Skip to content

Commit 4d4a5f3

Browse files
bugyafontcu
andauthored
allow array for multiselect .setValue() method (#1554)
* feat(wrapper.setvalue): allow array for multiselect .setValue() method enables Wrapper.setValue() method to accept array value for select elements (requires select to have an attribute 'multiple' or 'multiple="true"') fix #1505 * fix "missing property" error * Update test/specs/wrapper/setValue.spec.js Co-authored-by: Adrià Fontcuberta <[email protected]> * Update test/specs/wrapper/setValue.spec.js Co-authored-by: Adrià Fontcuberta <[email protected]> Co-authored-by: Adrià Fontcuberta <[email protected]>
1 parent e5b0f00 commit 4d4a5f3

File tree

7 files changed

+72
-15
lines changed

7 files changed

+72
-15
lines changed

Diff for: docs/api/wrapper/setValue.md

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ textInput.setValue('some value')
1919

2020
const select = wrapper.find('select')
2121
select.setValue('option value')
22+
23+
// requires <select multiple>
24+
const multiselect = wrapper.find('select')
25+
multiselect.setValue(['value1', 'value3'])
2226
```
2327

2428
- **Note:**

Diff for: docs/ja/api/wrapper/setValue.md

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ textInput.setValue('some value')
1919

2020
const select = wrapper.find('select')
2121
select.setValue('option value')
22+
23+
// requires <select multiple>
24+
const multiselect = wrapper.find('select')
25+
multiselect.setValue(['value1', 'value3'])
2226
```
2327

2428
- **注:**

Diff for: docs/ru/api/wrapper/setValue.md

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ textInput.setValue('some value')
1919

2020
const select = wrapper.find('select')
2121
select.setValue('option value')
22+
23+
// требует <select multiple>
24+
const multiselect = wrapper.find('select')
25+
multiselect.setValue(['value1', 'value3'])
2226
```
2327

2428
- **Примечание:**

Diff for: docs/zh/api/wrapper/setValue.md

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ textInput.setValue('some value')
1919

2020
const select = wrapper.find('select')
2121
select.setValue('option value')
22+
23+
// requires <select multiple>
24+
const multiselect = wrapper.find('select')
25+
multiselect.setValue(['value1', 'value3'])
2226
```
2327

2428
- **注意:**

Diff for: packages/test-utils/src/wrapper.js

+18-15
Original file line numberDiff line numberDiff line change
@@ -744,27 +744,30 @@ export default class Wrapper implements BaseWrapper {
744744
`wrapper.setValue() cannot be called on a <input type="radio" /> ` +
745745
`element. Use wrapper.setChecked() instead`
746746
)
747-
} else if (
748-
tagName === 'INPUT' ||
749-
tagName === 'TEXTAREA' ||
750-
tagName === 'SELECT'
751-
) {
747+
} else if (tagName === 'SELECT') {
748+
if (Array.isArray(value)) {
749+
// $FlowIgnore
750+
const options = this.element.options
751+
for (let i = 0; i < options.length; i++) {
752+
const option = options[i]
753+
option.selected = value.indexOf(option.value) >= 0
754+
}
755+
} else {
756+
// $FlowIgnore
757+
this.element.value = value
758+
}
759+
760+
this.trigger('change')
761+
return nextTick()
762+
} else if (tagName === 'INPUT' || tagName === 'TEXTAREA') {
752763
// $FlowIgnore
753764
this.element.value = value
754765

755-
if (tagName === 'SELECT') {
756-
this.trigger('change')
757-
} else {
758-
this.trigger('input')
759-
}
766+
this.trigger('input')
760767

761768
// for v-model.lazy, we need to trigger a change event, too.
762769
// $FlowIgnore
763-
if (
764-
(tagName === 'INPUT' || tagName === 'TEXTAREA') &&
765-
this.element._vModifiers &&
766-
this.element._vModifiers.lazy
767-
) {
770+
if (this.element._vModifiers && this.element._vModifiers.lazy) {
768771
this.trigger('change')
769772
}
770773
return nextTick()

Diff for: test/resources/components/component-with-input.vue

+7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@
2020
<option value="selectB"></option>
2121
<option value="selectC"></option>
2222
</select>
23+
<select v-model="multiselectVal" class="multiselect" multiple>
24+
<option value="selectA"></option>
25+
<option value="selectB"></option>
26+
<option value="selectC"></option>
27+
</select>
2328
<select v-model="selectVal" class="with-optgroups">
2429
<optgroup label="Group1">
2530
<option value="selectA"></option>
@@ -35,6 +40,7 @@
3540
<span class="counter">{{ counter }}</span>
3641
{{ textVal }}
3742
{{ selectVal }}
43+
{{ JSON.stringify(multiselectVal) }}
3844
{{ radioVal }}
3945
<input id="lazy" type="text" v-model.lazy="lazy" />
4046
{{ lazy }}
@@ -52,6 +58,7 @@ export default {
5258
textareaVal: undefined,
5359
radioVal: undefined,
5460
selectVal: undefined,
61+
multiselectVal: [],
5562
counter: 0
5663
}
5764
},

Diff for: test/specs/wrapper/setValue.spec.js

+31
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,37 @@ describeWithShallowAndMount('setValue', mountingMethod => {
6565
expect(wrapper.text()).to.contain('selectB')
6666
})
6767

68+
it('sets element of multiselect value', () => {
69+
const wrapper = mountingMethod(ComponentWithInput)
70+
const select = wrapper.find('select.multiselect')
71+
select.setValue(['selectA', 'selectC'])
72+
73+
const selectedOptions = Array.from(select.element.selectedOptions).map(
74+
o => o.value
75+
)
76+
expect(selectedOptions).to.deep.equal(['selectA', 'selectC'])
77+
})
78+
79+
it('overrides elements of multiselect', () => {
80+
const wrapper = mountingMethod(ComponentWithInput)
81+
const select = wrapper.find('select.multiselect')
82+
select.setValue(['selectA', 'selectC'])
83+
select.setValue(['selectB'])
84+
85+
const selectedOptions = Array.from(select.element.selectedOptions).map(
86+
o => o.value
87+
)
88+
expect(selectedOptions).to.deep.equal(['selectB'])
89+
})
90+
91+
it('updates dom with multiselect v-model when array', async () => {
92+
const wrapper = mountingMethod(ComponentWithInput)
93+
const select = wrapper.find('select.multiselect')
94+
await select.setValue(['selectA', 'selectC'])
95+
96+
expect(wrapper.text()).to.contain('["selectA","selectC"]')
97+
})
98+
6899
it('throws error if element is option', () => {
69100
const message =
70101
'wrapper.setValue() cannot be called on an <option> element. Use wrapper.setSelected() instead'

0 commit comments

Comments
 (0)