Skip to content

fix(forms): Correct editor validity state - #17637

Open
rkaraivanov wants to merge 2 commits into
masterfrom
rkaraivanov/fix-validity-state
Open

rkaraivanov wants to merge 2 commits into
masterfrom
rkaraivanov/fix-validity-state

Conversation

@rkaraivanov

Copy link
Copy Markdown
Member

Description

A pending async validator painted the invalid style. valid is false while validators run, and every editor mapped valid ? VALID : INVALID, so the error style showed before the rule had answered. The decision now lives one level up: NgControlAdapter exposes a status accessor mirroring FormControlStatus, and toInputState maps it to IgxInputState for all seven call sites. status is derived rather than read from NgControl.status, which the Signal Forms interop throws from on statuses it does not recognize (#17621).

aria-required stayed true after a conditional required rule turned off. Angular pushes the field's required into the directive input during the host view update pass, which runs after the adapter's root effect has already read the stale attribute. Writing the attribute from the required setter puts the final write after that read (#17620).

A field with no rules showed the valid state after switching [formField]. The interop NgControl is created once per directive and reused across switches, so the sticky "this field had rules" flag leaked from the previous field. The flag is now cleared while the control is pristine and untouched, which is the state the new field is observed in. Switching to an already touched or dirty field keeps the stale flag; there is no public way to detect that switch (#17619).

Closes #17619
Closes #17620
Closes #17621

Type of Change (check all that apply):

  • Bug fix

How Has This Been Tested?

  • Unit tests
  • Manual testing

Checklist:

  • All relevant tags have been applied to this PR
  • This PR includes unit tests covering all the new code (test guidelines)
  • This PR includes API docs for newly added methods/properties (api docs guidelines)
  • This PR includes feature/README.MD updates for the feature docs
  • This PR includes general feature table updates in the root README.MD
  • This PR includes CHANGELOG.MD updates for newly added functionality
  • This PR contains breaking changes
  • This PR includes ng update migrations for the breaking changes (migrations guidelines)
  • This PR includes behavioral changes and the feature specification has been updated with them
  • Accessibility (ARIA, keyboard navigation, focus management) has been verified

A pending async validator painted the invalid style. `valid` is false
while validators run, and every editor mapped `valid ? VALID : INVALID`,
so the error style showed before the rule had answered. The decision now
lives one level up: `NgControlAdapter` exposes a `status` accessor
mirroring `FormControlStatus`, and `toInputState` maps it to
`IgxInputState` for all seven call sites. `status` is derived rather
than read from `NgControl.status`, which the Signal Forms interop
throws from on statuses it does not recognize (#17621).

`aria-required` stayed true after a conditional `required` rule turned
off. Angular pushes the field's `required` into the directive input
during the host view update pass, which runs after the adapter's root
effect has already read the stale attribute. Writing the attribute from
the `required` setter puts the final write after that read (#17620).

A field with no rules showed the valid state after switching
`[formField]`. The interop `NgControl` is created once per directive and
reused across switches, so the sticky "this field had rules" flag leaked
from the previous field. The flag is now cleared while the control is
pristine and untouched, which is the state the new field is observed in.
Switching to an already touched or dirty field keeps the stale flag;
there is no public way to detect that switch (#17619).
Copilot AI lite review requested due to automatic review settings September 16, 2026 16:27
@rkaraivanov rkaraivanov added input ❌ status: awaiting-test PRs awaiting manual verification 📅 date-picker 🕐 time-picker combo select Select component 📅 date-range-picker simple-combo forms: validation Forms validation related, including ngModel.status aka VALID/INVALID/TOUCHED/PRISTINE etc. labels Sep 16, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Time-picker and date-range blur paths can still render pending validation as invalid, and two shipped fixes are missing from the changelog.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Fixes form editor validity handling for pending async validators, conditional required rules, and [formField] switches.

Changes:

  • Adds status-based input-state mapping across editors.
  • Synchronizes aria-required and Signal Forms tracking.
  • Adds regression tests and changelog coverage.
File summaries
File Summary
projects/igniteui-angular/time-picker/src/time-picker/time-picker.component.ts Applies status-aware rendering; blur handling still maps pending validation to invalid.
projects/igniteui-angular/time-picker/src/time-picker/time-picker.component.spec.ts Updates time-picker validity tests; pending-blur coverage is still needed.
projects/igniteui-angular/select/src/select/select.component.ts Uses status-based validity mapping.
projects/igniteui-angular/input-group/src/input-group/directives-input/input.directive.ts Maps control status and synchronizes aria-required.
projects/igniteui-angular/input-group/src/input-group/directives-input/input.directive.spec.ts Adds validation, ARIA, and field-switch regression coverage.
projects/igniteui-angular/date-picker/src/date-range-picker/date-range-picker.component.ts Applies status mapping; blur handling can still mark pending validation invalid.
projects/igniteui-angular/date-picker/src/date-picker/date-picker.component.ts Uses status-aware validity rendering.
projects/igniteui-angular/date-picker/src/date-picker/date-picker.component.spec.ts Updates date-picker test coverage and control mocks.
projects/igniteui-angular/core/src/core/ng-control-adapter.ts Adds derived control status and Signal Forms tracking.
projects/igniteui-angular/combo/src/combo/combo.common.ts Uses status-based validation mapping.
CHANGELOG.md Documents the pending-validator fix, but not the aria-required and field-switch fixes.
Review details
  • Files reviewed: 11/11 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread CHANGELOG.md
The time and date range pickers repaint validity on blur through a path
of their own, which still mapped `!valid` to `INVALID`. `valid` is false
while an async validator runs, so blurring painted the error style
before the rule had answered - the bug the status-change path was
already fixed for.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🕐 time-picker combo 📅 date-picker 📅 date-range-picker forms: validation Forms validation related, including ngModel.status aka VALID/INVALID/TOUCHED/PRISTINE etc. input select Select component simple-combo ❌ status: awaiting-test PRs awaiting manual verification

Projects

None yet

3 participants