Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Input fields are marked as red despite form reset in Angular

I got this problem where I have a form with input validation that contains a reset button which upon clicking should reset the form and thus the state of the inputfields as well as the submitted state. The inputfields are cleared, however they are marked red since one validation criterion is that the inputfield shall not be empty. Can someone explain why this happens or better how to fix it.

Thanks in advance!

import { Component, OnInit } from "@angular/core";
import { NgForm } from "@angular/forms";

@Component({
  selector: "app-contact",
  templateUrl: "./contact.component.html",
  styleUrls: ["./contact.component.css"],
})
export class ContactComponent implements OnInit {
  constructor() {}

  ngOnInit(): void {}

  sendMessage(form: NgForm): void {
    if (form.invalid) {
      return;
    }
    form.resetForm();
    form.reset();
  }

  clear(form: NgForm): void {
    form.resetForm();
  }
}
<mat-card>
  <form
    class="contactForm"
    (ngSubmit)="sendMessage(postForm)"
    #postForm="ngForm"
    [ngFormOptions]="{ updateOn: 'submit' }"
  >
    <mat-form-field class="nameField">
      <mat-label> Your Name </mat-label>
      <input
        matInput
        type="text"
        required
        name="inputName"
        ngModel
        #name="ngModel"
      />
      <mat-error *ngIf="true">
        Please enter a name
      </mat-error>
    </mat-form-field>

    <mat-form-field class="emailField">
      <mat-label> Your E-Mail </mat-label>
      <input
        matInput
        type="email"
        required
        name="inputEmail"
        ngModel
        email
        #email="ngModel"
      />
      <mat-error *ngIf="true">
        Please enter a valid email address
      </mat-error>
    </mat-form-field>

    <mat-form-field class="msgField">
      <mat-label> Your Message </mat-label>
      <textarea
        matInput
        type="text"
        required
        name="message"
        ngModel
        #message="ngModel"
      >
      </textarea>
      <mat-error *ngIf="true">
        Please enter a message
      </mat-error>
    </mat-form-field>

    <button mat-raised-button class="sendBtn" color="accent" type="submit">
      Send
    </button>
    <button
      mat-raised-button
      class="clearBtn"
      color="warn"
      (click)="clear(postForm)"
    >
      Clear
    </button>
  </form>
</mat-card>
like image 946
Jiaxuan He Avatar asked Dec 13 '22 08:12

Jiaxuan He


2 Answers

I had the same issue with my Angular (v8) project. The problem is even though the form is reset the error state isn't set back to null.

What worked for me was manually resetting the error state for each form control. It's not the prettiest, but it worked. Try something like this:

clear(form: NgForm): void {
    form.resetForm();
    Object.keys(form.controls).forEach(key =>{
       form.controls[key].setErrors(null)
    });
  }

One caveat though is I was using Reactive Forms and created the form as a Formgroup, using Formbuilder. I'm not positive if simply using form templates like you're if the result will be the same.

like image 145
Narm Avatar answered Jan 13 '23 15:01

Narm


Add type="button" attribute to your clear button.

As you are adding (ngSubmit)="sendMessage(postForm)" to form, the clear button is considered as form submission and hence the function sendMessage(postForm) gets called and as a result you are getting the validation messages..

As a note, you could also use type="reset" like,

<button
  mat-raised-button
  class="clearBtn"
  color="warn"
  (click)="clear(postForm)"
  type="reset"
>
  Clear
</button>

This resets all of the inputs in the form to their initial values.

Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/reset

component.html

<mat-card>
  <form
    class="contactForm"
    (ngSubmit)="sendMessage(postForm)"
    #postForm="ngForm"
    [ngFormOptions]="{ updateOn: 'submit' }"
  >
    <mat-form-field class="nameField">
      <mat-label> Your Name </mat-label>
      <input
        matInput
        type="text"
        required
        name="inputName"
        ngModel
        #name="ngModel"
      />
      <mat-error *ngIf="true">
        Please enter a name
      </mat-error>
    </mat-form-field>

    <mat-form-field class="emailField">
      <mat-label> Your E-Mail </mat-label>
      <input
        matInput
        type="email"
        required
        name="inputEmail"
        ngModel
        email
        #email="ngModel"
      />
      <mat-error *ngIf="true">
        Please enter a valid email address
      </mat-error>
    </mat-form-field>

    <mat-form-field class="msgField">
      <mat-label> Your Message </mat-label>
      <textarea
        matInput
        type="text"
        required
        name="message"
        ngModel
        #message="ngModel"
      >
      </textarea>
      <mat-error *ngIf="true">
        Please enter a message
      </mat-error>
    </mat-form-field>

    <button mat-raised-button class="sendBtn" color="accent" type="submit">
      Send
    </button>
    <button
      mat-raised-button
      class="clearBtn"
      color="warn"
      (click)="clear(postForm)"
      type="button"
    >
      Clear
    </button>
  </form>
</mat-card>

Working Stackblitz

like image 41
Maniraj Murugan Avatar answered Jan 13 '23 17:01

Maniraj Murugan