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

fix(ngOptions): do not unset the selected property unless necessary #15478

Closed

Conversation

gkalpak
Copy link
Member

@gkalpak gkalpak commented Dec 8, 2016

What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Bug fix.

What is the current behavior? (You can also link to an open issue here)
When updating the value of a select[multiple] element, all options are first set to selected = false and then the selected ones are set to true. By setting an already selected option to selected = false and then true again - essentially unselecting and reselecting it - causes some browsers (including Firefox, IE and under some circumstances Chrome) to unexpectedly scroll to the last selected option.

What is the new behavior (if this is a feature change)?
The selected property of the <option> elements is only set if its current value is different than the new one and even then it is set to its final value at once (i.e. without first setting it to false), thus avoiding the undesirable behavior.

Does this PR introduce a breaking change?
No.

Please check if the PR fulfills these requirements

Other information:
Fixes #15477

Previously, when updating the value of a `select[multiple]` element, all options
were first set to `selected = false` and then the selected ones were set to
`true`. By setting an already selected option to `selected = false` and then
`true` again - essentially unselecting and reselecting it - caused some browsers
(including Firefox, IE and under some circumstances Chrome) to unexpectedly
scroll to the last selected option.

This commit fixes it by ensuring that the `selected` property is only set if its
current value is different than the new one and even then it is set to its final
value at once (i.e. without first setting it to `false`), thus avoiding the
undesirable behavior.

Fixes angular#15477
@@ -506,16 +506,16 @@ var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile,
} else {

selectCtrl.writeValue = function writeNgOptionsMultiple(value) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change the parameter name to values? Since it's an array if it's defined. This also makes it easier to understand with map below.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@Narretz
Copy link
Contributor

Narretz commented Dec 15, 2016

LGTM

@Narretz
Copy link
Contributor

Narretz commented Dec 15, 2016

I restarted the unit test job, there were some mobile safari tests for animateCss, they looked unrelated

@gkalpak gkalpak closed this in 4e143fc Dec 19, 2016
gkalpak added a commit that referenced this pull request Dec 19, 2016
Previously, when updating the value of a `select[multiple]` element, all options
were first set to `selected = false` and then the selected ones were set to
`true`. By setting an already selected option to `selected = false` and then
`true` again - essentially unselecting and reselecting it - caused some browsers
(including Firefox, IE and under some circumstances Chrome) to unexpectedly
scroll to the last selected option.

This commit fixes it by ensuring that the `selected` property is only set if its
current value is different than the new one and even then it is set to its final
value at once (i.e. without first setting it to `false`), thus avoiding the
undesirable behavior.

Fixes #15477

Closes #15478
@gkalpak gkalpak deleted the fix-ngOptions-avoid-resetting-selected branch December 19, 2016 20:58
ellimist pushed a commit to ellimist/angular.js that referenced this pull request Mar 15, 2017
Previously, when updating the value of a `select[multiple]` element, all options
were first set to `selected = false` and then the selected ones were set to
`true`. By setting an already selected option to `selected = false` and then
`true` again - essentially unselecting and reselecting it - caused some browsers
(including Firefox, IE and under some circumstances Chrome) to unexpectedly
scroll to the last selected option.

This commit fixes it by ensuring that the `selected` property is only set if its
current value is different than the new one and even then it is set to its final
value at once (i.e. without first setting it to `false`), thus avoiding the
undesirable behavior.

Fixes angular#15477

Closes angular#15478
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

multiple select always jumps back to lowest marked element
3 participants