91 Commits

Author SHA1 Message Date
Jaime Burgos 8afd85c6d7 test(forms): migrate integration tests to zoneless scheduling
Use whenStable instead of manual change detection so integration tests exercise scheduled rendering. Await asynchronous callbacks and remove redundant timer waits to keep assertions within the test lifecycle.
2026-09-09 16:24:37 +02:00
Shuaib Hasan Akib 1bc7e3c2c3 refactor(core): use native Promise.withResolvers() in remaining tests
Replaces the remaining hand-rolled deferred promise implementations
with the native `Promise.withResolvers()` API and removes the now
unused helper and import.

Follow-up to #69739.
2026-09-09 16:17:04 +02:00
SkyZeroZx 6deb6afcd1 refactor(forms): modernize reactive forms tests to rely on whenStable
Rely on zoneless scheduling throughout reactive forms tests instead of triggering change detection manually.
2026-07-30 09:06:29 -07:00
Matthieu Riegler eae8f7e30b feat(core): Set default Component changeDetection strategy to OnPush
The default change detection strategy is now OnPush.

BREAKING CHANGE: Component with undefined `changeDetection` property are now `OnPush` by default. Specify `changeDetection: ChangeDetectionStrategy.Eager` to keep the previous behavior.
2026-03-24 16:25:02 -07:00
Alex Rickabaugh c4ce3f345f feat(forms): template & reactive support for FVC
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.
2026-03-17 13:18:26 -06:00
SkyZeroZx 19d0ceede3 test(forms): move timeout and autoTick helpers to shared testing utilities
Centralizes common test helpers under testing utilities and updates usages
2026-02-10 07:45:00 -08:00
Angular Robot 11767cabe4 build: update Jasmine to 6.0.0
Jasmine enables `forbidDuplicateNames: true` by default. So we also need to desambiguate duplicate spec names.
2026-02-09 12:15:57 -08:00
SkyZeroZx 7dfbacbcf8 test(forms): remove zone-based testing utilities
Removes usages of zone-based helpers such as `fakeAsync` , `tick`
`waitForAsync` as part of the migration to zoneless tests.

