diff --git a/src/ng/directive/select.js b/src/ng/directive/select.js index c4498f81e2d..19e9b04b3cb 100644 --- a/src/ng/directive/select.js +++ b/src/ng/directive/select.js @@ -252,7 +252,9 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { if (selectCtrl.hasOption(viewValue)) { if (unknownOption.parent()) unknownOption.remove(); selectElement.val(viewValue); - if (viewValue === '') emptyOption.prop('selected', true); // to make IE9 happy + if (msie && msie <= 9) { + forceRepaint(selectElement); + } } else { if (isUndefined(viewValue) && emptyOption) { selectElement.val(''); @@ -301,6 +303,18 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { }); } + function forceRepaint(selectElement) { + var option = document.createElement('option'); + viewValue = selectElement.val(); + selectElement[0].add(option, null); + selectElement[0].remove(selectElement[0].options.length - 1); + for(var i = 0, children = selectElement.children(), ii = children.length; i < ii; i++) { + if (children[i]) { + children.eq(i).prop('selected', children[i].value === viewValue) + } + } + }; + function setupAsOptions(scope, selectElement, ctrl) { var match; @@ -396,6 +410,9 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { } } ctrl.$setViewValue(value); + if (msie && msie <= 9 && !multiple) { + forceRepaint(selectElement); + } }); }); @@ -575,6 +592,13 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { while(optionGroupsCache.length > groupIndex) { optionGroupsCache.pop()[0].element.remove(); } + if (msie && msie <= 9 && !multiple) { + // the add an option then remove technique doesn't work too well for active + // elements and optgroups + if (optionGroup.length == 1 && selectElement[0] !== document.activeElement) { + forceRepaint(selectElement); + } + } } } } diff --git a/test/ng/directive/selectSpec.js b/test/ng/directive/selectSpec.js index 6fcd1fe05f8..7e1a111f77d 100644 --- a/test/ng/directive/selectSpec.js +++ b/test/ng/directive/selectSpec.js @@ -617,6 +617,32 @@ describe('select', function() { expect(element.find('option').length).toEqual(1); // we add back the special empty option }); + it('should select correct option when list is shrunk ', function() { + createSingleSelect(); + + scope.$apply(function() { + scope.values = [{name:'A'}, {name:'B'}, {name:'C'}]; + scope.selected = null + }); + + expect(element.find('option').length).toBe(4); + expect(element).toEqualSelect([''], '0', '1', '2'); + element.find('option').eq(1).prop('selected', true); + browserTrigger(element.find('option').eq(1)); + scope.$digest(); + expect(element).toEqualSelect(['0'], '1', '2'); + expect(scope.selected).toEqual({name: 'A'}) + + var A = element.find('option').eq(0); + expect(A.prop('value')).toBe('0'); + expect(A.prop('selected')).toBeTruthy(); + expect(A[0].selected).toBeTruthy(); + + var B = element.find('option').eq(1); + expect(B.prop('value')).toBe('1'); + expect(B.prop('selected')).toBeFalsy(); + expect(B[0].selected).toBeFalsy(); + }); it('should shrink and then grow list', function() { createSingleSelect();