From 258bbce0be5d9ae9b41ced11411d65553b883479 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Thu, 31 Jul 2014 09:31:14 +0100 Subject: [PATCH] fix(select): ensure that at least one option has the `selected` attribute set Using `prop` to set selected is correct programmatically but accessibility guidelines suggest that at least on item should have the `selected` attribute set. Closes #8366 --- src/ng/directive/select.js | 1 + test/ng/directive/selectSpec.js | 41 +++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/ng/directive/select.js b/src/ng/directive/select.js index c2b5a6d6c0ee..8bb93c56ceec 100644 --- a/src/ng/directive/select.js +++ b/src/ng/directive/select.js @@ -576,6 +576,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { (element = optionTemplate.clone()) .val(option.id) .prop('selected', option.selected) + .attr('selected', option.selected) .text(option.label); } diff --git a/test/ng/directive/selectSpec.js b/test/ng/directive/selectSpec.js index 3261605ffbde..ec40e277cc57 100644 --- a/test/ng/directive/selectSpec.js +++ b/test/ng/directive/selectSpec.js @@ -1008,6 +1008,47 @@ describe('select', function() { expect(scope.selected).toBe(scope.values[1]); }); + + + it('should ensure that at least one option element has the "selected" attribute', function() { + createSelect({ + 'ng-model': 'selected', + 'ng-options': 'item.id as item.name for item in values' + }); + + scope.$apply(function() { + scope.values = [{id: 10, name: 'A'}, {id: 20, name: 'B'}]; + }); + expect(element.val()).toEqual('?'); + expect(element.find('option').eq(0).attr('selected')).toEqual('selected'); + + scope.$apply(function() { + scope.selected = 10; + }); + // Here the ? option should disappear and the first real option should have selected attribute + expect(element.val()).toEqual('0'); + expect(element.find('option').eq(0).attr('selected')).toEqual('selected'); + + // Here the selected value is changed but we don't change the selected attribute + scope.$apply(function() { + scope.selected = 20; + }); + expect(element.val()).toEqual('1'); + expect(element.find('option').eq(0).attr('selected')).toEqual('selected'); + + scope.$apply(function() { + scope.values.push({id: 30, name: 'C'}); + }); + expect(element.val()).toEqual('1'); + expect(element.find('option').eq(0).attr('selected')).toEqual('selected'); + + // Here the ? option should reappear and have selected attribute + scope.$apply(function() { + scope.selected = undefined; + }); + expect(element.val()).toEqual('?'); + expect(element.find('option').eq(0).attr('selected')).toEqual('selected'); + }); });