diff --git a/docs/api/events.md b/docs/api/events.md index 7a9c7fb..4866fef 100644 --- a/docs/api/events.md +++ b/docs/api/events.md @@ -9,13 +9,45 @@ Triggered when the selected value changes. Used internally for `v-model`. this.$emit("input", val); ``` +## `option:selecting` + +Triggered after an option has been selected, before updating internal state. + +```js +this.$emit("option:selecting", selectedOption); +``` + +## `option:selected` + +Triggered when an option has been selected, after updating internal state. + +```js +this.$emit("option:selected", selectedOption); +``` + +## `option:deselecting` + +Triggered when an option has been deselected, before updating internal state. + +```js +this.$emit("option:deselecting", selectedOption); +``` + +## `option:deselected` + +Triggered when an option has been deselected, after updating internal state. + +```js +this.$emit("option:deselected", deselectedOption); +``` + ## `option:created` Triggered when `taggable` is `true` and a new option has been created. ```js /** - * @param newOption {Object} - created option + * @param newOption {Object} - created option */ this.$emit("option:created", newOption); ``` diff --git a/src/components/Select.vue b/src/components/Select.vue index a651070..6a21766 100644 --- a/src/components/Select.vue +++ b/src/components/Select.vue @@ -657,6 +657,7 @@ * @return {void} */ select(option) { + this.$emit('option:selecting', option); if (!this.isOptionSelected(option)) { if (this.taggable && !this.optionExists(option)) { this.$emit('option:created', option); @@ -665,6 +666,7 @@ option = this.selectedValue.concat(option) } this.updateValue(option); + this.$emit('option:selected', option); } this.onAfterSelect(option) }, @@ -675,9 +677,11 @@ * @return {void} */ deselect (option) { + this.$emit('option:deselecting', option); this.updateValue(this.selectedValue.filter(val => { return !this.optionComparator(val, option); })); + this.$emit('option:deselected', option); }, /** diff --git a/tests/unit/Selecting.spec.js b/tests/unit/Selecting.spec.js index b7a7290..a9eb33c 100755 --- a/tests/unit/Selecting.spec.js +++ b/tests/unit/Selecting.spec.js @@ -220,5 +220,84 @@ describe("VS - Selecting Values", () => { Select.vm.select("bar"); expect(Select.emitted("input")[0]).toEqual([["foo", "bar"]]); }); + + it("will not trigger the input event when multiple is true and selection is repeated", () => { + const Select = shallowMount(VueSelect, { + propsData: { multiple: true, value: ["foo ", "bar"], options: ["foo", "bar", "baz"] } + }); + + Select.vm.select("bar"); + expect(Select.emitted("input")).toBeFalsy(); + }); + }); + + describe("option:selecting Event", () => { + it("will trigger the option:selecting event when an option is selected", () => { + const Select = shallowMount(VueSelect); + Select.vm.select("bar"); + expect(Select.emitted("option:selecting")[0]).toEqual(["bar"]); + }); + + it("will trigger the option:selecting event regardless of current value", () => { + const Select = shallowMount(VueSelect, { + propsData: { value: ["foo"], options: ["foo", "bar"] } + }); + Select.vm.select("foo"); + Select.vm.select("bar"); + expect(Select.emitted("option:selecting")).toEqual([["foo"], ["bar"]]); + }); + + it("will trigger the option:selecting event with current selected item when multiple is true", () => { + const Select = shallowMount(VueSelect, { + propsData: { multiple: true, value: ["foo"], options: ["foo", "bar"] } + }); + Select.vm.select("bar"); + expect(Select.emitted("option:selecting")[0]).toEqual(["bar"]); + }); + + it("will trigger the option:selecting event regardless of current value when multiple is true", () => { + const Select = shallowMount(VueSelect, { + propsData: { multiple: true, value: ["foo", "bar"], options: ["foo", "bar"] } + }); + Select.vm.select("bar"); + Select.vm.select("bar"); + expect(Select.emitted("option:selecting")).toEqual([["bar"], ["bar"]]); + }); + }); + + describe("option:deselected Event", () => { + it("will trigger the option:deselected event when an option is deselected", () => { + const Select = shallowMount(VueSelect, { + propsData: { value: ["foo"], options: ["foo", "bar"] } + }); + Select.vm.deselect("foo"); + expect(Select.emitted("option:deselected")[0]).toEqual(["foo"]); + }); + + it("will trigger the option:deselected event regardless of current value", () => { + const Select = shallowMount(VueSelect, { + propsData: { value: ["foo"], options: ["foo", "bar"] } + }); + Select.vm.deselect("foo"); + Select.vm.deselect("bar"); + expect(Select.emitted("option:deselected")).toEqual([["foo"], ["bar"]]); + }); + + it("will trigger the option:selected event with current selected item when multiple is true", () => { + const Select = shallowMount(VueSelect, { + propsData: { multiple: true, value: ["foo"], options: ["foo", "bar"] } + }); + Select.vm.deselect("bar"); + expect(Select.emitted("option:deselected")[0]).toEqual(["bar"]); + }); + + it("will trigger the option:selected event regardless of current value when multiple is true", () => { + const Select = shallowMount(VueSelect, { + propsData: { multiple: true, value: ["foo", "bar"], options: ["foo", "bar"] } + }); + Select.vm.deselect("bar"); + Select.vm.deselect("bar"); + expect(Select.emitted("option:deselected")).toEqual([["bar"], ["bar"]]); + }); }); });