* Test that `minDate`/`maxDate` binds to `min`/`max` on date and time inputs
* Test that `min`/`max` attribute can be set directly on date and time inputs
* Relax type checker to allow `min`/`max` bindings on date and time inputs
PR Close#68001
Introduce a highly decoupled FVC and CVA custom control reset mechanism, and implement the framework-wide automatic `transformedValue` and native controls clearing bridge for both new Signal Forms and legacy forms (Template-driven and Reactive).
1. Custom Control Reset Propagation (Bug #2):
- Establish agnostic custom control resetting via `FormFieldBindingOptions.reset` in `FormField`.
- Ensure that `FieldNode.reset()` unconditionally triggers `writeValue` updates on CVA custom controls.
- Protect against duplicate writes during subsequent change detection updates in `control_cva.ts` by verifying and tracking previous written values in the local bindings cache.
2. Unified Framework-wide FormControl Integration:
- Introduce a monorepo-wide private InjectionToken `ɵFORM_CONTROL_INTEGRATION` and `ɵFormControlIntegration` interface to act as the single, decoupled bridge for hooking up FVC parse errors and receiving control resets across both Signal and legacy forms architectures.
- Simplify Signal Forms: make `FormField` implements `ɵFormControlIntegration` directly, removing the intermediate context object and reducing DI boilerplate down to a clean `useExisting: FormField` provider. Triggers the `onReset` callback directly inside `FormField.reset()`.
- Upgrade Legacy Forms: `NG_CONTROL_INTEGRATION_PROVIDER` provides the renamed token. `NgControl` handles the event subscription internally (`set onReset(callback)`) to recursively listen to `control.events` (`FormResetEvent`) lazily only when assigned, resolving all `FormControl` swapping timing and lifecycle cleanup races automatically.
3. Automatic `transformedValue` and Native Controls Utility Clearing:
- Make `Parser.reset()` method required in the interface for a cleaner and non-defensive execution.
- Wire `transformedValue` into the new integration token `ɵFORM_CONTROL_INTEGRATION` to clear validation parsing states on resets.
- Lazily resets the UI-facing `rawValue` linked signal utilizing the original native `linkedSignal.set` callback (`originalSet`), correctly bypassing the UI-to-model parser loopback and preventing redundant model writes during `reset()`.
- Wire up Native Controls (`control_native.ts\Device`): Hook `parent.onReset` inside native element creation to automatically trigger the native `parser.reset()` and force DOM writes (`setNativeControlValue`) back down to the DOM input value during resets, ensuring native elements with pending parsing validation errors are successfully cleared and synced on form resets.
TAG=agy
CONV=8b4cee1e-2117-42a4-b242-c8ec7bf01752
Adds a documentation page for the NG01002 runtime error thrown by
FormGroup and FormArray when setValue is called with a value that is
missing an entry for one or more registered controls.
The error code is also changed from positive (1002) to negative (-1002)
so that Angular appends a link to the error reference page in dev mode,
consistent with how other documented errors (e.g. NG01101, NG01203) are
handled.
Prioritize custom ControlValueAccessor instances over default or built-in accessors when applying the [formField] directive. This is achieved by directly consuming selectValueAccessor from @angular/forms, ensuring absolute alignment with the precedence rules used across standard Angular form directives.
Document that FormArray.value includes only enabled child controls when the array is enabled, but includes all child values when the FormArray itself is disabled.
Fixes#67759
The `pending` getter in `AbstractControl` used loose equality (`==`)
while all other status getters (`valid`, `invalid`, `disabled`) use
strict equality (`===`). Both sides are strings so behavior is
identical, but this inconsistency would fail strict linting rules.
Implement support for `FormUiComponent`s in both Reactive and Template-driven
forms. This allows components that use the new signal-based form control
architecture to be used seamlessly within existing Angular form paradigms.
Key changes:
- Integrated `ɵngControlCreate` and `ɵngControlUpdate` lifecycle hooks into
`NgModel`, `FormControlDirective`, and `FormControlName`.
- Implemented branching logic to choose between the traditional `ControlValueAccessor` (CVA) path and the new FVC path based on the host element's capabilities.
- Added comprehensive unit tests for FVC integration in both Reactive (`reactive_fvc.spec.ts`) and Template-driven (`template_fvc.spec.ts`) forms, covering:
- Value synchronization (model -> view and view -> model).
- Status synchronization (touched, dirty, valid, invalid, pending, required).
- Error propagation and `parseErrors` support.
- Fallback behavior to native DOM properties (disabled, required) when FVC inputs are missing.
- Graceful fallback to CVA when no FVC pattern is detected.
- Refined `NgModel` to correctly handle `required` validation via its existing `RequiredValidator` directive while supporting FVC for other properties.
Update `NgControl` to support binding to custom controls via the new `ngControlCreate` and
`ngControlUpdate` lifecycle hooks. This will allow Reactive and Template-driven forms to integrate
with components that use the new `FormValueControl` (FVC) binding convention.
Key changes:
- Implement synchronization of control state between `FormControl` and custom controls.
- Add support for `parseErrors` signals from custom controls, integrating them into the Reactive
Forms validation loop via a dynamic validator.
- Convert Reactive Forms errors into `ReactiveValidationError` objects for consumption by custom
controls.
- Update `NgModel`, `FormControlDirective`, and `FormControlName` to provide necessary dependencies
(`Injector`, `Renderer2`) to `NgControl`.
- Rename `setUpControl` to `setUpControlValueAccessor` to clarify its role in the traditional
CVA path.
Introduces an internal signal that tracks whether `Validators.required` is in the set of validators
for an `AbstractControl`. This signal is updated whenever the validators are changed.
Relocate some utility code into `@angular/forms` instead of the signal-forms specific entrypoint,
to facilitate their reuse in existing template & reactive forms.
Delay the selection of a CVA until after the `ɵɵcontrol` instruction has a chance to execute.
This is necessary to delay the error that would be thrown for a missing CVA until after we have a
chance to recognize we're actually on an FVC/FCC.
If `FormsModule` or `ReactiveFormsModule` is present in the scope of a
template, plain `<input>` and other form elements will get default CVA
directives added. This commit adds an `ngNoCva` attribute as a negative
selector for those directives, so `<input ngNoCva>` elements will not have
them matched.
The removeValidators and hasValidator methods both had identical "Reference to a ValidatorFn" section titles, causing duplicate entries in the API documentation table of contents.
This change replaces all remaining occurrences of `typeof ngDevMode !== undefined`
with the correct `typeof ngDevMode !== 'undefined'` form. This aligns the codebase
with JavaScript typeof semantics and maintains consistency with other Angular code.
Annotate the `new Version(...)` call with `/* @__PURE__ */` to signal to optimizers that the constructor is side-effect free.
Without this hint, bundlers such as Terser or ESBuild may conservatively retain the `VERSION` instantiation even when unused. With the annotation, the constant can be tree-shaken away in production builds if not referenced, reducing bundle size.
Renames the control directive and the input that users set to bind a
field to a UI control.
Previously users would do:
```
<input [control]="someField">
```
Now users will do:
```
<input [filed]="someField">
```
PR Close#64300
Since those are top level APIs, `ngDevMode` might not be available at runtime if they're invoked before the variable is set.
fixes#62796
PR Close#63875
The `FormArrayDirective` will allow to have a `FormArray` as a top-level form object.
* `NgControlStatusGroup` directive will be applied to the `FormArrayDirective`
* `NgForm` will still create a `FormGroup`
Fixes angular#30264
BREAKING CHANGE: This new directive will conflict with existing FormArray directives or formArray inputs on the same element.
PR Close#55880
Enables users to add an array of FormControls to a FormArray using its existing .push() method,
instead of pushing each new FormControl one by one triggering events along the way.
PR Close#57102
Simplifies destruction logic by relying directly on the injector's destroyed state.
Eliminates unnecessary retrieval of a separate destroy reference
PR Close#62738
We defer the update until after rendering
is complete for two reasons: first, to avoid repeatedly calling
`writeValue` on every option element until we find the selected one
(could be the very last element). Second, to ensure that we perform the
write after the DOM elements have been created (this doesn't happen
until the end of change detection when animations are enabled).
This is needed to efficiently set the select value when adding/removing options. The
previous approach resulted in exponentially more `_compareValue` calls than the number
of option elements (issue angular#41330).
Finally, this PR fixes an issue with delayed element removal when using the animations
module (in all browsers). Previously when a selected option was removed (so no option
matched the ngModel anymore), Angular changed the select element value before actually
removing the option from the DOM. Then when the option was finally removed from the DOM,
the browser would change the select value to that of the first option, even though it
didn't match the ngModel (issue angular#18430). Note that this is still
somewhat of an application problem when using `ngModel`. The model value
still needs to be updated to a valid value when the selected value is
deleted or it will be out of sync with the DOM.
Fixes#41330, fixes#18430.
PR Close#61949
This change also decorelate the `reset` type argument from `TValue` by adding a 3rd generic parameter to `AbstractControl`.
This improves the typings overall.
PR Close#55860
This aligns with how angular/components marks their hidden APIs.
`@nodoc` has been broken since the switch to adev, this change should
properly hide the APIs again.
PR Close#61194
Currently, only forms created with `FormGroupDirective` emit events on
form submission and resetting. This commit extends this behavior to
Template-driven forms also.
Related to #58894
PR Close#60887
Adds the `markAllAsDirty` method to the `AbstractControl` class. This method will mark the control and all its
descendants as dirty.
I pretty much just duplicated the behaviour and tests of `markAllAsTouched`.
Fixes#55990
PR Close#58663