Completes the transition to zoneless.
2026-02-04 15:38:09 -08:00
SkyZeroZx 4aae3379c2 test(forms): migrate reactive forms and value accessors to zoneless
Migrates reactive forms, template-driven forms, and value accessors to zoneless tests.
2026-02-02 10:16:58 -08:00
SkyZeroZx f4469ad583 refactor(core): update error message links to versioned docs (#66374)
Error message links now point to the archived documentation site (v*.angular.dev)
so that referenced content matches the framework version in use.

See angular#44650

PR Close #66374
2026-01-09 22:33:51 +00:00
Matthieu Riegler 6270bba056 ci: reformat files
This is after we've slightly changed a rule in #66056
2025-12-16 14:44:19 -08:00
Matthieu Riegler c0d88c37c9 fix(forms): Emit FormResetEvent when resetting control (#64024)
Prior to this change, the event was emitted by the Form Directive. With the change, it is now emitted at the control level.

fixes #58894

PR Close #64024
2025-09-24 16:48:32 +00:00
Andrew Scott c3576506b3 refactor(core): Update tests for zoneless by default (#63668)
This updates tests and examples only to prepare for zoneless by default.

These changes were identified and made as part of #63382. Anything that
failed gets `provideZoneChangeDetection` unless the fixes were easily
and quickly determined.

It also adds the zoneless provider to the `initTestEnvironment` calls
for tests in this repo to prevent regressions before #63382 is merged.

PR Close #63668
2025-09-09 14:41:56 -07:00
Matthieu Riegler 0dd95c503f feat(forms): Add FormArrayDirective (#55880)
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
2025-08-21 09:38:37 -07:00
Joey Perrott e11f48f65e build: migrate forms to rules_js (#61535)
Migrate forms to use ng_project and ts_project

PR Close #61535
2025-05-21 09:16:05 +00:00
Paul Gschwendtner 3a106a35bc build: move private testing helpers outside platform-browser/testing (#61472)
These helpers are often imported by various tests throughout the
repository, but the helpers aren't exported/exposed from the public
entry-point; even though they confusingly reside in there.

This commit fixes this, and moves the helpers into
`packages/private/testing`. This is a preparation for the `ts_project`
migration where we don't want to leverage deep imports between packages.

PR Close #61472
2025-05-20 10:00:43 +00:00
Domenico Gemoli a07ee60989 feat(forms): add markAllAsDirty to AbstractControl (#58663)
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
2025-04-02 18:25:32 +00:00
Matthieu Riegler bdfbd54932 feat(forms): Allow to reset a form without emitting events (#60354)
This change  add an option paramter to `resetForm` that is passed to the FormGroup.

fixes #60274

PR Close #60354
2025-04-02 11:36:24 +00:00
Andrew Kushnir be7c8d4fc6 refactor(forms): convert scripts within packages/forms to relative imports (#60624)
This commit updates scripts within `packages/forms` to relative imports as a prep work to the upcoming infra updates.

PR Close #60624
2025-03-31 19:22:09 +00:00
Matthieu Riegler 09df589e31 refactor(core): Migrate all packages with the explicit-standalone-flag schematic. (#58160)
All components, directives and pipes will now use standalone as default.
Non-standalone decorators have now `standalone: false`.

PR Close #58160
2024-10-14 14:58:57 +00:00
Joey Perrott 9dbe6fc18b refactor: update license text to point to angular.dev (#57901)
Update license text to point to angular.dev instead of angular.io

PR Close #57901
2024-09-24 15:33:00 +02:00
Matthieu Riegler b2445a0953 fix(core): link errors to ADEV (#55554) (#56038)
Console error links will now point to adev.

PR Close #55554

PR Close #56038
2024-05-28 12:50:53 +02:00
Pawel Kozlowski 760207b254 Revert "fix(core): link errors to ADEV (#55554)" (#56031)
This reverts commit dd0700ff1d.
We will need G3 patch cleanup before this one can land.

PR Close #56031
2024-05-23 13:57:53 +02:00
Matthieu Riegler dd0700ff1d fix(core): link errors to ADEV (#55554)
Console error links will now point to adev.

PR Close #55554
2024-05-23 11:58:54 +02:00
Matthieu Riegler fedeaac8ba fix(forms): Add event for forms submitted & reset (#55667)
This commit adds 2 new events to the unified control event observable.

PR Close #55667
2024-05-09 09:21:14 -07:00
fdonzello c001b05c77 refactor(forms): added control name in console errors (#55397)
When a formControlName is used without a parent formGroup, an error is
logged in the console. Before this commit, there was no information
about which control had the issue. Now, it's reported and the
troubleshoot is much faster.

PR Close #55397
2024-04-23 15:16:57 -07:00
Joey Perrott a2aca69bd3 refactor: migrate forms to prettier formatting (#55423)
Migrate formatting to prettier for forms from clang-format

PR Close #55423
2024-04-19 13:49:24 -07:00
Matthieu Riegler 3547e1e769 refactor(forms): emit status/value event in a consistant order (#55198)
We emit `ValueChangeEvent` first and then `StatusChangeEvent`

PR Close #55198
2024-04-09 15:21:39 -07:00
cexbrayat 9c776d6802 docs(forms): add docs for emitEvent flag (#55249)
PR Close #55249
2024-04-09 10:31:10 -07:00
Matthieu Riegler 1c736dc3b2 feat(forms): Unified Control State Change Events (#54579)
This commit introduces a new method to subscribe to on every `AbstractControl` subclass.
It allows to track value, pristine, touched and status changes on a given control.

Fixes #10887

PR Close #54579
2024-04-03 17:12:04 +00:00
Kristiyan Kostadinov c07805612f test(core): clean up unnecessary nesting in old tests (#52239)
A lot of our tests are wrapped in `{}` which serves no purpose, aside from increasing the nesting level and, in some cases, causing confusion. The braces appear to be a leftover from a time when all tests were wrapped in a `function main() {}`. The function declaration was removed in #21053, but the braces remained, presumably because it was easier to search&replace for `function main()`, but not to remove the braces at the same time.

PR Close #52239
2023-10-19 09:26:15 -07:00
Kristiyan Kostadinov 52cc7f839b build: align with internal tsconfig options (#51728)
Currently internally Angular has some customized tsconfig files, because we don't align with the tsconfig of the rest of g3. These changes enable `noImplicitReturns` and `noPropertyAccessFromIndexSignature` to align better with the internal config.

PR Close #51728
2023-09-12 11:39:42 -07:00
Matthieu Riegler a871e23857 docs: remove duplicate words. (#51215)
Using the `\b(\w+)\s+\1\b` we can find duplicate word. Let's remove them.

PR Close #51215
2023-08-01 12:08:33 -07:00
Dylan Hunn 59685614f8 fix(forms): Make radio buttons respect [attr.disabled] (#48864)
`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
2023-02-10 11:25:11 +01:00
Matthieu Riegler 6edf35c8d6 refactor(forms): remove deprecated uses from the unit tests (#48894)
Jasmine has deprecated the `expectationFailOutput` argument and replaced it by the `withContext()` method

Also removing all references to #24571 from the forms unit tests as the non null assertions are fine in the context.

PR Close #48894
2023-02-02 09:28:39 -08:00
Dylan Hunn 604cdb7307 fix(forms): Improve a very commonly viewed error message by adding a guide. (#47969)
[A Github issue](https://github.com/angular/angular/issues/43821) about an arcane-sounding Forms error is one of the repo's top-ten most visited pages. This converts the error to `RuntimeErrorCode` and adds a dedicated guide to explain how to solve it.

PR Close #47969
2022-11-07 16:00:06 -08:00
Kristiyan Kostadinov 4a13210ecd fix(forms): don't prevent default behavior for forms with method="dialog" (#47308)
The forms `submit` event handlers have a `return false` to prevent form submissions from reloading the page, however this also prevents the browser behavior for forms with `method="dialog"`.

These changes add an exception since the `method="dialog"` doesn't refresh the page.

Fixes #47150.

PR Close #47308
2022-09-09 14:26:48 -07:00
Kristiyan Kostadinov b36dec6b5b fix(forms): not picking up disabled state if group is swapped out and disabled (#43499)
Fixes a long-standing issue where swapping out the `FormGroup` and calling `disable` immediately afterwards doesn't actually disable the `ControlValueAccessor`.

Fixes #22556.

PR Close #43499
2022-03-28 09:26:19 -07:00
JiaLiPassion 225e4f2dbe feat(core): triggerEventHandler accept optional eventObj (#45279)
Close #44724

`DebugNode.triggerEventHandler()` should accept the `eventObj` as an
optional parameter. So the user don't have to write code like

```
elem.triggerEventHandler('click', null);
```

PR Close #45279
2022-03-09 13:51:54 -08:00
iRealNirmal 531d1cf9a3 refactor(forms): update required validator and checkbox validator to inherit abstractValidator (#44162)
Modified required validator and checkbox validator to inherit abstractValidator.

For every validato type different PR will be raised as discussed in #42378.

Closes #42267

PR Close #44162
2022-01-24 14:50:57 -08:00
Dylan Hunn 65717999c8 refactor(forms): Make the minimum changes to the forms unit tests in order to support the typed forms PR (#43834). (#44451)
Currently, many of our unit tests are written to use heterogenous groups and arrays, and controls that accept heterogenous values. This PR will make the minimum possible alterations to prepare those usages, mainly by annotating them as untyped controls, etc.

This PR is *not* intended to test typed forms, merely to minimize the size of the upcoming PR. This will allow that PR to be focused on the actual features and tests, rather than boilerplate fixes.

PR Close #44451
2021-12-14 16:10:08 -05:00
iRealNirmal d9d8f950e9 feat(forms): allow disabling min/max validators dynamically (by setting the value to null) (#42978)
This commit updates the logic of the `min` and `max` validators to allow
disabling them dynamically in case `null` is provided as a value. For example: `<input
type="number" [min]="minValue">`, when `minValue` might be set to `null` in a
component class. This should allow `min` and `max` validators to be used for dynamic forms.

Note: similar support was added to the `minLength` and `maxLength`
validators earlier (see #42565).

PR Close #42978
2021-09-24 10:35:31 -07:00
iRealNirmal a502279592 feat(forms): allow minLength/maxLength validator to be bound to null (#42565)
If the validator is bound to be `null` then no validation occurs and
attribute is not added to DOM.

For every validator type different PR will be raised as discussed in
https://github.com/angular/angular/pull/42378.

Closes #42267.

PR Close #42565
2021-07-21 22:35:59 +00:00
Dylan Hunn 34ce635e3a feat(forms): undo revert and add ng-submitted class to forms that have been submitted. (#42132) (#42132)
As previously discussed in pull/31070 and issues/30486, this would be useful because it is often desirable to apply styles to fields that are both `ng-invalid` and `ng-pristine` after the first attempt at form submission, but Angular does not provide any simple way to do this (although evidently Angularjs did). This will now be possible with a descendant selector such as `.ng-submitted .ng-invalid`.

In this implementation, the directive that sets control status classes on forms and formGroups has its set of statuses widened to include `ng-submitted`. Then, in the event that `is('submitted')` is invoked, the `submitted` property of the control container is returned iff it exists. This is preferred over checking whether the container is a `Form` or `FormGroup` directly to avoid reflecting on those classes.

Closes #30486.

PR Close #42132.

This reverts commit 00b1444d12, undoing the rollback of this change.

PR Close #42132
2021-06-08 14:02:29 -07:00
Jessica Janiuk 00b1444d12 Revert "feat(forms): add ng-submitted class to forms that have been submitted." (#42474)
This reverts commit f024d7556081f8913f21761bb8e6aab8d08be110.

PR Close #42474
2021-06-03 17:42:02 -07:00
Dylan Hunn 47270d9e63 feat(forms): add ng-submitted class to forms that have been submitted. (#42132)
As previously discussed in pull/31070 and issues/30486, this would be useful because it is often desirable to apply styles to fields that are both `ng-invalid` and `ng-pristine` after the first attempt at form submission, but Angular does not provide any simple way to do this (although evidently Angularjs did). This will now be possible with a descendant selector such as `.ng-submitted .ng-invalid`.

In this implementation, the directive that sets control status classes on forms and formGroups has its set of statuses widened to include `ng-submitted`. Then, in the event that `is('submitted')` is invoked, the `submitted` property of the control container is returned iff it exists. This is preferred over checking whether the container is a `Form` or `FormGroup` directly to avoid reflecting on those classes.

Closes #30486.

PR Close #42132
2021-06-03 13:21:29 -07:00
iRealNirmal 751cd83ae3 fix(forms): the min and max validators should work correctly with 0 as a value (#42412)
Prior to this change the `min` and `max` validator directives would not
set the `min` and `max` attributes on the host element. The problem was
caused by the truthy check in host binding expression that was
calculated as `false` when `0` is used as a value. This commit updates
the logic to leverage nullish coalescing operator in these host binding
expressions, so `0` is treated as a valid value, thus the `min` and
`max` attributes are set correctly.

Partially closes #42267

PR Close #42412
2021-06-03 11:34:46 -07:00
Kristiyan Kostadinov a787f78074 test: clean up internal testing utilities (#42177)
We have some internal proxies for all of the Jasmine functions, as well as some other helpers. This code hasn't been touched in more than 5 years, it can lead to confusion and it isn't really necessary since the same can be achieved using Jasmine.

These changes remove most of the code and clean up our existing unit tests.

PR Close #42177
2021-05-26 20:07:25 +00:00
iRealNirmal 3d9062dad7 fix(forms): Add float number support for min and max validator (#42223)
Added float number support for minValidator and maxValidator

Closes #42215

PR Close #42223
2021-05-25 20:31:09 +00:00
Dylan Hunn a4ebe8656e fix(forms): registerOnValidatorChange should be called for ngModelGroup. (#41971)
The Validator and AsyncValidator interfaces provide a callback, `registerOnValidatorChange(fn)`. `registerOnValidatorChange` is supposed to be fired at least once to register `fn` with the validator. `fn` is then called by the validator whenever its inputs change. This was previously not happening for FormGroup validators, and is now fixed.

PR Close #41971
2021-05-13 13:57:47 -04:00