Angular form validation how to show error message on submit

Viewed 23602

I have a form as follows :

<form [formGroup]="editProfileForm">
    <input type="text" id="name" class="form-control" placeholder="First" formControlName="firstName [(ngModel)]="profileDetails.first_name">
    <small class="text-danger" [hidden]="editProfileForm.controls['firstName'].valid || (editProfileForm.controls['firstName'].pristine && !submitted)">First name Required</small>
    <input type="text" class="form-control" placeholder="Last" formControlName="lastName" [(ngModel)]="profileDetails.last_name">
    <small class="text-danger" [hidden]="editProfileForm.controls['lastName'].valid || (editProfileForm.controls['lastName'].pristine && !submitted)">Last name Required</small>
    <button class="save-changes-btn" [disabled]="(!editProfileForm.valid)" (click)="saveDetails();">Save Changes</button>
</form>

and the editProfile is defined in the component file as

this.editProfileForm = this.formBuilder.group({
    firstName: [_.get(this.profileDetails, 'first_name', ''), Validators.required],
    lastName: [_.get(this.profileDetails, 'last_name', ''), Validators.required],
});

Now I need to show the validation messages on clicking the submit button. Here now I have disabled the submit button if, the form is not valid. But it will not show the error messages near to the corresponding fields and this will makes the user thinks that the there is nothing happening. How can I trigger the error messages to show near corresponding input fields ?

3 Answers

When saving, if the form is not valid, simply call markAllAsTouched() on the form group.

saveDetails() {
  if(!this.editProfileForm.valid) {
    this.editProfileForm.markAllAsTouched();
  }
}

You can do something like this.

First remove the disabling logic in the submit button.

In component template.

<form [formGroup]="editProfileForm" (ngSubmit)="onSubmit()">
  <div class="form-group block" [ngClass]="{'has-error': submitted && (editProfileForm.controls.firstName.errors)}">
    <label>Email</label>
    <input type="text" class="form-control" formControlName="firstName">
    <p>
      <span *ngIf="submitted && editProfileForm.controls.firstName.errors?.required">First name is required</span>
    </p>
  </div>

  // other controls
</form>

In component class

public onSubmit(): void {
  this.submitted = true;
  if(!this.editProfileForm.valid) {
    return;
  }

  // make the submitted variable false when submission is completed.

}

you can remove following part if you need to.

[ngClass]="{'has-error': submitted && (editProfileForm.controls.firstName.errors)}"

It will add css class to the element when the form control is invalid and submitted.

Use showValidationMsg() method and pass the form group as parameter inside submit button method:

showValidationMsg(formGroup: FormGroup) {

    for (const key in formGroup.controls) {
        if (formGroup.controls.hasOwnProperty(key)) {
            const control: FormControl = <FormControl>formGroup.controls[key];

            if (Object.keys(control).includes('controls')) {
                const formGroupChild: FormGroup = <FormGroup>formGroup.controls[key];
                this.showValidationMsg(formGroupChild);
            }

            control.markAsTouched();
        }
    }
}
Related