Skip to content

Commit

Permalink
fix(reduce): reduce + taggable bug (#1091)
Browse files Browse the repository at this point in the history
Resolves #1089
Resolves #993
  • Loading branch information
sagalbot committed Mar 11, 2020
1 parent d71d592 commit 518e191
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 9 deletions.
32 changes: 23 additions & 9 deletions src/components/Select.vue
Expand Up @@ -629,7 +629,7 @@
this.setInternalValueFromOptions(this.value)
}
this.$on('option:created', this.maybePushTag)
this.$on('option:created', this.pushTag)
},
methods: {
Expand Down Expand Up @@ -662,7 +662,6 @@
}
this.updateValue(option);
}
this.onAfterSelect(option)
},
Expand Down Expand Up @@ -772,15 +771,32 @@
},
/**
* Finds an option from this.options
* Finds an option from the options
* where a reduced value matches
* the passed in value.
*
* @param value {Object}
* @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;
},
/**
Expand Down Expand Up @@ -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);
},
/**
Expand Down Expand Up @@ -986,7 +1000,7 @@
* @return {Array}
*/
optionList () {
return this.options.concat(this.pushedTags);
return this.options.concat(this.pushTags ? this.pushedTags : []);
},
/**
Expand Down
29 changes: 29 additions & 0 deletions tests/unit/Reduce.spec.js
Expand Up @@ -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);
});
});
});

0 comments on commit 518e191

Please sign in to comment.