@@ -48,19 +48,43 @@ var SelectController =
48
48
// Read the value of the select control, the implementation of this changes depending
49
49
// upon whether the select can have multiple values and whether ngOptions is at work.
50
50
self . readValue = function readSingleValue ( ) {
51
- self . removeUnknownOption ( ) ;
52
51
var val = $element . val ( ) ;
53
52
// ngValue added option values are stored in the selectValueMap, normal interpolations are not
54
- return val in self . selectValueMap ? self . selectValueMap [ val ] : val ;
53
+ var realVal = val in self . selectValueMap ? self . selectValueMap [ val ] : val ;
54
+
55
+ console . log ( 'read' , 'elval' , val , 'possiblyhashed' , realVal )
56
+ if ( self . hasOption ( realVal ) ) {
57
+ console . log ( 'has selected val' , realVal )
58
+ // self.removeUnknownOption();
59
+ return realVal ;
60
+ }
61
+
62
+ return null ;
55
63
} ;
56
64
57
65
58
66
// Write the value to the select control, the implementation of this changes depending
59
67
// upon whether the select can have multiple values and whether ngOptions is at work.
60
68
self . writeValue = function writeSingleValue ( value ) {
69
+ console . log ( 'write' , value ) ;
61
70
if ( self . hasOption ( value ) ) {
71
+ console . log ( 'hasOption' , value ) ;
62
72
self . removeUnknownOption ( ) ;
63
- $element . val ( value ) ;
73
+ var hashedVal = hashKey ( value ) ;
74
+ if ( hashedVal in self . selectValueMap ) {
75
+ $element . val ( hashedVal ) ;
76
+ } else {
77
+ $element . val ( value ) ;
78
+ }
79
+ console . log ( 'after set' , $element . val ( ) )
80
+ // console.log('selectValueMap', self.selectValueMap)
81
+ // var items = new HashMap();
82
+ // items.put(value, value);
83
+ // console.log(items, hashKey(value));
84
+
85
+ // if (hashKey(value) in self.selectValueMap) {
86
+ // console.log('hashed')
87
+ // }
64
88
if ( value === '' ) self . emptyOption . prop ( 'selected' , true ) ; // to make IE9 happy
65
89
} else {
66
90
if ( value == null && self . emptyOption ) {
@@ -110,50 +134,124 @@ var SelectController =
110
134
111
135
self . registerOption = function ( optionScope , optionElement , optionAttrs , interpolateValueFn , interpolateTextFn ) {
112
136
113
- if ( interpolateValueFn === true ) {
137
+ // console.log('attr', optionAttrs)
138
+ if ( optionAttrs . $attr . ngValue ) {
114
139
// The value attribute is set by ngValue
115
140
var oldVal , hashedVal = NaN ;
116
141
optionAttrs . $observe ( 'value' , function valueAttributeObserveAction ( newVal ) {
142
+ console . log ( 'ngValue change' , 'n' , newVal , 'o' , oldVal , 'hashed' , hashedVal )
143
+
144
+ var removal ;
145
+ console . log ( 'val' , $element . val ( ) ) ;
146
+ var previouslySelected = optionElement . prop ( 'selected' ) ;
147
+
117
148
if ( isDefined ( hashedVal ) ) {
118
149
self . removeOption ( oldVal ) ;
119
150
delete self . selectValueMap [ hashedVal ] ;
151
+ removal = true ;
120
152
}
121
153
122
154
hashedVal = hashKey ( newVal ) ;
123
155
oldVal = newVal ;
124
- self . addOption ( newVal , optionElement ) ;
125
156
self . selectValueMap [ hashedVal ] = newVal ;
157
+ self . addOption ( newVal , optionElement ) ;
158
+ console . log ( 'val' , $element . val ( ) ) ;
126
159
// Set the attribute directly instead of using optionAttrs.$set - this stops the observer
127
160
// from firing a second time. Other $observers on value will also get the result of the
128
161
// ngValue expression, not the hashed value
129
162
optionElement . attr ( 'value' , hashedVal ) ;
163
+
164
+ console . log ( 'previouslySelected' , previouslySelected , 'removal' , removal )
165
+
166
+ if ( removal && previouslySelected ) {
167
+ console . log ( 'removed val is currently selected' , $element . val ( ) )
168
+ self . ngModelCtrl . $setViewValue ( self . readValue ( ) ) ;
169
+ }
170
+
130
171
} ) ;
131
172
} else if ( interpolateValueFn ) {
132
173
// The value attribute is interpolated
133
174
optionAttrs . $observe ( 'value' , function valueAttributeObserveAction ( newVal ) {
175
+ // console.log('value attribute changed', 'viewVal', self.ngModelCtrl.$viewValue, 'index', optionElement[0].index, 'indices', $element[0].selectedIndex, $element[0].selectedOptions)
176
+ var currentVal = self . readValue ( ) ;
177
+ var removal ;
178
+ var previouslySelected = optionElement . prop ( 'selected' ) ;
179
+ var removedVal ;
180
+
134
181
if ( isDefined ( oldVal ) ) {
135
182
self . removeOption ( oldVal ) ;
183
+ removal = true ;
184
+ removedVal = oldVal ;
136
185
}
137
186
oldVal = newVal ;
138
187
self . addOption ( newVal , optionElement ) ;
188
+
189
+ console . log ( 'updated interpolated value' , 'new' , newVal , 'removed' , removedVal , 'current' , currentVal ) ;
190
+ if ( removal && previouslySelected ) {
191
+ console . log ( 'removed val is currently selected' , $element . val ( ) )
192
+ self . ngModelCtrl . $setViewValue ( self . readValue ( ) ) ;
193
+ }
139
194
} ) ;
140
195
} else if ( interpolateTextFn ) {
141
196
// The text content is interpolated
142
197
optionScope . $watch ( interpolateTextFn , function interpolateWatchAction ( newVal , oldVal ) {
143
198
optionAttrs . $set ( 'value' , newVal ) ;
199
+ var previouslySelected = optionElement . prop ( 'selected' ) ;
144
200
if ( oldVal !== newVal ) {
145
201
self . removeOption ( oldVal ) ;
146
202
}
147
203
self . addOption ( newVal , optionElement ) ;
204
+
205
+ if ( oldVal && previouslySelected ) {
206
+ self . ngModelCtrl . $setViewValue ( self . readValue ( ) ) ;
207
+ }
148
208
} ) ;
149
209
} else {
150
210
// The value attribute is static
151
211
self . addOption ( optionAttrs . value , optionElement ) ;
152
212
}
153
213
214
+
215
+ var oldDisabled ;
216
+ optionAttrs . $observe ( 'disabled' , function ( newVal ) {
217
+
218
+ // Since model updates will also select disabled options (like ngOptions),
219
+ // we only have to handle options becomeing disabled, not enabled
220
+
221
+ if ( newVal === 'true' || newVal && optionElement . prop ( 'selected' ) ) {
222
+ console . log ( 'disabled' )
223
+ self . ngModelCtrl . $setViewValue ( null ) ;
224
+ self . ngModelCtrl . $render ( ) ;
225
+ oldDisabled = newVal ;
226
+ } else if ( isDefined ( oldDisabled ) && ! newVal || newVal === 'false' ) {
227
+ // var val = optionAttrs.value;
228
+ // console.log('OA', optionAttrs.value);
229
+ // var realVal = val in self.selectValueMap ? self.selectValueMap[val] : val;
230
+ // console.log('back from disabled', val, realVal, self.ngModelCtrl.$viewValue);
231
+
232
+ // if (realVal === self.ngModelCtrl.$viewValue) {
233
+ // self.writeValue(realVal);
234
+ // self.ngModelCtrl.$setViewValue(self.readValue());
235
+ // }
236
+ }
237
+ } ) ;
238
+
154
239
optionElement . on ( '$destroy' , function ( ) {
155
- self . removeOption ( optionAttrs . value ) ;
240
+ var currentValue = self . readValue ( ) ;
241
+ var removeValue = optionAttrs . value ;
242
+
243
+ console . log ( 'destroy' , removeValue , 'elval' , $element . val ( ) )
244
+ // console.log('viewValue', self.ngModelCtrl.$viewValue)
245
+ self . removeOption ( removeValue ) ;
156
246
self . ngModelCtrl . $render ( ) ;
247
+
248
+ if ( currentValue === removeValue ) {
249
+ // console.log('removed val is currently selected', $element.val())
250
+ // console.log('self.readValue()', self.readValue());
251
+ self . ngModelCtrl . $setViewValue ( self . readValue ( ) ) ;
252
+
253
+ }
254
+ // console.log('read after render', self.readValue())
157
255
} ) ;
158
256
} ;
159
257
} ] ;
@@ -389,6 +487,8 @@ var selectDirective = function() {
389
487
// to the `readValue` method, which can be changed if the select can have multiple
390
488
// selected values or if the options are being generated by `ngOptions`
391
489
element . on ( 'change' , function ( ) {
490
+ console . log ( 'on change' , element . val ( ) )
491
+ selectCtrl . removeUnknownOption ( ) ;
392
492
scope . $apply ( function ( ) {
393
493
ngModelCtrl . $setViewValue ( selectCtrl . readValue ( ) ) ;
394
494
} ) ;
@@ -467,17 +567,17 @@ var optionDirective = ['$interpolate', function($interpolate) {
467
567
restrict : 'E' ,
468
568
priority : 100 ,
469
569
compile : function ( element , attr ) {
470
- var interpolateValueFn ;
570
+ var interpolateValueFn , interpolateTextFn ;
471
571
472
572
if ( isDefined ( attr . ngValue ) ) {
473
- interpolateValueFn = true ;
573
+ // Will be handled by registerOption
474
574
} else if ( isDefined ( attr . value ) ) {
475
575
// If the value attribute is defined, check if it contains an interpolation
476
576
interpolateValueFn = $interpolate ( attr . value , true ) ;
477
577
} else {
478
578
// If the value attribute is not defined then we fall back to the
479
579
// text content of the option element, which may be interpolated
480
- var interpolateTextFn = $interpolate ( element . text ( ) , true ) ;
580
+ interpolateTextFn = $interpolate ( element . text ( ) , true ) ;
481
581
if ( ! interpolateTextFn ) {
482
582
attr . $set ( 'value' , element . text ( ) ) ;
483
583
}
0 commit comments