mirror of
https://github.com/tenrok/vue-select.git
synced 2026-06-22 10:30:34 +03:00
tagging 90% complete
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
node_modules
|
node_modules
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
|
.idea
|
||||||
|
|||||||
+65
-37
@@ -153,7 +153,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul v-show="open" v-el:dropdown-menu :transition="transition" :style="{ 'max-height': maxHeight }" class="dropdown-menu animated">
|
<ul v-show="open" v-el:dropdown-menu :transition="transition" :style="{ 'max-height': maxHeight }" class="dropdown-menu animated">
|
||||||
<li v-for="option in filteredOptions" :class="{ active: isOptionSelected(option), highlight: $index === typeAheadPointer }" @mouseover="typeAheadPointer = $index">
|
<li v-for="option in filteredOptions" track-by="$index" :class="{ active: isOptionSelected(option), highlight: $index === typeAheadPointer }" @mouseover="typeAheadPointer = $index">
|
||||||
<a @mousedown.prevent="select(option)">
|
<a @mousedown.prevent="select(option)">
|
||||||
{{ getOptionLabel(option) }}
|
{{ getOptionLabel(option) }}
|
||||||
</a>
|
</a>
|
||||||
@@ -167,7 +167,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script type="text/babel">
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
/**
|
/**
|
||||||
@@ -278,6 +278,11 @@
|
|||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
pushTags: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User defined function for adding Options
|
* User defined function for adding Options
|
||||||
* @type {Function}
|
* @type {Function}
|
||||||
@@ -285,15 +290,10 @@
|
|||||||
createOption: {
|
createOption: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: function (newOption) {
|
default: function (newOption) {
|
||||||
let value = newOption
|
if (typeof this.options[0] === 'object') {
|
||||||
let firstOption = this.options ? this.options[0] : null
|
return {[this.label]: newOption}
|
||||||
if (firstOption && typeof firstOption === 'object' ) {
|
|
||||||
value = {
|
|
||||||
value
|
|
||||||
}
|
|
||||||
value[this.label] = newOption
|
|
||||||
}
|
}
|
||||||
return value
|
return newOption
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -331,25 +331,34 @@
|
|||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
select(option) {
|
select(option) {
|
||||||
if (! this.isOptionSelected(option) ) {
|
if (!this.isOptionSelected(option)) {
|
||||||
if (this.multiple) {
|
if (this.taggable && !this.optionExists(option)) {
|
||||||
|
newOption = this.createOption(option)
|
||||||
|
option = typeof newOption === 'undefined' ? option : newOption
|
||||||
|
|
||||||
if( ! this.value ) {
|
if( this.pushTags ) {
|
||||||
this.$set('value', [option])
|
this.options.push(option)
|
||||||
} else {
|
|
||||||
this.value.push(option)
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.value = option
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.multiple) {
|
|
||||||
this.value.$remove(option)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onAfterSelect(option)
|
if (this.multiple) {
|
||||||
|
|
||||||
|
if (!this.value) {
|
||||||
|
this.$set('value', [option])
|
||||||
|
} else {
|
||||||
|
this.value.push(option)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.value = option
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.multiple) {
|
||||||
|
this.value.$remove(option)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onAfterSelect(option)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -366,10 +375,6 @@
|
|||||||
if( this.clearSearchOnSelect ) {
|
if( this.clearSearchOnSelect ) {
|
||||||
this.search = ''
|
this.search = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// if( this.onChange ) {
|
|
||||||
// this.onChange(this.$get('value'))
|
|
||||||
// }
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -377,7 +382,7 @@
|
|||||||
* @param {Event} e
|
* @param {Event} e
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
toggleDropdown( e ) {
|
toggleDropdown(e) {
|
||||||
if( e.target === this.$els.openIndicator || e.target === this.$els.search || e.target === this.$els.toggle || e.target === this.$el ) {
|
if( e.target === this.$els.openIndicator || e.target === this.$els.search || e.target === this.$els.toggle || e.target === this.$el ) {
|
||||||
if( this.open ) {
|
if( this.open ) {
|
||||||
this.$els.search.blur() // dropdown will close on blur
|
this.$els.search.blur() // dropdown will close on blur
|
||||||
@@ -395,7 +400,15 @@
|
|||||||
*/
|
*/
|
||||||
isOptionSelected( option ) {
|
isOptionSelected( option ) {
|
||||||
if( this.multiple && this.value ) {
|
if( this.multiple && this.value ) {
|
||||||
return this.value.indexOf(option) !== -1
|
let selected = false
|
||||||
|
this.value.forEach(opt => {
|
||||||
|
if( typeof opt === 'object' && opt[this.label] === option ) {
|
||||||
|
selected = true
|
||||||
|
} else if( opt === option ) {
|
||||||
|
selected = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return selected
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.value === option
|
return this.value === option
|
||||||
@@ -460,11 +473,7 @@
|
|||||||
if( this.filteredOptions[ this.typeAheadPointer ] ) {
|
if( this.filteredOptions[ this.typeAheadPointer ] ) {
|
||||||
this.select( this.filteredOptions[ this.typeAheadPointer ] );
|
this.select( this.filteredOptions[ this.typeAheadPointer ] );
|
||||||
} else if (this.taggable && this.search.length){
|
} else if (this.taggable && this.search.length){
|
||||||
let option = this.createOption(this.search)
|
this.select(this.search)
|
||||||
this.$set('options', [option, ...this.options])
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.select(option)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( this.clearSearchOnSelect ) {
|
if( this.clearSearchOnSelect ) {
|
||||||
@@ -494,6 +503,21 @@
|
|||||||
if( ! this.$els.search.value.length && this.value ) {
|
if( ! this.$els.search.value.length && this.value ) {
|
||||||
return this.multiple ? this.value.pop() : this.$set('value', null)
|
return this.multiple ? this.value.pop() : this.$set('value', null)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
optionExists(option) {
|
||||||
|
let exists = false
|
||||||
|
|
||||||
|
this.options.forEach(opt => {
|
||||||
|
if( typeof opt === 'object' && opt[this.label] === option ) {
|
||||||
|
exists = true
|
||||||
|
} else if( opt === option ) {
|
||||||
|
exists = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return exists
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -527,7 +551,11 @@
|
|||||||
* @return {[type]} [description]
|
* @return {[type]} [description]
|
||||||
*/
|
*/
|
||||||
filteredOptions() {
|
filteredOptions() {
|
||||||
return this.$options.filters.filterBy(this.options, this.search)
|
let options = this.$options.filters.filterBy(this.options, this.search)
|
||||||
|
if (this.taggable && this.search.length && !this.optionExists(this.search)) {
|
||||||
|
options.unshift(this.search)
|
||||||
|
}
|
||||||
|
return options
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+330
-222
@@ -3,7 +3,7 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import vSelect from '../../src/components/Select.vue'
|
import vSelect from '../../src/components/Select.vue'
|
||||||
|
|
||||||
function trigger (target, event, process) {
|
function trigger(target, event, process) {
|
||||||
var e = document.createEvent('HTMLEvents')
|
var e = document.createEvent('HTMLEvents')
|
||||||
e.initEvent(event, true, true)
|
e.initEvent(event, true, true)
|
||||||
if (process) process(e)
|
if (process) process(e)
|
||||||
@@ -11,243 +11,351 @@ function trigger (target, event, process) {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function searchSubmit(vm) {
|
||||||
|
trigger(vm.$children[0].$els.search, 'keyup', function (e) {
|
||||||
|
e.keyCode = 13
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
describe('Select.vue', () => {
|
describe('Select.vue', () => {
|
||||||
|
|
||||||
it('can accept an array with pre-selected values', () => {
|
describe('Selecting values', () => {
|
||||||
const vm = new Vue({
|
it('can accept an array with pre-selected values', () => {
|
||||||
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
|
const vm = new Vue({
|
||||||
components: { vSelect },
|
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
|
||||||
data: {
|
components: {vSelect},
|
||||||
value: ['one'],
|
data: {
|
||||||
options: ['one','two','three']
|
value: ['one'],
|
||||||
}
|
options: ['one', 'two', 'three']
|
||||||
}).$mount()
|
|
||||||
expect(vm.$children[0].value).toEqual(['one'])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can accept an array of objects and pre-selected value (single)', () => {
|
|
||||||
const vm = new Vue({
|
|
||||||
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
|
|
||||||
components: { vSelect },
|
|
||||||
data: {
|
|
||||||
value: {label: 'This is Foo', value: 'foo'},
|
|
||||||
options: [{label: 'This is Foo', value: 'foo'}, {label: 'This is Bar', value: 'bar'}]
|
|
||||||
}
|
|
||||||
}).$mount()
|
|
||||||
expect( vm.$children[0].$get('value').value ).toEqual( 'foo' )
|
|
||||||
expect( vm.$children[0].$get('value').label ).toEqual( 'This is Foo' )
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can accept an array of objects and pre-selected values (multiple)', () => {
|
|
||||||
const vm = new Vue({
|
|
||||||
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
|
|
||||||
components: { vSelect },
|
|
||||||
data: {
|
|
||||||
value: [{label: 'This is Foo', value: 'foo'}, {label: 'This is Bar', value: 'bar'}],
|
|
||||||
options: [{label: 'This is Foo', value: 'foo'}, {label: 'This is Bar', value: 'bar'}]
|
|
||||||
}
|
|
||||||
}).$mount()
|
|
||||||
var values = vm.$children[0].$get('value')
|
|
||||||
var labels = []
|
|
||||||
labels = values.map( value => value.label )
|
|
||||||
values = values.map( value => value.value )
|
|
||||||
expect( values ).toEqual( ['foo', 'bar'] )
|
|
||||||
expect( labels ).toEqual( ['This is Foo', 'This is Bar'] )
|
|
||||||
})
|
|
||||||
|
|
||||||
it('removes the given tag when its close icon is clicked', (done) => {
|
|
||||||
const vm = new Vue({
|
|
||||||
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
|
|
||||||
components: { vSelect },
|
|
||||||
data: {
|
|
||||||
value: ['one'],
|
|
||||||
options: ['one','two','three']
|
|
||||||
}
|
|
||||||
}).$mount()
|
|
||||||
vm.$children[0].$els.toggle.querySelector('.close').click()
|
|
||||||
Vue.nextTick(() => {
|
|
||||||
expect(vm.$children[0].$get('value')).toEqual([])
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('removes the last item in the value array on delete keypress when multiple is true', () => {
|
|
||||||
|
|
||||||
const vm = new Vue({
|
|
||||||
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
|
|
||||||
components: { vSelect },
|
|
||||||
data: {
|
|
||||||
value: ['one','two'],
|
|
||||||
options: ['one','two','three']
|
|
||||||
}
|
|
||||||
}).$mount()
|
|
||||||
vm.$children[0].maybeDeleteValue()
|
|
||||||
Vue.nextTick(() => {
|
|
||||||
expect(vm.$children[0].$get('value')).toEqual(['one'])
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('sets the value to null on delete keypress when multiple is false', () => {
|
|
||||||
const vm = new Vue({
|
|
||||||
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
|
|
||||||
components: { vSelect },
|
|
||||||
data: {
|
|
||||||
value: 'one',
|
|
||||||
options: ['one','two','three']
|
|
||||||
}
|
|
||||||
}).$mount()
|
|
||||||
vm.$children[0].maybeDeleteValue()
|
|
||||||
Vue.nextTick(() => {
|
|
||||||
expect(vm.$children[0].$get('value')).toEqual(null)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can determine if the value prop is empty', () => {
|
|
||||||
const vm = new Vue({
|
|
||||||
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
|
|
||||||
components: { vSelect },
|
|
||||||
data: {
|
|
||||||
value: [],
|
|
||||||
options: ['one','two','three']
|
|
||||||
}
|
|
||||||
}).$mount()
|
|
||||||
var select = vm.$children[0]
|
|
||||||
expect(select.isValueEmpty).toEqual(true)
|
|
||||||
|
|
||||||
select.$set('value', ['one'])
|
|
||||||
expect(select.isValueEmpty).toEqual(false)
|
|
||||||
|
|
||||||
select.$set('value', [{l:'f'}])
|
|
||||||
expect(select.isValueEmpty).toEqual(false)
|
|
||||||
|
|
||||||
select.$set('value', 'one')
|
|
||||||
expect(select.isValueEmpty).toEqual(false)
|
|
||||||
|
|
||||||
select.$set('value', {label: 'foo', value: 'foo'})
|
|
||||||
expect(select.isValueEmpty).toEqual(false)
|
|
||||||
|
|
||||||
select.$set('value', '')
|
|
||||||
expect(select.isValueEmpty).toEqual(true)
|
|
||||||
|
|
||||||
select.$set('value', null)
|
|
||||||
expect(select.isValueEmpty).toEqual(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('resets the selected values when the options property changes', (done) => {
|
|
||||||
const vm = new Vue({
|
|
||||||
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
|
|
||||||
components: { vSelect },
|
|
||||||
data: {
|
|
||||||
value: ['one'],
|
|
||||||
options: ['one','two','three']
|
|
||||||
}
|
|
||||||
}).$mount()
|
|
||||||
vm.$children[0].options = ['four','five','six']
|
|
||||||
Vue.nextTick(() => {
|
|
||||||
expect(vm.$children[0].$get('value')).toEqual([])
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can retain values present in a new array of options', () => {
|
|
||||||
const vm = new Vue({
|
|
||||||
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
|
|
||||||
components: { vSelect },
|
|
||||||
data: {
|
|
||||||
value: ['one'],
|
|
||||||
options: ['one','two','three']
|
|
||||||
}
|
|
||||||
}).$mount()
|
|
||||||
vm.$children[0].$set('options', ['one','five','six'])
|
|
||||||
expect(vm.$children[0].value).toEqual(['one'])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can generate labels using the default label key', () => {
|
|
||||||
const vm = new Vue({
|
|
||||||
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
|
|
||||||
components: { vSelect },
|
|
||||||
data: {
|
|
||||||
value: [{label: 'Baz'}],
|
|
||||||
options: [{label: 'Foo'}, {label: 'Baz'}]
|
|
||||||
}
|
|
||||||
}).$mount()
|
|
||||||
expect(vm.$children[0].$els.toggle.querySelector('.selected-tag').textContent).toContain('Baz')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can generate labels using a custom label key', () => {
|
|
||||||
const vm = new Vue({
|
|
||||||
template: '<div><v-select label="name" :options="options" :value.sync="value" :multiple="true"></v-select></div>',
|
|
||||||
components: { vSelect },
|
|
||||||
data: {
|
|
||||||
value: [{name: 'Baz'}],
|
|
||||||
options: [{name: 'Foo'}, {name: 'Baz'}]
|
|
||||||
}
|
|
||||||
}).$mount()
|
|
||||||
expect(vm.$children[0].$els.toggle.querySelector('.selected-tag').textContent).toContain('Baz')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can run a callback when the selection changes', (done) => {
|
|
||||||
const vm = new Vue({
|
|
||||||
template: '<div><v-select :on-change="foo" value="bar" :options="options"></v-select></div>',
|
|
||||||
components: { vSelect },
|
|
||||||
data: {
|
|
||||||
val: null,
|
|
||||||
options: ['foo','bar','baz']
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
foo(value) {
|
|
||||||
this.val = value
|
|
||||||
}
|
}
|
||||||
}
|
}).$mount()
|
||||||
}).$mount()
|
expect(vm.$children[0].value).toEqual(['one'])
|
||||||
|
})
|
||||||
|
|
||||||
vm.$children[0].select('foo')
|
it('can accept an array of objects and pre-selected value (single)', () => {
|
||||||
Vue.nextTick(function() {
|
const vm = new Vue({
|
||||||
expect(vm.$get('val')).toEqual('foo')
|
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: {label: 'This is Foo', value: 'foo'},
|
||||||
|
options: [{label: 'This is Foo', value: 'foo'}, {label: 'This is Bar', value: 'bar'}]
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
expect(vm.$children[0].$get('value').value).toEqual('foo')
|
||||||
|
expect(vm.$children[0].$get('value').label).toEqual('This is Foo')
|
||||||
|
})
|
||||||
|
|
||||||
vm.$children[0].$set('value', 'baz')
|
it('can accept an array of objects and pre-selected values (multiple)', () => {
|
||||||
Vue.nextTick(function() {
|
const vm = new Vue({
|
||||||
expect(vm.$get('val')).toEqual('baz')
|
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: [{label: 'This is Foo', value: 'foo'}, {label: 'This is Bar', value: 'bar'}],
|
||||||
|
options: [{label: 'This is Foo', value: 'foo'}, {label: 'This is Bar', value: 'bar'}]
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
var values = vm.$children[0].$get('value')
|
||||||
|
var labels = []
|
||||||
|
labels = values.map(value => value.label)
|
||||||
|
values = values.map(value => value.value)
|
||||||
|
expect(values).toEqual(['foo', 'bar'])
|
||||||
|
expect(labels).toEqual(['This is Foo', 'This is Bar'])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can determine if the value prop is empty', () => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: [],
|
||||||
|
options: ['one', 'two', 'three']
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
var select = vm.$children[0]
|
||||||
|
expect(select.isValueEmpty).toEqual(true)
|
||||||
|
|
||||||
|
select.$set('value', ['one'])
|
||||||
|
expect(select.isValueEmpty).toEqual(false)
|
||||||
|
|
||||||
|
select.$set('value', [{l: 'f'}])
|
||||||
|
expect(select.isValueEmpty).toEqual(false)
|
||||||
|
|
||||||
|
select.$set('value', 'one')
|
||||||
|
expect(select.isValueEmpty).toEqual(false)
|
||||||
|
|
||||||
|
select.$set('value', {label: 'foo', value: 'foo'})
|
||||||
|
expect(select.isValueEmpty).toEqual(false)
|
||||||
|
|
||||||
|
select.$set('value', '')
|
||||||
|
expect(select.isValueEmpty).toEqual(true)
|
||||||
|
|
||||||
|
select.$set('value', null)
|
||||||
|
expect(select.isValueEmpty).toEqual(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('resets the selected values when the options property changes', (done) => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: ['one'],
|
||||||
|
options: ['one', 'two', 'three']
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
vm.$children[0].options = ['four', 'five', 'six']
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
expect(vm.$children[0].$get('value')).toEqual([])
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('can retain values present in a new array of options', () => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: ['one'],
|
||||||
|
options: ['one', 'two', 'three']
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
vm.$children[0].$set('options', ['one', 'five', 'six'])
|
||||||
|
expect(vm.$children[0].value).toEqual(['one'])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Removing values', () => {
|
||||||
|
it('removes the given tag when its close icon is clicked', (done) => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: ['one'],
|
||||||
|
options: ['one', 'two', 'three']
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
vm.$children[0].$els.toggle.querySelector('.close').click()
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
expect(vm.$children[0].$get('value')).toEqual([])
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('removes the last item in the value array on delete keypress when multiple is true', () => {
|
||||||
|
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: ['one', 'two'],
|
||||||
|
options: ['one', 'two', 'three']
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
vm.$children[0].maybeDeleteValue()
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
expect(vm.$children[0].$get('value')).toEqual(['one'])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sets the value to null on delete keypress when multiple is false', () => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: 'one',
|
||||||
|
options: ['one', 'two', 'three']
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
vm.$children[0].maybeDeleteValue()
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
expect(vm.$children[0].$get('value')).toEqual(null)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('can adding option if taggable enabled and search is not empty', () => {
|
describe('Labels', () => {
|
||||||
const vm = new Vue({
|
it('can generate labels using the default label key', () => {
|
||||||
template: '<div><v-select :options="options" :value.sync="value" :multiple="true" :taggable="true"></v-select></div>',
|
const vm = new Vue({
|
||||||
components: { vSelect },
|
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
|
||||||
data: {
|
components: {vSelect},
|
||||||
value: ['one'],
|
data: {
|
||||||
options: ['one','two','three']
|
value: [{label: 'Baz'}],
|
||||||
}
|
options: [{label: 'Foo'}, {label: 'Baz'}]
|
||||||
}).$mount()
|
}
|
||||||
vm.$children[0].search = 'four'
|
}).$mount()
|
||||||
|
expect(vm.$children[0].$els.toggle.querySelector('.selected-tag').textContent).toContain('Baz')
|
||||||
trigger(vm.$children[0].$els.search, 'keyup', function (e) {
|
|
||||||
e.keyCode = 13
|
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(vm.$children[0].options[0]).toEqual('four')
|
it('can generate labels using a custom label key', () => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select label="name" :options="options" :value.sync="value" :multiple="true"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: [{name: 'Baz'}],
|
||||||
|
options: [{name: 'Foo'}, {name: 'Baz'}]
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
expect(vm.$children[0].$els.toggle.querySelector('.selected-tag').textContent).toContain('Baz')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can run a callback when the selection changes', (done) => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select :on-change="foo" value="bar" :options="options"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
val: null,
|
||||||
|
options: ['foo', 'bar', 'baz']
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
foo(value) {
|
||||||
|
this.val = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
|
||||||
|
vm.$children[0].select('foo')
|
||||||
|
Vue.nextTick(function () {
|
||||||
|
expect(vm.$get('val')).toEqual('foo')
|
||||||
|
|
||||||
|
vm.$children[0].$set('value', 'baz')
|
||||||
|
Vue.nextTick(function () {
|
||||||
|
expect(vm.$get('val')).toEqual('baz')
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should select added option if taggable enabled and search is not empty', (done) => {
|
describe('When Tagging Is Enabled', () => {
|
||||||
const vm = new Vue({
|
it('can determine if a given option string already exists', () => {
|
||||||
template: '<div><v-select :options="options" :value.sync="value" :multiple="true" :taggable="true"></v-select></div>',
|
const vm = new Vue({
|
||||||
components: { vSelect },
|
template: '<div><v-select v-ref:select :options="options" :taggable="true"></v-select></div>',
|
||||||
data: {
|
components: {vSelect},
|
||||||
value: ['one'],
|
data: {
|
||||||
options: ['one','two','three']
|
options: ['one', 'two']
|
||||||
}
|
}
|
||||||
}).$mount()
|
}).$mount()
|
||||||
vm.$children[0].search = 'four'
|
|
||||||
|
|
||||||
trigger(vm.$children[0].$els.search, 'keyup', function (e) {
|
expect(vm.$refs.select.optionExists('one')).toEqual(true)
|
||||||
e.keyCode = 13
|
expect(vm.$refs.select.optionExists('three')).toEqual(false)
|
||||||
})
|
})
|
||||||
Vue.nextTick(() => {
|
|
||||||
expect(vm.$children[0].$get('value')).toEqual(['one', 'four'])
|
it('can determine if a given option object already exists', () => {
|
||||||
done()
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select v-ref:select :options="options" :taggable="true"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
options: [{label: 'one'}, {label: 'two'}]
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
|
||||||
|
expect(vm.$refs.select.optionExists('one')).toEqual(true)
|
||||||
|
expect(vm.$refs.select.optionExists('three')).toEqual(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can determine if a given option object already exists when using custom labels', () => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select v-ref:select :options="options" label="foo" :taggable="true"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
options: [{foo: 'one'}, {foo: 'two'}]
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
|
||||||
|
expect(vm.$refs.select.optionExists('one')).toEqual(true)
|
||||||
|
expect(vm.$refs.select.optionExists('three')).toEqual(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can add the current search text as the first item in the options list', () => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select :options="options" :value.sync="value" :multiple="true" :taggable="true"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: ['one'],
|
||||||
|
options: ['one', 'two']
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
|
||||||
|
vm.$children[0].search = 'three'
|
||||||
|
expect(vm.$children[0].filteredOptions).toEqual(['three'])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can select the current search text', (done) => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select :options="options" :value.sync="value" :multiple="true" :taggable="true"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: ['one'],
|
||||||
|
options: ['one', 'two']
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
|
||||||
|
vm.$children[0].search = 'three'
|
||||||
|
|
||||||
|
searchSubmit(vm)
|
||||||
|
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
expect(vm.$children[0].$get('value')).toEqual(['one', 'three'])
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('will add a freshly created option/tag to the options list when pushTags is true', () => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select :options="options" pushTags :value.sync="value" :multiple="true" :taggable="true"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: ['one'],
|
||||||
|
options: ['one', 'two']
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
|
||||||
|
vm.$children[0].search = 'three'
|
||||||
|
|
||||||
|
searchSubmit(vm)
|
||||||
|
|
||||||
|
expect(vm.$children[0].options).toEqual(['one', 'two', 'three'])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('will select an existing option if the search string matches a string from options', (done) => {
|
||||||
|
let two = 'two'
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select :options="options" :value.sync="value" :multiple="true" :taggable="true"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: null,
|
||||||
|
options: ['one', two]
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
vm.$children[0].search = 'two'
|
||||||
|
|
||||||
|
searchSubmit(vm)
|
||||||
|
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
expect(vm.$children[0].$get('value')[0]).toBe(two)
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('will select an existing option if the search string matches an objects label from options', (done) => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select :options="options" :value.sync="value" multiple :taggable="true"></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: null,
|
||||||
|
options: [{label: 'one'}, {label: 'two'}]
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
|
||||||
|
vm.$children[0].search = 'two'
|
||||||
|
|
||||||
|
searchSubmit(vm)
|
||||||
|
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
console.dir(JSON.stringify(vm.$children[0].options))
|
||||||
|
console.dir(JSON.stringify(vm.$children[0].value))
|
||||||
|
expect(vm.$children[0].value).toEqual({label: 'two'})
|
||||||
|
done()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user