feat(forms): add `markAllAsTouched()` to `AbstractControl` (#26812)
Add functionality to mark a control and its descendant controls as touched Closes #19400 PR Close #26812
This commit is contained in:
parent
ab2bf83398
commit
45bf911df8
|
@ -364,6 +364,16 @@ export abstract class AbstractControl {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the control and all its descendant controls as `touched`.
|
||||
* @see `markAsTouched()`
|
||||
*/
|
||||
markAllAsTouched(): void {
|
||||
this.markAsTouched({onlySelf: true});
|
||||
|
||||
this._forEachChild((control: AbstractControl) => control.markAllAsTouched());
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the control as `untouched`.
|
||||
*
|
||||
|
|
|
@ -96,6 +96,58 @@ import {of } from 'rxjs';
|
|||
});
|
||||
});
|
||||
|
||||
describe('markAllAsTouched', () => {
|
||||
it('should mark all descendants as touched', () => {
|
||||
const formArray: FormArray = new FormArray([
|
||||
new FormControl('v1'), new FormControl('v2'),
|
||||
new FormGroup({'c1': new FormControl('v1')}),
|
||||
new FormArray([new FormGroup({'c2': new FormControl('v2')})])
|
||||
]);
|
||||
|
||||
expect(formArray.touched).toBe(false);
|
||||
|
||||
const control1 = formArray.at(0) as FormControl;
|
||||
|
||||
expect(control1.touched).toBe(false);
|
||||
|
||||
const group1 = formArray.at(2) as FormGroup;
|
||||
|
||||
expect(group1.touched).toBe(false);
|
||||
|
||||
const group1Control1 = group1.get('c1') as FormControl;
|
||||
|
||||
expect(group1Control1.touched).toBe(false);
|
||||
|
||||
const innerFormArray = formArray.at(3) as FormArray;
|
||||
|
||||
expect(innerFormArray.touched).toBe(false);
|
||||
|
||||
const innerFormArrayGroup = innerFormArray.at(0) as FormGroup;
|
||||
|
||||
expect(innerFormArrayGroup.touched).toBe(false);
|
||||
|
||||
const innerFormArrayGroupControl1 = innerFormArrayGroup.get('c2') as FormControl;
|
||||
|
||||
expect(innerFormArrayGroupControl1.touched).toBe(false);
|
||||
|
||||
formArray.markAllAsTouched();
|
||||
|
||||
expect(formArray.touched).toBe(true);
|
||||
|
||||
expect(control1.touched).toBe(true);
|
||||
|
||||
expect(group1.touched).toBe(true);
|
||||
|
||||
expect(group1Control1.touched).toBe(true);
|
||||
|
||||
expect(innerFormArray.touched).toBe(true);
|
||||
|
||||
expect(innerFormArrayGroup.touched).toBe(true);
|
||||
|
||||
expect(innerFormArrayGroupControl1.touched).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setValue', () => {
|
||||
let c: FormControl, c2: FormControl, a: FormArray;
|
||||
|
||||
|
|
|
@ -47,6 +47,15 @@ import {FormArray} from '@angular/forms/src/model';
|
|||
expect(c.value).toBe(null);
|
||||
});
|
||||
|
||||
describe('markAllAsTouched', () => {
|
||||
it('should mark only the control itself as touched', () => {
|
||||
const control = new FormControl('');
|
||||
expect(control.touched).toBe(false);
|
||||
control.markAllAsTouched();
|
||||
expect(control.touched).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('boxed values', () => {
|
||||
it('should support valid boxed values on creation', () => {
|
||||
const c = new FormControl({value: 'some val', disabled: true}, null !, null !);
|
||||
|
|
|
@ -86,6 +86,67 @@ import {of } from 'rxjs';
|
|||
|
||||
});
|
||||
|
||||
describe('markAllAsTouched', () => {
|
||||
it('should mark all descendants as touched', () => {
|
||||
const formGroup: FormGroup = new FormGroup({
|
||||
'c1': new FormControl('v1'),
|
||||
'group': new FormGroup({'c2': new FormControl('v2'), 'c3': new FormControl('v3')}),
|
||||
'array': new FormArray([
|
||||
new FormControl('v4'), new FormControl('v5'),
|
||||
new FormGroup({'c4': new FormControl('v4')})
|
||||
])
|
||||
});
|
||||
|
||||
expect(formGroup.touched).toBe(false);
|
||||
|
||||
const control1 = formGroup.get('c1') as FormControl;
|
||||
|
||||
expect(control1.touched).toBe(false);
|
||||
|
||||
const innerGroup = formGroup.get('group') as FormGroup;
|
||||
|
||||
expect(innerGroup.touched).toBe(false);
|
||||
|
||||
const innerGroupFirstChildCtrl = innerGroup.get('c2') as FormControl;
|
||||
|
||||
expect(innerGroupFirstChildCtrl.touched).toBe(false);
|
||||
|
||||
formGroup.markAllAsTouched();
|
||||
|
||||
expect(formGroup.touched).toBe(true);
|
||||
|
||||
expect(control1.touched).toBe(true);
|
||||
|
||||
expect(innerGroup.touched).toBe(true);
|
||||
|
||||
expect(innerGroupFirstChildCtrl.touched).toBe(true);
|
||||
|
||||
const innerGroupSecondChildCtrl = innerGroup.get('c3') as FormControl;
|
||||
|
||||
expect(innerGroupSecondChildCtrl.touched).toBe(true);
|
||||
|
||||
const array = formGroup.get('array') as FormArray;
|
||||
|
||||
expect(array.touched).toBe(true);
|
||||
|
||||
const arrayFirstChildCtrl = array.at(0) as FormControl;
|
||||
|
||||
expect(arrayFirstChildCtrl.touched).toBe(true);
|
||||
|
||||
const arraySecondChildCtrl = array.at(1) as FormControl;
|
||||
|
||||
expect(arraySecondChildCtrl.touched).toBe(true);
|
||||
|
||||
const arrayFirstChildGroup = array.at(2) as FormGroup;
|
||||
|
||||
expect(arrayFirstChildGroup.touched).toBe(true);
|
||||
|
||||
const arrayFirstChildGroupFirstChildCtrl = arrayFirstChildGroup.get('c4') as FormControl;
|
||||
|
||||
expect(arrayFirstChildGroupFirstChildCtrl.touched).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('adding and removing controls', () => {
|
||||
it('should update value and validity when control is added', () => {
|
||||
const g = new FormGroup({'one': new FormControl('1')});
|
||||
|
|
|
@ -32,6 +32,7 @@ export declare abstract class AbstractControl {
|
|||
get(path: Array<string | number> | string): AbstractControl | null;
|
||||
getError(errorCode: string, path?: Array<string | number> | string): any;
|
||||
hasError(errorCode: string, path?: Array<string | number> | string): boolean;
|
||||
markAllAsTouched(): void;
|
||||
markAsDirty(opts?: {
|
||||
onlySelf?: boolean;
|
||||
}): void;
|
||||
|
|
Loading…
Reference in New Issue