Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 2c54a3c

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. This doesn't impact the functionality of the select, but it can be problematic if option elements are selected with `option[selected]` in tests. Closes #14115 Closes #14125
1 parent 5078c76 commit 2c54a3c

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)