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

"Selected" attributes for <select> options elements not being updated properly #14419

Closed
gallor opened this issue Apr 12, 2016 · 2 comments · Fixed by #14894
Closed

"Selected" attributes for <select> options elements not being updated properly #14419

gallor opened this issue Apr 12, 2016 · 2 comments · Fixed by #14894

Comments

@gallor
Copy link

gallor commented Apr 12, 2016

Request Type: bug

Current Behavior:
When a select element is created with both ng-options and ng-model attributes to track the selected option, the "selected" element property is added to the selected attribute (per this issue: #8366). However, when a different option is selected, the "selected" attribute is not removed, resulting in all of the options containing a selected="selected" attribute (if all options have been selected). This is important due to accessibility guidelines stipulate the use of the selected attribute on options to indicate what option has been selected. Aria Guidelines.

Reproduce?
Any select box that has a ng-model tracking the value within an ng-options attribute for a select element. This is a modification of the Angular docs example for ng-options that illustrates nicely the select attribute not being added and removed properly: https://plnkr.co/edit/PjbWbo

Expected behavior?
Only one selected="selected" attributes should be present within the options of a select element. When a selection is changed the attribute should be removed and added to the newly selected option.

What is the motivation / use case for changing the behavior?
As per mentioned above, having one option with a selected attribute allows for proper accessibility functionality.

Versions
This was tested in Angular 1.4.1 and 1.5.3 in Chrome 49, Canary 52, Safari 9 and Firefox 42

I found this was addressed in commits 79538af and 3d393dc

@Narretz
Copy link
Contributor

Narretz commented Apr 12, 2016

Do you know if this actually causes aria issues in practice? Because the selected attribute / property is not a very good indicator of seeing which option is actually selected. The bulletproof way to go should be the selectedIndex property on the select itself. So I don't know how screenreaders handle this, it seems to me they would be looking at selectedIndex rather than the selected attribute.
But wen can definitely try to fix that. Do you want to give a PR a shot?

@Narretz Narretz added this to the Backlog milestone Apr 12, 2016
@gallor
Copy link
Author

gallor commented Apr 12, 2016

I agree that the selectedIndex would be the bulletproof way of returning what option value is selected. However I believe screen readers are looking for the actual selected="selected" DOM property on the option so that when an option is selected, feedback would be provided accordingly.
And sure, I'll give a PR a shot.

Narretz added a commit to Narretz/angular.js that referenced this issue Jul 11, 2016
When the select model changes, we add the "selected" attribute to the selected option, so that
screen readers know which option is selected.

Previously, we failed to remove the attribute when the model changed to match a different option, or
the unknown / empty option.

When using "track by", the behavior would also show when a user selected an option, and then the
model was changed, because track by watches the tracked expression, and calls the $render function
on change.

This fix reads the current select value, finds the matching option and removes the "selected"
attribute.

Fixes angular#14892
Fixes angular#14419
Related angular#12731
Narretz added a commit to Narretz/angular.js that referenced this issue Jul 22, 2016
When the select model changes, we add the "selected" attribute to the selected option, so that
screen readers know which option is selected.

Previously, we failed to remove the attribute when the model changed to match a different option, or
the unknown / empty option.

When using "track by", the behavior would also show when a user selected an option, and then the
model was changed, because track by watches the tracked expression, and calls the $render function
on change.

This fix reads the current select value, finds the matching option and removes the "selected"
attribute.

Fixes angular#14892
Fixes angular#14419
Related angular#12731
Narretz added a commit to Narretz/angular.js that referenced this issue Jul 23, 2016
When the select model changes, we add the "selected" attribute to the selected option, so that
screen readers know which option is selected.

Previously, we failed to remove the attribute from the selected / empty option when the model changed
to match a different option, or the unknown / empty option.

When using "track by", the behavior would also show when a user selected an option, and then the
model was changed, because track by watches the tracked expression, and calls the $render function
on change.

This fix reads the current select value, finds the matching option and removes the "selected"
attribute.

IE9 had to be special cased, as it will report option.hasAttribute('selected') === true even
if the option's property and attribute have been unset (even the dev tools show not selected attribute).

I've added a custom matcher that accounts for this behavior. In all other browsers, property and
attribute should always be in the same state. Since few people will use screen readers with IE9, I
hope this is a satisfactory solution to the problem.

Fixes angular#14892
Fixes angular#14419
Related angular#12731
Narretz added a commit to Narretz/angular.js that referenced this issue Jul 23, 2016
When the select model changes, we add the "selected" attribute to the selected option, so that
screen readers know which option is selected.

Previously, we failed to remove the attribute from the selected / empty option when the model changed
to match a different option, or the unknown / empty option.

When using "track by", the behavior would also show when a user selected an option, and then the
model was changed, because track by watches the tracked expression, and calls the $render function
on change.

This fix reads the current select value, finds the matching option and removes the "selected"
attribute.

IE9 had to be special cased, as it will report option.hasAttribute('selected') === true even
if the option's property and attribute have been unset (even the dev tools show not selected attribute).

I've added a custom matcher that accounts for this behavior. In all other browsers, property and
attribute should always be in the same state. Since few people will use screen readers with IE9, I
hope this is a satisfactory solution to the problem.

Fixes angular#14892
Fixes angular#14419
Related angular#12731
Narretz added a commit to Narretz/angular.js that referenced this issue Jul 23, 2016
When the select model changes, we add the "selected" attribute to the selected option, so that
screen readers know which option is selected.

Previously, we failed to remove the attribute from the selected / empty option when the model changed
to match a different option, or the unknown / empty option.

When using "track by", the behavior would also show when a user selected an option, and then the
model was changed, because track by watches the tracked expression, and calls the $render function
on change.

This fix reads the current select value, finds the matching option and removes the "selected"
attribute.

IE9 had to be special cased, as it will report option.hasAttribute('selected') === true even
if the option's property and attribute have been unset (even the dev tools show not selected attribute).

I've added a custom matcher that accounts for this behavior. In all other browsers, property and
attribute should always be in the same state. Since few people will use screen readers with IE9, I
hope this is a satisfactory solution to the problem.

Fixes angular#14892
Fixes angular#14419
Related angular#12731
Narretz added a commit that referenced this issue Jul 23, 2016
When the select model changes, we add the "selected" attribute to the selected option, so that
screen readers know which option is selected.

Previously, we failed to remove the attribute from the selected / empty option when the model changed
to match a different option, or the unknown / empty option.

When using "track by", the behavior would also show when a user selected an option, and then the
model was changed, because track by watches the tracked expression, and calls the $render function
on change.

This fix reads the current select value, finds the matching option and removes the "selected"
attribute.

IE9 had to be special cased, as it will report option.hasAttribute('selected') === true even
if the option's property and attribute have been unset (even the dev tools show not selected attribute).

I've added a custom matcher that accounts for this behavior. In all other browsers, property and
attribute should always be in the same state. Since few people will use screen readers with IE9, I
hope this is a satisfactory solution to the problem.

Fixes #14892
Fixes #14419
Related #12731
PR (#14894)
Narretz added a commit that referenced this issue Jul 23, 2016
When the select model changes, we add the "selected" attribute to the selected option, so that
screen readers know which option is selected.

Previously, we failed to remove the attribute from the selected / empty option when the model changed
to match a different option, or the unknown / empty option.

When using "track by", the behavior would also show when a user selected an option, and then the
model was changed, because track by watches the tracked expression, and calls the $render function
on change.

This fix reads the current select value, finds the matching option and removes the "selected"
attribute.

IE9 had to be special cased, as it will report option.hasAttribute('selected') === true even
if the option's property and attribute have been unset (even the dev tools show not selected attribute).

I've added a custom matcher that accounts for this behavior. In all other browsers, property and
attribute should always be in the same state. Since few people will use screen readers with IE9, I
hope this is a satisfactory solution to the problem.

Fixes #14892
Fixes #14419
Related #12731
PR (#14894)
Narretz added a commit to Narretz/angular.js that referenced this issue Feb 5, 2017
This helps screen readers identify the selected options,
see angular#14419
Narretz added a commit to Narretz/angular.js that referenced this issue Feb 8, 2017
This helps screen readers identify the selected options,
see angular#14419
Narretz added a commit that referenced this issue Feb 8, 2017
This helps screen readers identify the selected options,
see #14419
ellimist pushed a commit to ellimist/angular.js that referenced this issue Mar 15, 2017
This helps screen readers identify the selected options,
see angular#14419
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants