From 77dc6ef41190807f0bc47f18aeeb1758da77c3a6 Mon Sep 17 00:00:00 2001 From: Kara Date: Fri, 1 Jul 2016 15:36:04 -0700 Subject: [PATCH] fix(forms): mark control containers as touched when child controls are touched (#9735) --- modules/@angular/forms/src/model.ts | 9 +++- modules/@angular/forms/test/model_spec.ts | 60 +++++++++++++++++++++-- tools/public_api_guard/forms/index.d.ts | 4 +- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/modules/@angular/forms/src/model.ts b/modules/@angular/forms/src/model.ts index 17ad84347e..750a751708 100644 --- a/modules/@angular/forms/src/model.ts +++ b/modules/@angular/forms/src/model.ts @@ -120,7 +120,14 @@ export abstract class AbstractControl { clearValidators(): void { this.validator = null; } - markAsTouched(): void { this._touched = true; } + markAsTouched({onlySelf}: {onlySelf?: boolean} = {}): void { + onlySelf = normalizeBool(onlySelf); + this._touched = true; + + if (isPresent(this._parent) && !onlySelf) { + this._parent.markAsTouched({onlySelf: onlySelf}); + } + } markAsDirty({onlySelf}: {onlySelf?: boolean} = {}): void { onlySelf = normalizeBool(onlySelf); diff --git a/modules/@angular/forms/test/model_spec.ts b/modules/@angular/forms/test/model_spec.ts index d6561188a6..28eaf1d318 100644 --- a/modules/@angular/forms/test/model_spec.ts +++ b/modules/@angular/forms/test/model_spec.ts @@ -231,17 +231,30 @@ export function main() { describe('dirty', () => { it('should be false after creating a control', () => { - var c = new FormControl('value'); + const c = new FormControl('value'); expect(c.dirty).toEqual(false); }); it('should be true after changing the value of the control', () => { - var c = new FormControl('value'); + const c = new FormControl('value'); c.markAsDirty(); expect(c.dirty).toEqual(true); }); }); + describe('touched', () => { + it('should be false after creating a control', () => { + const c = new FormControl('value'); + expect(c.touched).toEqual(false); + }); + + it('should be true after markAsTouched runs', () => { + const c = new FormControl('value'); + c.markAsTouched(); + expect(c.touched).toEqual(true); + }); + }); + describe('updateValue', () => { var g: any /** TODO #9100 */, c: any /** TODO #9100 */; beforeEach(() => { @@ -504,7 +517,7 @@ export function main() { }); describe('dirty', () => { - var c: any /** TODO #9100 */, g: any /** TODO #9100 */; + var c: FormControl, g: FormGroup; beforeEach(() => { c = new FormControl('value'); @@ -513,13 +526,31 @@ export function main() { it('should be false after creating a control', () => { expect(g.dirty).toEqual(false); }); - it('should be false after changing the value of the control', () => { + it('should be true after changing the value of the control', () => { c.markAsDirty(); expect(g.dirty).toEqual(true); }); }); + + describe('touched', () => { + var c: FormControl, g: FormGroup; + + beforeEach(() => { + c = new FormControl('value'); + g = new FormGroup({'one': c}); + }); + + it('should be false after creating a control', () => { expect(g.touched).toEqual(false); }); + + it('should be true after control is marked as touched', () => { + c.markAsTouched(); + + expect(g.touched).toEqual(true); + }); + }); + describe('optional components', () => { describe('contains', () => { var group: any /** TODO #9100 */; @@ -817,13 +848,32 @@ export function main() { it('should be false after creating a control', () => { expect(a.dirty).toEqual(false); }); - it('should be false after changing the value of the control', () => { + it('should be true after changing the value of the control', () => { c.markAsDirty(); expect(a.dirty).toEqual(true); }); }); + describe('touched', () => { + var c: FormControl; + var a: FormArray; + + beforeEach(() => { + c = new FormControl('value'); + a = new FormArray([c]); + }); + + it('should be false after creating a control', () => { expect(a.touched).toEqual(false); }); + + it('should be true after child control is marked as touched', () => { + c.markAsTouched(); + + expect(a.touched).toEqual(true); + }); + }); + + describe('pending', () => { var c: FormControl; var a: FormArray; diff --git a/tools/public_api_guard/forms/index.d.ts b/tools/public_api_guard/forms/index.d.ts index 06828ccc20..e9c4b3a30e 100644 --- a/tools/public_api_guard/forms/index.d.ts +++ b/tools/public_api_guard/forms/index.d.ts @@ -28,7 +28,9 @@ export declare abstract class AbstractControl { markAsPending({onlySelf}?: { onlySelf?: boolean; }): void; - markAsTouched(): void; + markAsTouched({onlySelf}?: { + onlySelf?: boolean; + }): void; setAsyncValidators(newValidator: AsyncValidatorFn | AsyncValidatorFn[]): void; setErrors(errors: { [key: string]: any;