Skip to content

Commit 68ca564

Browse files
committed
support static default option in <select> with options param (close #1103)
1 parent 425d4d3 commit 68ca564

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

src/directives/model/select.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ module.exports = {
4343
update: function (value) {
4444
var el = this.el
4545
el.selectedIndex = -1
46+
if (!value) {
47+
if (this.defaultOption) {
48+
this.defaultOption.selected = true
49+
}
50+
return
51+
}
4652
var multi = this.multiple && _.isArray(value)
4753
var options = el.options
4854
var i = options.length
@@ -75,11 +81,22 @@ module.exports = {
7581

7682
function initOptions (expression) {
7783
var self = this
84+
var el = self.el
85+
var defaultOption = self.defaultOption = self.el.options[0]
7886
var descriptor = dirParser.parse(expression)[0]
7987
function optionUpdateWatcher (value) {
8088
if (_.isArray(value)) {
81-
self.el.innerHTML = ''
82-
buildOptions(self.el, value)
89+
// clear old options.
90+
// cannot reset innerHTML here because IE family get
91+
// confused during compilation.
92+
var i = el.options.length
93+
while (i--) {
94+
var option = el.options[i]
95+
if (option !== defaultOption) {
96+
el.removeChild(option)
97+
}
98+
}
99+
buildOptions(el, value)
83100
self.forceUpdate()
84101
} else {
85102
process.env.NODE_ENV !== 'production' && _.warn(

test/unit/specs/directives/model_spec.js

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,11 +369,39 @@ if (_.inBrowser) {
369369
template: '<select v-model="test" options="opts | aFilter"></select>'
370370
})
371371
expect(el.firstChild.innerHTML).toBe(
372-
'<option value="a0">a0</option>' +
373-
'<option value="b1">b1</option>'
372+
'<option value="a0">a0</option>' +
373+
'<option value="b1">b1</option>'
374374
)
375375
})
376376

377+
it('select + options + static option', function (done) {
378+
var vm = new Vue({
379+
el: el,
380+
data: {
381+
opts: ['a', 'b']
382+
},
383+
template:
384+
'<select v-model="test" options="opts">' +
385+
'<option value="">default...</option>' +
386+
'</select>'
387+
})
388+
expect(el.firstChild.innerHTML).toBe(
389+
'<option value="">default...</option>' +
390+
'<option value="a">a</option>' +
391+
'<option value="b">b</option>'
392+
)
393+
expect(el.firstChild.options[0].selected).toBe(true)
394+
vm.opts = ['c']
395+
_.nextTick(function () {
396+
expect(el.firstChild.innerHTML).toBe(
397+
'<option value="">default...</option>' +
398+
'<option value="c">c</option>'
399+
)
400+
expect(el.firstChild.options[0].selected).toBe(true)
401+
done()
402+
})
403+
})
404+
377405
it('text', function (done) {
378406
var vm = new Vue({
379407
el: el,

0 commit comments

Comments
 (0)