2
0
mirror of https://github.com/tenrok/vue-select.git synced 2026-05-17 02:29:37 +03:00

fix(reduce): reduce + taggable bug (#1091)

Resolves #1089
Resolves #993
This commit is contained in:
Jeff Sagal
2020-03-10 21:10:58 -07:00
committed by GitHub
parent d71d592bb3
commit 518e1919f8
2 changed files with 52 additions and 9 deletions
+23 -9
View File
@@ -629,7 +629,7 @@
this.setInternalValueFromOptions(this.value)
}
this.$on('option:created', this.maybePushTag)
this.$on('option:created', this.pushTag)
},
methods: {
@@ -662,7 +662,6 @@
}
this.updateValue(option);
}
this.onAfterSelect(option)
},
@@ -772,7 +771,7 @@
},
/**
* Finds an option from this.options
* Finds an option from the options
* where a reduced value matches
* the passed in value.
*
@@ -780,7 +779,24 @@
* @returns {*}
*/
findOptionFromReducedValue (value) {
return this.options.find(option => JSON.stringify(this.reduce(option)) === JSON.stringify(value)) || value;
const predicate = option => JSON.stringify(this.reduce(option)) === JSON.stringify(value);
const matches = [
...this.options,
...this.pushedTags,
].filter(predicate);
if (matches.length === 1) {
return matches[0];
}
/**
* This second loop is needed to cover an edge case where `taggable` + `reduce`
* were used in conjunction with a `create-option` that doesn't create a
* unique reduced value.
* @see https://github.com/sagalbot/vue-select/issues/1089#issuecomment-597238735
*/
return matches.find(match => this.optionComparator(match, this.$data._value)) || value;
},
/**
@@ -836,10 +852,8 @@
* @param {Object || String} option
* @return {void}
*/
maybePushTag(option) {
if (this.pushTags) {
this.pushedTags.push(option)
}
pushTag (option) {
this.pushedTags.push(option);
},
/**
@@ -986,7 +1000,7 @@
* @return {Array}
*/
optionList () {
return this.options.concat(this.pushedTags);
return this.options.concat(this.pushTags ? this.pushedTags : []);
},
/**
+29
View File
@@ -226,4 +226,33 @@ describe("When reduce prop is defined", () => {
expect(Select.vm.selectedValue).toEqual([optionToChangeTo]);
});
describe('Reducing Tags', () => {
it('tracks values that have been created by the user', async () => {
const Parent = mount({
data: () => ({selected: null, options: []}),
template: `
<v-select
v-model="selected"
:options="options"
taggable
:reduce="name => name.value"
:create-option="label => ({ label, value: -1 })"
/>
`,
components: {'v-select': VueSelect},
});
const Select = Parent.vm.$children[0];
// When
Select.search = 'hello';
Select.typeAheadSelect();
await Select.$nextTick();
// Then
expect(Select.selectedValue).toEqual([{label: 'hello', value: -1}]);
expect(Select.$refs.selectedOptions.textContent.trim()).toEqual('hello');
expect(Parent.vm.selected).toEqual(-1);
});
});
});