1
1
var utils = require ( '../utils' ) ,
2
2
isIE9 = navigator . userAgent . indexOf ( 'MSIE 9.0' ) > 0
3
3
4
+ /**
5
+ * Returns an array of values from a multiple select
6
+ */
7
+ function getMultipleSelectOptions ( select ) {
8
+ return Array . prototype . filter
9
+ . call ( select . options , function ( option ) {
10
+ return option . selected
11
+ } )
12
+ . map ( function ( option ) {
13
+ return option . value || option . text
14
+ } )
15
+ }
16
+
4
17
module . exports = {
5
18
6
19
bind : function ( ) {
@@ -21,17 +34,22 @@ module.exports = {
21
34
: 'input'
22
35
23
36
// determine the attribute to change when updating
24
- var attr = self . attr = type === 'checkbox'
37
+ self . attr = type === 'checkbox'
25
38
? 'checked'
26
39
: ( tag === 'INPUT' || tag === 'SELECT' || tag === 'TEXTAREA' )
27
40
? 'value'
28
41
: 'innerHTML'
29
42
43
+ // select[multiple] support
44
+ if ( tag === 'SELECT' && el . hasAttribute ( 'multiple' ) ) {
45
+ this . multi = true
46
+ }
47
+
30
48
var compositionLock = false
31
- this . cLock = function ( ) {
49
+ self . cLock = function ( ) {
32
50
compositionLock = true
33
51
}
34
- this . cUnlock = function ( ) {
52
+ self . cUnlock = function ( ) {
35
53
compositionLock = false
36
54
}
37
55
el . addEventListener ( 'compositionstart' , this . cLock )
@@ -48,10 +66,10 @@ module.exports = {
48
66
// so that after vm.$set changes the input
49
67
// value we can put the cursor back at where it is
50
68
var cursorPos
51
- try {
52
- cursorPos = el . selectionStart
53
- } catch ( e ) { }
54
- self . vm . $set ( self . key , el [ attr ] )
69
+ try { cursorPos = el . selectionStart } catch ( e ) { }
70
+
71
+ self . _set ( )
72
+
55
73
// since updates are async
56
74
// we need to reset cursor position async too
57
75
utils . nextTick ( function ( ) {
@@ -64,7 +82,9 @@ module.exports = {
64
82
if ( compositionLock ) return
65
83
// no filters, don't let it trigger update()
66
84
self . lock = true
67
- self . vm . $set ( self . key , el [ attr ] )
85
+
86
+ self . _set ( )
87
+
68
88
utils . nextTick ( function ( ) {
69
89
self . lock = false
70
90
} )
@@ -90,29 +110,45 @@ module.exports = {
90
110
}
91
111
} ,
92
112
113
+ _set : function ( ) {
114
+ this . vm . $set (
115
+ this . key , this . multi
116
+ ? getMultipleSelectOptions ( this . el )
117
+ : this . el [ this . attr ]
118
+ )
119
+ } ,
120
+
93
121
update : function ( value ) {
94
- if ( this . lock ) return
95
122
/* jshint eqeqeq: false */
96
- var self = this ,
97
- el = self . el
123
+ if ( this . lock ) return
124
+ var el = this . el
98
125
if ( el . tagName === 'SELECT' ) { // select dropdown
99
- // setting <select>'s value in IE9 doesn't work
100
- var o = el . options ,
101
- i = o . length ,
102
- index = - 1
103
- while ( i -- ) {
104
- if ( o [ i ] . value == value ) {
105
- index = i
106
- break
107
- }
126
+ el . selectedIndex = - 1
127
+ if ( this . multi && Array . isArray ( value ) ) {
128
+ value . forEach ( this . updateSelect , this )
129
+ } else {
130
+ this . updateSelect ( value )
108
131
}
109
- o . selectedIndex = index
110
132
} else if ( el . type === 'radio' ) { // radio button
111
133
el . checked = value == el . value
112
134
} else if ( el . type === 'checkbox' ) { // checkbox
113
135
el . checked = ! ! value
114
136
} else {
115
- el [ self . attr ] = utils . toText ( value )
137
+ el [ this . attr ] = utils . toText ( value )
138
+ }
139
+ } ,
140
+
141
+ updateSelect : function ( value ) {
142
+ /* jshint eqeqeq: false */
143
+ // setting <select>'s value in IE9 doesn't work
144
+ // we have to manually loop through the options
145
+ var options = this . el . options ,
146
+ i = options . length
147
+ while ( i -- ) {
148
+ if ( options [ i ] . value == value ) {
149
+ options [ i ] . selected = true
150
+ break
151
+ }
116
152
}
117
153
} ,
118
154
0 commit comments