Home > Software engineering >  Angular Form Validators do not stop form submission
Angular Form Validators do not stop form submission

Time:09-03

I have an Angular Form built with a FormBuilder and Material Angular error messages set up in the template. I can get the validation error messages to show up. But they don't stop me from submitting the form. Shouldn't they dim the submit button somehow? Or do I manually have to put that logic in somehow?

Here is the Form built up in the component ts file:

ngOnInit(): void {
this.form = this.fb.group({
  name: ['',
    Validators.required,
    this.isDupeField("name")
  ],
  iso2: ['',
    [
      Validators.required,
      Validators.pattern(/^[a-zA-Z]{2}$/)
    ],
    this.isDupeField("iso2")
  ],
  iso3: ['',
    [
      Validators.required,
      Validators.pattern(/^[a-zA-Z]{3}$/)
    ],
    this.isDupeField("iso3")
  ]
});

    this.loadData();
}

And here is the form in the template:

<form [formGroup]="form" (ngSubmit)="onSubmit()">

<!-- Name -->
<mat-form-field>
  <mat-label>Name:</mat-label>
  <input matInput formControlName="name" required
         placeholder="Type a name" />
  <mat-error *ngIf="this.form.controls['name'].errors?.['required']">
    Name is required
  </mat-error>
  <mat-error *ngIf="this.form.controls['name'].errors?.['isDupField']">
    Name already exists: please choose another.
  </mat-error>
</mat-form-field>

<!-- ISO2 -->
<mat-form-field>
  <mat-label>
    ISO 3166-1 ALPHA-2 Country code (2 letters)
  </mat-label>
  <input matInput formControlName="iso2" required
         placeholder="Insert the ISO2 Country code" />
  <mat-error *ngIf="this.form.controls['iso2'].errors?.['required']">
    ISO 3166-1 ALPHA-2 Country code is required
  </mat-error>
  <mat-error *ngIf="this.form.controls['iso2'].errors?.['pattern']">
    ISO 3166-1 ALPHA-2 Country code requirs 2 letters.
  </mat-error>
  <mat-error *ngIf="this.form.controls['iso2'].errors?.['isDupeField']">
    This code already exists: please choose another.
  </mat-error>
</mat-form-field>

<!-- ISO3 -->
<mat-form-field>
  <mat-label>
    ISO 3166-1 ALPHA-3 Country code (3 letters)
  </mat-label>
  <input matInput formControlName="iso3" required
         placeholder="Insert the ISO3 Country code" />
  <mat-error *ngIf="this.form.controls['iso3'].errors?.['required']">
    ISO 3166-1 ALPHA-3 Country code is required
  </mat-error>
  <mat-error *ngIf="this.form.controls['iso3'].errors?.['pattern']">
    ISO 3166-1 ALPHA-3 Country code requirs 3 letters.
  </mat-error>
  <mat-error *ngIf="this.form.controls['iso3'].errors?.['isDupeField']">
    This code already exists: please choose another.
  </mat-error>
</mat-form-field>

<div>
  <button mat-flat-button color="primary"
          type="submit">
    {{ this.id ? "Save" : "Create" }}
  </button>
  <button mat-flat-button color="secondary"
          [routerLink]="['/countries']">
    Cancel
  </button>
</div>

The button is of type submit so shouldn't it be getting disabled somehow when there are validation errors?

CodePudding user response:

You need to bind an HTML property on the button element called disabled to your form state. Angular form will keep track of the state of the individual formControlNames inside the formGroup. Once they all satisfy their validators conditions set in your .ts file, the form will be marked as valid. If one of them is not satisfying its validator, the submit button will keep being disabled or even hidden if you want (it depends on the UX you prefer).

Putting this theory in a simple action, you only need to add this to your HTML file:

  <button mat-flat-button color="primary" type="submit" [disabled]="!form.valid">
    {{ this.id ? "Save" : "Create" }}
  </button>

You can also bind to hidden instead of disabled in the [disabled]="!form.valid".

  • Related