Angular2 - How to set `touched` property on form to true
Asked Answered
E

4

44

I have a reactive form in my component and I want to set the touched property on every one of the inputs equal to true. My current code does this, but it throws the error Cannot set property touched of #<AbstractControl> which has only a getter:

addressForm: FormGroup;

...

this.addressForm = this._fb.group({
    street: ["", [<any>Validators.required]],
    city: ["", [<any>Validators.required]],
    state: ["", [<any>Validators.required]],
    zipCode: ["", [<any>Validators.required]],
    country: ["", [<any>Validators.required]]
});

...

for (var key in this.addressForm.controls) {
    this.addressForm.controls[key].touched = true;
}

How can I set the touched value of every input to true?

Entozoon answered 22/2, 2017 at 18:27 Comment(5)
Touched and Untouched are read only properties.you cannot assign a value.Blacklist
BTW if you use #myForm="ngForm" on your HTML form element, you have access to myForm.submitted in the HTML, so might not need to bother with .touchedPhalarope
@RonNewcomb you should add this as an answer. It save me some effortBenefice
this.addressForm.controls[key].markAsTouched()Supplicate
form.control.markAllAsTouched()Crumple
B
84

There's a pretty straightforward method to do this: markAsTouched. It should be enough to use it on the form group.

this.addressForm.markAsTouched()

In case you want for some reason to mark all controls manually, they itself have this method available.

markAsTouched is a method of the AbstractControl all form elements inherit from. Out of curiosity, you might want to visit the @angular/forms/src/model.d.ts declaration file to find some more interesting methods of the form objects. Or just visit the documentation.

Blanche answered 22/2, 2017 at 21:17 Comment(2)
this.addressForm.form.markAsTouched()Nodular
this.addressForm.controls['controlName'].markAsTouched();Allomorph
P
0

If you use #myForm="ngForm" on your HTML form element, you have access to myForm.submitted in the HTML, so might not need to bother with .touched

Phalarope answered 12/8, 2019 at 20:4 Comment(0)
T
0
@Component()
export class AppComponent {
  public loginForm: FormGroup = new FormGroup({
    email: new FormControl('', Validators.required),
    password: new FormControl('', Validators.required)
  });

  public onSubmit(): void {
    this.loginForm.markAllAsTouched();
    if(this.loginForm.valid) { ... }
  }
}

or better way write once and use it everywhere as a directive :D

 import { Directive, Self, HostListener } from '@angular/core';
  import { ControlContainer } from '@angular/forms';

  @Directive({
    selector: 'form[formGroup]'
  })
  export class MarkAllTouchedDirective {
    @HostListener('submit')
    public onSubmit(): void {
      this.container.control.markAllAsTouched();
    }

    constructor(
      @Self() private container: ControlContainer
    ) {}
  }
Tetrabrach answered 20/9, 2022 at 17:31 Comment(0)
C
0
 public markAllAsTouched(formGroup: FormGroup): void {
    (Object as any).values(formGroup.controls).forEach((control: any) => {
        control.markAsTouched();
        if (control.controls) {
            this.markAllAsTouched(control);
        }
    });
}

Use above function on submit action.

This can be another possible solution. Reference : https://www.geekstrick.com/markallastouched-in-angular-forms/

Catharine answered 23/5, 2023 at 8:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.