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`.
|
* 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', () => {
|
describe('setValue', () => {
|
||||||
let c: FormControl, c2: FormControl, a: FormArray;
|
let c: FormControl, c2: FormControl, a: FormArray;
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,15 @@ import {FormArray} from '@angular/forms/src/model';
|
||||||
expect(c.value).toBe(null);
|
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', () => {
|
describe('boxed values', () => {
|
||||||
it('should support valid boxed values on creation', () => {
|
it('should support valid boxed values on creation', () => {
|
||||||
const c = new FormControl({value: 'some val', disabled: true}, null !, null !);
|
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', () => {
|
describe('adding and removing controls', () => {
|
||||||
it('should update value and validity when control is added', () => {
|
it('should update value and validity when control is added', () => {
|
||||||
const g = new FormGroup({'one': new FormControl('1')});
|
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;
|
get(path: Array<string | number> | string): AbstractControl | null;
|
||||||
getError(errorCode: string, path?: Array<string | number> | string): any;
|
getError(errorCode: string, path?: Array<string | number> | string): any;
|
||||||
hasError(errorCode: string, path?: Array<string | number> | string): boolean;
|
hasError(errorCode: string, path?: Array<string | number> | string): boolean;
|
||||||
|
markAllAsTouched(): void;
|
||||||
markAsDirty(opts?: {
|
markAsDirty(opts?: {
|
||||||
onlySelf?: boolean;
|
onlySelf?: boolean;
|
||||||
}): void;
|
}): void;
|
||||||
|
|
Loading…
Reference in New Issue