Skip to content

Commit 8beddb9

Browse files
committed
fix(ngOptions): always set the 'selected' attribute for selected options
We don't set selected property / attribute on options that are already selected. That happens for example if the browser has automatically selected the first option in a select. In that case, the selected property is set automatically, but the selected attribute is not Closes angular#14115
1 parent 3c86212 commit 8beddb9

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

src/ng/directive/ngOptions.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,14 +468,20 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
468468
var option = options.getOptionFromViewValue(value);
469469

470470
if (option && !option.disabled) {
471+
// Don't update the option when it is already selected.
472+
// For example, the browser will select the first option by default. In that case,
473+
// most properties are set automatically - except the `selected` attribute, which we
474+
// set always
475+
471476
if (selectElement[0].value !== option.selectValue) {
472477
removeUnknownOption();
473478
removeEmptyOption();
474479

475480
selectElement[0].value = option.selectValue;
476481
option.element.selected = true;
477-
option.element.setAttribute('selected', 'selected');
478482
}
483+
484+
option.element.setAttribute('selected', 'selected');
479485
} else {
480486
if (value === null || providedEmptyOption) {
481487
removeUnknownOption();

test/ng/directive/ngOptionsSpec.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,40 @@ describe('ngOptions', function() {
298298

299299
});
300300

301+
it('should set the "selected" attribute and property on selected options', function() {
302+
scope.values = [{
303+
id: 'FF0000',
304+
display: 'red'
305+
}, {
306+
id: '0000FF',
307+
display: 'blue'
308+
}];
309+
scope.selected = 'FF0000';
310+
311+
createSelect({
312+
'ng-model': 'selected',
313+
'ng-options': 'option.id as option.display for option in values'
314+
});
315+
scope.$digest();
316+
317+
var options = element.find('option');
318+
expect(options.length).toEqual(2);
319+
expect(options.eq(0)).toEqualOption('FF0000', 'red');
320+
expect(options.eq(1)).toEqualOption('0000FF', 'blue');
321+
322+
expect(options.eq(0)[0].getAttribute('selected')).toBe('selected');
323+
expect(options.eq(0).attr('selected')).toBe('selected');
324+
expect(options.eq(0)[0].selected).toBe(true);
325+
expect(options.eq(0).prop('selected')).toBe(true);
326+
327+
scope.selected = '0000FF';
328+
scope.$digest();
329+
330+
expect(options.eq(1)[0].getAttribute('selected')).toBe('selected');
331+
expect(options.eq(1).attr('selected')).toBe('selected');
332+
expect(options.eq(1)[0].selected).toBe(true);
333+
expect(options.eq(1).prop('selected')).toBe(true);
334+
});
301335

302336
it('should render zero as a valid display value', function() {
303337
createSingleSelect();

0 commit comments

Comments
 (0)