-
Notifications
You must be signed in to change notification settings - Fork 27.4k
fix(select) ... breaks some selects with required attributes on firefox. #7715
Comments
In Firefox, hovering over an option in an open select menu updates the selected property of option elements. This means that when a render is triggered by the digest cycle, and the list of options is being rendered, the selected properties are reset to the values from the model and the option hovered over changes. This fix changes the code to only use DOM elements' selected properties in a comparison when a change event has been fired. Otherwise, the internal new and existing option arrays are used. Closes #2448 Closes #5994 Closes #6769
It looks like the optional select is also broken on Chrome, because the select has A selected, whereas 'Choose a choice' should be selected |
we filed an issue about this with Chromium, actually, because it works as expected in firefox, but differently in chrome --- mostly because that section of html is a bit underspecified. I haven't kept up with the issues though, don't think I added myself to the CC list |
Oh, so it's actually correct in Firefox: because the first field is disabled, the second field is automatically selected? But @luismreis says that's broken. So maybe the expectation is that a disabled field can still be preselected (but not user selected), because you don't want to make a selection for the user ... regardless of required state. |
the scenario which is broken is sort of hard to explain, it's easiest to just show the fiddle --- it's in one of the issues about this, can't recall OTOH though |
@Narretz The scenario is this: you need a select control for something that is required, but you don't want to pre-choose one of the normal options. A way to do this is by having a default value that is disabled, so, the user can choose another one, but not the initial void/empty one. I prefer the "show disabled option" behaviour, but I understand that it feels a bit broken - maybe I should be using another widget for this. BTW, I started to have doubts on this being pure browser or angular bejaviour and now there's a new version of the fiddle at (http://jsbin.com/wobod/4). The problem is exactly the same regardless if angular is involved or not. |
After some investigation with @ealtenho, I think the only way to satisfy these constraints for a consistent experience in all browsers is to create a new directive (e.g. ngOptionDisabled). Constraints:
The approach would involve setting the Here's the script we were using to test in FF and Chrome: var select = document.createElement('select');
select.setAttribute('required', true);
var option1 = document.createElement('option');
option1.setAttribute('selected', true);
//if (Chrome) option1.value = ''
select.appendChild(option1);
option1.text = 'One';
var option2 = document.createElement('option');
option2.setAttribute('value', '2');
option2.text = 'Two';
select.appendChild(option2);
document.body.appendChild(select);
//select.validity.valid == false
//Selected option in browser should be 'One'
option1.setAttribute('disabled', true);
//select.validity.valid == false
//Selected option in browser should be 'One' @caitp interested in your thoughts on this approach |
@jeffbcross @caitp @btford Particularly, we wonder if the alteration in line 540 is a source of error. Pursuing this strategy, I've been trying to develop a PR: |
A previous patch attempted to avoid unnecessary selections on hover in Firefox by skipping selection changes when no change event was fired. However, the alteration in "lastElement[0].selected" to "existingOption.selected" effectively checked incorrect values. This caused other select issues, particularly with the disabled attribute. angular#7715
Basically what the issue came down to was, the existing algorithm was causing a hovered property to be deselected/flicker when frequent digests were happening frequently (if I recall correctly). I tried a few times to come up with an algorithm which would make each browser happy, but it turned out to be not very easy :( It might actually be easier to just fix the bug in Gecko, and revert the patch here which introduced the regressions. As it stands, that part of the code is kind of maze-like and very hard to reason about, so I think it's okay to not come up with a workable solution on the first try. I'm sure there's something that could be done about it, but it might be easier to just fix it in C++ instead of JS. |
Thanks @caitp ! I appreciate the advice. |
Currently, our plan to deal with this issue is to |
@btford The following tests shows this select box error. it('should allow the selection of a disabled option as the first element in a required select',
function() {
var html = '<select';
html += ' required>';
html += '<option value="" disabled>Choose One</option>';
html += '<option value="1">Option One</option>';
html += '</select>';
compile(html);
document.body.innerHTML = html;
var options = element.find('option');
var optionToSelect = options.eq(0);
expect(optionToSelect.text()).toBe('Choose One');
expect(optionToSelect.prop('selected')).toBe(true);
dealoc(element);
}); It fails in Firefox (but passes in Chrome), documenting this issue. This appears to be a separate Firefox behavior. Hence a pertinent question now is whether Angular should alter this behavior using something like |
I would expect for b8ae73e to fix this issue. Can you please check if this issue is present at 1.3.beta15? If it is not, then I can back port this issue to the 1.2.x branch |
A bug in Firefox prevents selecting the first option in a select if that option is disabled in a required select. The failure of this test documents the operation of this bug. Related to #7715
…render This reverts commit dc149de. This commit fixes a bug caused by Firefox updating select.value on hover. However, it causes other bugs with select including the issue described in angular#7715. This issue causes selects with a blank disabled option to skip to the second option. A bug has been filed to deal with the Firefox issue addressed by this commit, and alternate Angular fixes are being investigated. The test introduced in this commit does test a valid case and should be added back if an Angular solution to the issue is being pursued.
An earlier commit caused an error where the first option of a select would be skipped over if it had a blank value. This fix adds a test case to identify this case and shows that reverting the earlier commit causes the behavior to change. In the case of a select with a blank disabled first option, that option should still be selected. Relates to angular#7715
An earlier commit dc149de caused an error where the first option of a select would be skipped over if it had a blank disabled value. These tests demonstrate that with that commit in place, blank disabled options are skipped in a select. When the commit is reverted, the correct behavior is seen that the blank disabled option is still selected in both selects marked with required and those that have optional choices. Relates to angular#7715
…render This reverts commit dc149de. This commit fixes a bug caused by Firefox updating `select.value` on hover. However, it causes other bugs with select including the issue described in angular#7715. This issue causes selects with a blank disabled option to skip to the second option. We filed a bug with Firefox for the problematic behavior this commit addresses https://bugzilla.mozilla.org/show_bug.cgi?id=1039047, and alternate Angular fixes are being investigated. The test introduced in this commit does test a valid case and is therefore not reverted.
An earlier commit dc149de caused an error where the first option of a select would be skipped over if it had a blank disabled value. These tests demonstrate that with that commit in place, blank disabled options are skipped in a select. When the commit is reverted, the correct behavior is seen that the blank disabled option is still selected in both selects marked with required and those that have optional choices. Relates to angular#7715
…render This reverts commit dc149de. That commit fixes a bug caused by Firefox updating `select.value` on hover. However, it causes other bugs with select including the issue described in angular#7715. This issue details how selects with a blank disabled option skip to the second option. We filed a bug with Firefox for the problematic behavior the reverted commit addresses https://bugzilla.mozilla.org/show_bug.cgi?id=1039047, and alternate Angular fixes are being investigated. The test introduced in this commit does test a valid case and is therefore not reverted. Closes angular#7715 angular#7855
An earlier commit dc149de caused an error where the first option of a select would be skipped over if it had a blank disabled value. These tests demonstrate that with that commit in place, blank disabled options are skipped in a select. When the commit is reverted, the correct behavior is seen that the blank disabled option is still selected in both selects marked with required and those that have optional choices. Relates to angular#7715
…render This reverts commit dc149de. That commit fixes a bug caused by Firefox updating `select.value` on hover. However, it causes other bugs with select including the issue described in angular#7715. This issue details how selects with a blank disabled option skip to the second option. We filed a bug with Firefox for the problematic behavior the reverted commit addresses https://bugzilla.mozilla.org/show_bug.cgi?id=1039047, and alternate Angular fixes are being investigated. The test introduced in this commit does test a valid case and is therefore not reverted. Closes angular#7715 angular#7855
An earlier commit dc149de caused an error where the first option of a select would be skipped over if it had a blank disabled value. These tests demonstrate that with that commit in place, blank disabled options are skipped in a select. When the commit is reverted, the correct behavior is seen that the blank disabled option is still selected in both selects marked with required and those that have optional choices. Relates to angular#7715
…render This reverts commit dc149de. That commit fixes a bug caused by Firefox updating `select.value` on hover. However, it causes other bugs with select including the issue described in angular#7715. This issue details how selects with a blank disabled option skip to the second option. We filed a bug with Firefox for the problematic behavior the reverted commit addresses https://bugzilla.mozilla.org/show_bug.cgi?id=1039047, and alternate Angular fixes are being investigated. Closes angular#7715 angular#7855
…ith no change event Commit dc149de was reverted to fix regressions angular#7715 and angular#7855. This commit introduced this test case and a corresponding fix for preventing the update of the selected property of an option element on a digest with no change event. Although the previous fix introduced regressions, the test covers a valid issue and should be included.
An earlier commit dc149de caused an error where the first option of a select would be skipped over if it had a blank disabled value. These tests demonstrate that with that commit in place, blank disabled options are skipped in a select. When the commit is reverted, the correct behavior is seen that the blank disabled option is still selected in both selects marked with required and those that have optional choices. Relates to angular#7715
…ith no change event Commit dc149de was reverted to fix regressions #7715 and #7855. This commit introduced this test case and a corresponding fix for preventing the update of the selected property of an option element on a digest with no change event. Although the previous fix introduced regressions, the test covers a valid issue and should be included.
An earlier commit dc149de caused an error where the first option of a select would be skipped over if it had a blank disabled value. These tests demonstrate that with that commit in place, blank disabled options are skipped in a select. When the commit is reverted, the correct behavior is seen that the blank disabled option is still selected in both selects marked with required and those that have optional choices. Relates to #7715
…digest with no change event The `render()` method was being invoked on every turn of the digest cycle, which was inadvertently updating the DOM even when a `change` event had not been triggered. This change only calls the `render()` method when `ctrl.$render()` is called, as part of the NgModelController` lifecycle and when the `modelValue` has significantly changed. Closes #8221 Closes #7715
…render This reverts commit dc149de. That commit fixes a bug caused by Firefox updating `select.value` on hover. However, it causes other bugs with select including the issue described in #7715. This issue details how selects with a blank disabled option skip to the second option. We filed a bug with Firefox for the problematic behavior the reverted commit addresses https://bugzilla.mozilla.org/show_bug.cgi?id=1039047, and alternate Angular fixes are being investigated. Closes #7715 #7855
…ith no change event Commit dc149de was reverted to fix regressions #7715 and #7855. This commit introduced this test case and a corresponding fix for preventing the update of the selected property of an option element on a digest with no change event. Although the previous fix introduced regressions, the test covers a valid issue and should be included.
An earlier commit dc149de caused an error where the first option of a select would be skipped over if it had a blank disabled value. These tests demonstrate that with that commit in place, blank disabled options are skipped in a select. When the commit is reverted, the correct behavior is seen that the blank disabled option is still selected in both selects marked with required and those that have optional choices. Relates to #7715
…digest with no change event The `render()` method was being invoked on every turn of the digest cycle, which was inadvertently updating the DOM even when a `change` event had not been triggered. This change only calls the `render()` method when `ctrl.$render()` is called, as part of the NgModelController` lifecycle and when the `modelValue` has significantly changed. Closes #8221 Closes #7715
The commit dc149de breaks selects with a required attribute and an disabled default empty option, but only on firefox.
Please check this jsbin on both chrome and firefox.
The text was updated successfully, but these errors were encountered: