-
Notifications
You must be signed in to change notification settings - Fork 24.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(forms): Make radio buttons respect [attr.disabled]
#48864
Conversation
Thanks @AndrewKushnir and sorry for the delay. Back to you on this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (just a couple minor comments) 👍
`setDisabledState` is supposed to be called whenever the disabled state of a control changes, including upon control creation. However, a longstanding bug caused the method to not fire when an *enabled* control was attached. This bug was fixed in v15. This had a side effect: previously, it was possible to instantiate a reactive form control with `[attr.disabled]=true`, even though the the corresponding control was enabled in the model. (Note that the similar-looking property binding version `[disabled]=true` was always rejected, though.) This resulted in a mismatch between the model and the DOM. Now, because `setDisabledState` is always called, the value in the DOM will be immediately overwritten with the "correct" enabled value. Users should instead disable the control directly in their model. (There are many ways to do this, such as using the `{value: 'foo', disabled: true}` constructor format, or immediately calling `FooControl.disable()` in `ngOnInit`.) If this incompatibility is too breaking, you may also opt out using `FormsModule.withConfig` or `ReactiveFormsModule.withConfig` at the time you import it, via the `callSetDisabledState` option. However, there is an exceptional case: radio buttons. Because Reactive Forms models the entire group of radio buttons as a single `FormControl`, there is no way to control the disabled state for individual radios, so they can no longer be configured as disabled. In this PR, we have special cased radio buttons to ignore their first call to `setDisabledState` when in `callSetDisabledState: 'always'` mode. This preserves the old behavior.
merge-assistance: the Public API change is to prevent a spurious documentation symbol for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reviewed-for: public-api
This PR was merged into the repository by commit 5968561. |
`setDisabledState` is supposed to be called whenever the disabled state of a control changes, including upon control creation. However, a longstanding bug caused the method to not fire when an *enabled* control was attached. This bug was fixed in v15. This had a side effect: previously, it was possible to instantiate a reactive form control with `[attr.disabled]=true`, even though the the corresponding control was enabled in the model. (Note that the similar-looking property binding version `[disabled]=true` was always rejected, though.) This resulted in a mismatch between the model and the DOM. Now, because `setDisabledState` is always called, the value in the DOM will be immediately overwritten with the "correct" enabled value. Users should instead disable the control directly in their model. (There are many ways to do this, such as using the `{value: 'foo', disabled: true}` constructor format, or immediately calling `FooControl.disable()` in `ngOnInit`.) If this incompatibility is too breaking, you may also opt out using `FormsModule.withConfig` or `ReactiveFormsModule.withConfig` at the time you import it, via the `callSetDisabledState` option. However, there is an exceptional case: radio buttons. Because Reactive Forms models the entire group of radio buttons as a single `FormControl`, there is no way to control the disabled state for individual radios, so they can no longer be configured as disabled. In this PR, we have special cased radio buttons to ignore their first call to `setDisabledState` when in `callSetDisabledState: 'always'` mode. This preserves the old behavior. PR Close #48864
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@angular/animations](https://github.com/angular/angular) | dependencies | patch | [`15.1.4` -> `15.1.5`](https://renovatebot.com/diffs/npm/@angular%2fanimations/15.1.4/15.1.5) | | [@angular/common](https://github.com/angular/angular) | dependencies | patch | [`15.1.4` -> `15.1.5`](https://renovatebot.com/diffs/npm/@angular%2fcommon/15.1.4/15.1.5) | | [@angular/compiler](https://github.com/angular/angular) | dependencies | patch | [`15.1.4` -> `15.1.5`](https://renovatebot.com/diffs/npm/@angular%2fcompiler/15.1.4/15.1.5) | | [@angular/compiler-cli](https://github.com/angular/angular/tree/main/packages/compiler-cli) ([source](https://github.com/angular/angular)) | devDependencies | patch | [`15.1.4` -> `15.1.5`](https://renovatebot.com/diffs/npm/@angular%2fcompiler-cli/15.1.4/15.1.5) | | [@angular/core](https://github.com/angular/angular) | dependencies | patch | [`15.1.4` -> `15.1.5`](https://renovatebot.com/diffs/npm/@angular%2fcore/15.1.4/15.1.5) | | [@angular/forms](https://github.com/angular/angular) | dependencies | patch | [`15.1.4` -> `15.1.5`](https://renovatebot.com/diffs/npm/@angular%2fforms/15.1.4/15.1.5) | | [@angular/platform-browser](https://github.com/angular/angular) | dependencies | patch | [`15.1.4` -> `15.1.5`](https://renovatebot.com/diffs/npm/@angular%2fplatform-browser/15.1.4/15.1.5) | | [@angular/platform-browser-dynamic](https://github.com/angular/angular) | dependencies | patch | [`15.1.4` -> `15.1.5`](https://renovatebot.com/diffs/npm/@angular%2fplatform-browser-dynamic/15.1.4/15.1.5) | --- ### Release Notes <details> <summary>angular/angular</summary> ### [`v15.1.5`](https://github.com/angular/angular/blob/HEAD/CHANGELOG.md#​1515-2023-02-15) [Compare Source](angular/angular@15.1.4...15.1.5) ##### forms | Commit | Type | Description | | -- | -- | -- | | [5f2a3edcf2](angular/angular@5f2a3ed) | fix | Make radio buttons respect `[attr.disabled]` ([#​48864](angular/angular#48864)) | #### Special Thanks AleksanderBodurri, Alvaro Junqueira, Dylan Hunn, Joey Perrott, Matthieu Riegler, PaloMiklo and Paul Gschwendtner <!-- CHANGELOG SPLIT MARKER --> </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC4xMzguMiIsInVwZGF0ZWRJblZlciI6IjM0LjEzOC4yIn0=--> Co-authored-by: cabr2-bot <cabr2.help@gmail.com> Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1786 Reviewed-by: 6543 <6543@obermui.de> Co-authored-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org> Co-committed-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org>
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
setDisabledState
is supposed to be called whenever the disabled state of a control changes, including upon control creation. However, a longstanding bug caused the method to not fire when an enabled control was attached. This bug was fixed in v15.This had a side effect: previously, it was possible to instantiate a reactive form control with
[attr.disabled]=true
, even though the the corresponding control was enabled in the model. (Note that the similar-looking property binding version[disabled]=true
was always rejected, though.) This resulted in a mismatch between the model and the DOM. Now, becausesetDisabledState
is always called, the value in the DOM will be immediately overwritten with the "correct" enabled value.Users should instead disable the control directly in their model. (There are many ways to do this, such as using the
{value: 'foo', disabled: true}
constructor format, or immediately callingFooControl.disable()
inngOnInit
.)If this incompatibility is too breaking, you may also opt out using
FormsModule.withConfig
orReactiveFormsModule.withConfig
at the time you import it, via thecallSetDisabledState
option.However, there is an exceptional case: radio buttons. Because Reactive Forms models the entire group of radio buttons as a single
FormControl
, there is no way to control the disabled state for individual radios, so they can no longer be configured as disabled.In this PR, we have special cased radio buttons to ignore their first call to
setDisabledState
when incallSetDisabledState: 'always'
mode. This preserves the old behavior.Related to #48350.