Home > other >  Angular Reactive Form - Validate form on button click
Angular Reactive Form - Validate form on button click

Time:08-18

I have a form in which I am using FormBuilder to create my form. I need to validate it when the button is clicked.

Below is my HTML:

<input id="user-name" name="userName" placeholder="Enter Username" formControlName="username"  />
<label  for="user-name">Username</label>

<div  *ngIf="loginForm.controls['username'].touched && loginForm.controls['username'].errors?.['required']">Please enter the username</div>

Below is .ts file code:

constructor(private formBuilder: FormBuilder) {}

ngOnInit() {
  this.generateForm();
}

generateForm() {
  this.loginForm = this.formBuilder.group({
    username: [null, Validators.compose([Validators.required])],
    password: [null, Validators.compose([Validators.required])],
  });
}

Now, I don't want my validations to work before hitting the button. I want to make it work when I will hit the button, it will show me errors if any.

Any suggestions/solutions will help me a lot.

CodePudding user response:

  1. Create submitted flag.
submitted = true;
  1. Add (ngSubmit) event and update submitted to true. This indicates that when the form is submitted, the submitted flag is updated to true.
<form [formGroup]="loginForm" (ngSubmit)="submitted = true">
  
  ...

  <button>Submit</button>
</form>
  1. Show the error when submitted is true.
<div
  
  *ngIf="submitted && loginForm.controls['username'].errors?.['required']"
>
  Please enter the username
</div>

Demo @ StackBlitz


Additional

You may find out that when you submit the form when the field is not filled, it shows the error message (Correct behavior). You fill in the field, the error message is gone (Correct behavior). When you try to clear the field (to blank), an error message has appeared (Wrong behavior).

This is due to the submitted will be forever true when the form is submitted. For such scenario, you need to subscribe the form's valueChanges event and reset the submitted flag when the user inputs and the form is submitted previously.

import { debounceTime } from 'rxjs';

this.loginForm.valueChanges.pipe(debounceTime(500)).subscribe((_) => {
  if (this.submitted) this.submitted = false;
});

(Improved) Demo @ StackBlitz

CodePudding user response:

Hi You can create a function to mark all controls on the form as touched and fire it if the form is invalid.

submitForm(): void {
    if (this.loginForm.invalid) {
        this.markFormGroupTouched(this.loginForm);
        return;
    }
    // submit form actions
}

markFormGroupTouched(formGroup: FormGroup): void {
    ( Object as any).values(formGroup.controls).forEach(control => {
        control.markAsTouched();
        if (control.controls) {
            this.markFormGroupTouched(control);
        }
    });
}

I hope this help you, regards.

  • Related