vue-multiselect
Advanced tools
Comparing version 1.0.1 to 1.1.0
@@ -32,6 +32,3 @@ import deepClone from './utils' | ||
/** | ||
* Presets the selected options. Add `.sync` to | ||
* update parent value. If this.onChange callback is present, | ||
* this will not update. In that case, the parent is responsible | ||
* for updating this value. | ||
* Presets the selected options value. | ||
* @type {Object||Array||String||Integer} | ||
@@ -38,0 +35,0 @@ */ |
@@ -5,3 +5,3 @@ module.exports = { | ||
pointer: 0, | ||
visibleElements: this.maxHeight / 40 | ||
visibleElements: this.maxHeight / this.optionHeight | ||
} | ||
@@ -18,2 +18,11 @@ }, | ||
default: true | ||
}, | ||
/** | ||
* Sets the height of the option. Used for scroll calculations | ||
* @type {Number} | ||
* @default 40 | ||
*/ | ||
optionHeight: { | ||
type: Number, | ||
default: 40 | ||
} | ||
@@ -23,3 +32,3 @@ }, | ||
pointerPosition () { | ||
return this.pointer * 40 | ||
return this.pointer * this.optionHeight | ||
} | ||
@@ -42,4 +51,4 @@ }, | ||
this.pointer++ | ||
if (this.$els.list.scrollTop <= this.pointerPosition - this.visibleElements * 40) { | ||
this.$els.list.scrollTop = this.pointerPosition - (this.visibleElements - 1) * 40 | ||
if (this.$els.list.scrollTop <= this.pointerPosition - this.visibleElements * this.optionHeight) { | ||
this.$els.list.scrollTop = this.pointerPosition - (this.visibleElements - 1) * this.optionHeight | ||
} | ||
@@ -46,0 +55,0 @@ } |
{ | ||
"name": "vue-multiselect", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "Multiselect component for vue.js", | ||
@@ -5,0 +5,0 @@ "author": "Damian Dulisz <damian.dulisz@monterail.com>", |
204
README.md
# vue-multiselect ![Build Status](https://circleci.com/gh/monterail/vue-multiselect/tree/master.svg?style=shield&circle-token=5c931ff28fd12587610f835472becdd514d09cef) | ||
Probably the most complete *selecting* solution for Vue.js, without jQuery. | ||
#### Current version: v1.1.0 | ||
### Features & characteristics: | ||
@@ -9,2 +11,3 @@ * NO dependencies | ||
* Tagging | ||
* Custom option templates (1.1.0+) | ||
* Dropdowns | ||
@@ -17,3 +20,3 @@ * Filtering | ||
* Async options support | ||
* \> 95% test coverage | ||
* \> 99% test coverage | ||
* Fully configurable (see props list below) | ||
@@ -34,3 +37,7 @@ | ||
<div> | ||
<multiselect :selected.sync="selected" :options="options"></multiselect> | ||
<multiselect | ||
:selected="selected" | ||
:options="options" | ||
@update="updateSelected"> | ||
</multiselect> | ||
</div> | ||
@@ -40,4 +47,2 @@ </template> | ||
> **It is very important not to mix `.sync` with `:on-change` prop. You have to either choose two-way binding or one way binding with `:on-change` callback as a way to update the `:selected` value** | ||
``` javascript | ||
@@ -52,2 +57,7 @@ import Multiselect from 'vue-multiselect' | ||
} | ||
}, | ||
methods: { | ||
updateSelected (newSelected) { | ||
this.selected = newSelected | ||
} | ||
} | ||
@@ -74,5 +84,4 @@ } | ||
* 1.0 Release – Event based, deprecate two-way binding, make it easy to migrate to Vue 2.0 | ||
* Grouping | ||
* Examples of custom components / templates ready to use in project | ||
* Better documentation | ||
@@ -86,9 +95,9 @@ ## Examples | ||
:options="source", | ||
:selected.sync="value", | ||
:multiple="false", | ||
:selected="value", | ||
:searchable="false", | ||
placeholder="Select one", | ||
label="name", | ||
:close-on-select="false", | ||
:allow-empty="false", | ||
@update="updateSelected", | ||
label="name", | ||
placeholder="Select one", | ||
key="name" | ||
@@ -102,9 +111,8 @@ ) | ||
:options="source", | ||
:selected.sync="value", | ||
:multiple="false", | ||
:searchable="true", | ||
:selected="value", | ||
:close-on-select="true", | ||
:clear-on-select="false", | ||
@update="updateValue", | ||
placeholder="Select one", | ||
label="name", | ||
:close-on-select="true", | ||
:clear-on-select="false" | ||
key="name" | ||
@@ -115,11 +123,11 @@ ) | ||
### Multiple select with search | ||
``` jade | ||
```jade | ||
multiselect( | ||
:options="source", | ||
:selected.sync="multiValue", | ||
:selected="multiValue", | ||
:multiple="true", | ||
:searchable="true", | ||
:close-on-select="true", | ||
@update="updateMultiValue", | ||
placeholder="Pick some", | ||
label="name", | ||
:close-on-select="true" | ||
key="name" | ||
@@ -130,15 +138,14 @@ ) | ||
### Tagging | ||
with `:on-tag` and `:on-change` callback functions | ||
``` jade | ||
with `@tag` event | ||
```jade | ||
multiselect( | ||
:options="taggingOptions", | ||
:selected="taggingSelected", | ||
:multiple="multiple", | ||
:searchable="searchable", | ||
:on-tag="addTag", | ||
:on-change="updateSelectedTagging", | ||
:multiple="true", | ||
:taggable="true", | ||
tag-placeholder="Add this as new tag" | ||
placeholder="Type to search or add tag" | ||
label="name" | ||
@tag="addTag", | ||
@update="updateSelectedTagging", | ||
tag-placeholder="Add this as new tag", | ||
placeholder="Type to search or add tag", | ||
label="name", | ||
key="code" | ||
@@ -148,4 +155,3 @@ ) | ||
``` javascript | ||
```javascript | ||
addTag (newTag) { | ||
@@ -161,13 +167,15 @@ const tag = { | ||
### Vuex supporting example | ||
with `:on-change` callback function | ||
``` jade | ||
### Custom option template | ||
Using partial API | ||
```jade | ||
multiselect( | ||
:options="source", | ||
:selected="value", | ||
:multiple="false", | ||
:searchable="false", | ||
placeholder="Select one", | ||
:on-change="onChangeAction" | ||
:options="styleList", | ||
:selected="selectedStyle", | ||
:option-height="130", | ||
:custom-label="styleLabel", | ||
@update="updateSelectedStyle", | ||
option-partial="customOptionPartial" | ||
placeholder="Fav No Man’s Sky path" | ||
label="title" | ||
key="title" | ||
) | ||
@@ -177,5 +185,12 @@ ``` | ||
``` javascript | ||
import customOptionPartial from './partials/customOptionPartial.html' | ||
Vue.partial('customOptionPartial', customOptionPartial) | ||
// ...Inside Vue component | ||
methods: { | ||
onChangeAction (newValue) { | ||
dispatch('SET_SELECT_VALUE', newValue) | ||
styleLabel ({ title, desc }) { | ||
return `${title} – ${desc}` | ||
}, | ||
updateSelectedStyle (style) { | ||
this.selectedStyle = style | ||
} | ||
@@ -185,2 +200,15 @@ } | ||
``` html | ||
<div> | ||
<img class="option__image" :src="option.img" alt="No Man’s Sky" /> | ||
<div class="option__desc"> | ||
<span class="option__title">{{ option.title }}</span> | ||
<span class="option__small"> | ||
{{ option.desc }} | ||
</span> | ||
</div> | ||
</div> | ||
``` | ||
### Asynchronous dropdown | ||
@@ -190,7 +218,7 @@ ``` jade | ||
:options="countries", | ||
:selected.sync="selectedCountries", | ||
:selected="selectedCountries", | ||
:multiple="multiple", | ||
:searchable="searchable", | ||
@search-change="asyncFind", | ||
placeholder="Type to search", | ||
:on-search-change="asyncFind", | ||
label="name" | ||
@@ -203,3 +231,3 @@ key="code" | ||
``` javascript | ||
```javascript | ||
methods: { | ||
@@ -238,11 +266,6 @@ asyncFind (query) { | ||
/** | ||
* Required. Presets the selected options. Add `.sync` to | ||
* update parent value. If this.onChange callback is present, | ||
* this will not update. In that case, the parent is responsible | ||
* for updating this value. | ||
* Presets the selected options value. | ||
* @type {Object||Array||String||Integer} | ||
*/ | ||
selected: { | ||
required: true | ||
}, | ||
selected: {}, | ||
/** | ||
@@ -321,35 +344,2 @@ * Key to compare objects | ||
/** | ||
* Callback function to call after this.value changes | ||
* @callback onChange | ||
* @default false | ||
* @param {Array||Object||String||Integer} Current this.value | ||
* @param {Integer} $index of current selection | ||
* @type {Function} | ||
*/ | ||
onChange: { | ||
type: Function, | ||
default: false | ||
}, | ||
/** | ||
* Callback function to call after this.search changes | ||
* @callback onSearchChange | ||
* @default false | ||
* @param {String} Pass current search String | ||
* @type {Function} | ||
*/ | ||
onSearchChange: { | ||
type: Function, | ||
default: false | ||
}, | ||
/** | ||
* Value that indicates if the dropdown has been used. | ||
* Useful for validation. | ||
* @default false | ||
* @type {Boolean} | ||
*/ | ||
touched: { | ||
type: Boolean, | ||
default: false | ||
}, | ||
/** | ||
* Reset this.value, this.search, this.selected after this.value changes. | ||
@@ -393,15 +383,2 @@ * Useful if want to create a stateless dropdown, that fires the this.onChange | ||
/** | ||
* Callback function to run when attemting to add a tag | ||
* @default suitable for primitive values | ||
* @param {String} Tag string to build a tag | ||
* @type {Function} | ||
*/ | ||
onTag: { | ||
type: Function, | ||
default: function (tag) { | ||
this.options.push(tag) | ||
this.value.push(tag) | ||
} | ||
}, | ||
/** | ||
* String to show when highlighting a potential tag | ||
@@ -423,2 +400,11 @@ * @default 'Press enter to create a tag' | ||
default: false | ||
}, | ||
/** | ||
* Will be passed with all events as second param. | ||
* Useful for identifying events origin. | ||
* @default null | ||
* @type {String|Integer} | ||
*/ | ||
id: { | ||
default: null | ||
} | ||
@@ -439,3 +425,3 @@ } | ||
} | ||
} | ||
}, | ||
@@ -482,3 +468,3 @@ // Multiselect.vue | ||
/** | ||
* Label to look for in option Object | ||
* Limit the display of selected options. The rest will be hidden within the limitText string. | ||
* @default 'label' | ||
@@ -501,2 +487,20 @@ * @type {String} | ||
default: count => `and ${count} more` | ||
}, | ||
/** | ||
* Set true to trigger the loading spinner. | ||
* @default False | ||
* @type {Boolean} | ||
*/ | ||
loading: { | ||
type: Boolean, | ||
default: false | ||
}, | ||
/** | ||
* Disables the multiselect if true. | ||
* @default false | ||
* @type {Boolean} | ||
*/ | ||
disabled: { | ||
type: Boolean, | ||
default: false | ||
} | ||
@@ -503,0 +507,0 @@ } |
@@ -32,6 +32,3 @@ import deepClone from './utils' | ||
/** | ||
* Presets the selected options. Add `.sync` to | ||
* update parent value. If this.onChange callback is present, | ||
* this will not update. In that case, the parent is responsible | ||
* for updating this value. | ||
* Presets the selected options value. | ||
* @type {Object||Array||String||Integer} | ||
@@ -38,0 +35,0 @@ */ |
@@ -5,3 +5,3 @@ module.exports = { | ||
pointer: 0, | ||
visibleElements: this.maxHeight / 40 | ||
visibleElements: this.maxHeight / this.optionHeight | ||
} | ||
@@ -18,2 +18,11 @@ }, | ||
default: true | ||
}, | ||
/** | ||
* Sets the height of the option. Used for scroll calculations | ||
* @type {Number} | ||
* @default 40 | ||
*/ | ||
optionHeight: { | ||
type: Number, | ||
default: 40 | ||
} | ||
@@ -23,3 +32,3 @@ }, | ||
pointerPosition () { | ||
return this.pointer * 40 | ||
return this.pointer * this.optionHeight | ||
} | ||
@@ -42,4 +51,4 @@ }, | ||
this.pointer++ | ||
if (this.$els.list.scrollTop <= this.pointerPosition - this.visibleElements * 40) { | ||
this.$els.list.scrollTop = this.pointerPosition - (this.visibleElements - 1) * 40 | ||
if (this.$els.list.scrollTop <= this.pointerPosition - this.visibleElements * this.optionHeight) { | ||
this.$els.list.scrollTop = this.pointerPosition - (this.visibleElements - 1) * this.optionHeight | ||
} | ||
@@ -46,0 +55,0 @@ } |
@@ -1293,2 +1293,18 @@ import Vue from 'vue' | ||
}) | ||
describe(':option-partial', () => { | ||
it('should switch the option template to the one provided in the partial', () => { | ||
Vue.partial('customPartial', '<span>test_test</span>') | ||
const vm = new Vue({ | ||
template: '<multiselect :selected="value" :searchable="true" :options="source" :multiple="true" :limit="1" option-partial="customPartial"></multiselect>', | ||
components: { Multiselect }, | ||
data: { | ||
value: ['1', '2', '3'], | ||
source: ['1', '2', '3', '4', '5'] | ||
} | ||
}).$mount() | ||
vm.$children[0].activate() | ||
expect(vm.$children[0].$els.list.children[0].children[0].textContent).to.equal('test_test') | ||
}) | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2016086
43
3327
508