11var utils = require ( '../utils' ) ,
22 isIE9 = navigator . userAgent . indexOf ( 'MSIE 9.0' ) > 0
33
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+
417module . exports = {
518
619 bind : function ( ) {
@@ -21,17 +34,22 @@ module.exports = {
2134 : 'input'
2235
2336 // determine the attribute to change when updating
24- var attr = self . attr = type === 'checkbox'
37+ self . attr = type === 'checkbox'
2538 ? 'checked'
2639 : ( tag === 'INPUT' || tag === 'SELECT' || tag === 'TEXTAREA' )
2740 ? 'value'
2841 : 'innerHTML'
2942
43+ // select[multiple] support
44+ if ( tag === 'SELECT' && el . hasAttribute ( 'multiple' ) ) {
45+ this . multi = true
46+ }
47+
3048 var compositionLock = false
31- this . cLock = function ( ) {
49+ self . cLock = function ( ) {
3250 compositionLock = true
3351 }
34- this . cUnlock = function ( ) {
52+ self . cUnlock = function ( ) {
3553 compositionLock = false
3654 }
3755 el . addEventListener ( 'compositionstart' , this . cLock )
@@ -48,10 +66,10 @@ module.exports = {
4866 // so that after vm.$set changes the input
4967 // value we can put the cursor back at where it is
5068 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+
5573 // since updates are async
5674 // we need to reset cursor position async too
5775 utils . nextTick ( function ( ) {
@@ -64,7 +82,9 @@ module.exports = {
6482 if ( compositionLock ) return
6583 // no filters, don't let it trigger update()
6684 self . lock = true
67- self . vm . $set ( self . key , el [ attr ] )
85+
86+ self . _set ( )
87+
6888 utils . nextTick ( function ( ) {
6989 self . lock = false
7090 } )
@@ -90,29 +110,45 @@ module.exports = {
90110 }
91111 } ,
92112
113+ _set : function ( ) {
114+ this . vm . $set (
115+ this . key , this . multi
116+ ? getMultipleSelectOptions ( this . el )
117+ : this . el [ this . attr ]
118+ )
119+ } ,
120+
93121 update : function ( value ) {
94- if ( this . lock ) return
95122 /* jshint eqeqeq: false */
96- var self = this ,
97- el = self . el
123+ if ( this . lock ) return
124+ var el = this . el
98125 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 )
108131 }
109- o . selectedIndex = index
110132 } else if ( el . type === 'radio' ) { // radio button
111133 el . checked = value == el . value
112134 } else if ( el . type === 'checkbox' ) { // checkbox
113135 el . checked = ! ! value
114136 } 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+ }
116152 }
117153 } ,
118154
0 commit comments