Template driven form validation in Angular

In this tutorial, we will learn template-driven form validation in Angular. It is very common that the users will make mistakes when filling out the web form. This is where the validations come into play. The validation module must ensure that the user has provided accurate and complete information in the form fields. We must display the validation error messages to the users, disable the submit button until validation. In this tutorial, we will look at how validations are handled in Template-driven forms in Angular and learn how to use the Angular built-in validators.

This tutorial is a continuation of the Angular template-driven forms tutorial, where we built a simple form. In the next tutorial, we learned how to set the values to the form fields. We suggest you read those tutorials if you are new to Template-driven forms in Angular

Template-driven Form Validation

Validations in Template-driven forms are provided by the Validation directives. The Angular Forms Module comes with several built-in validators. You can also create your own custom Validator.

Template

Consider the following template-driven form. It has firstname, lastname, email, gender & istoc form fields.

Component Class

Disabling the Browser validation

First, we need to disable browser validator interfering with the Angular validator. To do that we need to add novalidate attribute on <form> element as shown below

Built-in Validators

The Built-in validators use the HTML5 validation attributes like required, minlength, maxlength & pattern. Angular interprets these validation attributes and add the validator functions to FormControl instance.

Adding in Built-in Validators

Required Validation

The required validator returns true only if the form control has non-empty value entered. Let us add this validator to all fields


Minlength Validation

This Validator requires the control value must not have less number of characters than the value specified in the validator.

For Example, minlength validator ensures that the firstname value has at least 10 characters.

Maxlength Validation

This Validator requires that the number of characters must not exceed the value of the attribute.

Pattern Validation

This Validator requires that the control value must match the regex pattern provided in the attribute. For example, the pattern ^[a-zA-Z]+$ ensures that the only letters are allowed (even spaces are not allowed). Let us apply this pattern to the lastName

Email Validation

This Validator requires that the control value must be a valid email address. We apply this to the email field

Disable Submit button

Now, we have successfully added the validators. You will notice that the click submit button still submits the form.

We need to disable the submit button if our form is not valid.

Angular forms module keep track of the state of our form and each of its form elements. These states are exposed to the user through FormGroup, FormArray & FormControl objects.

We get the reference to the top-level FormGroup instance by creating a template variable and bind it to ngForm. We have already done it when we had added the #contactForm="ngForm" in our form tag.

The FormGroup has a valid property, which is set to true if all of its child controls are valid. We use it to set the disabled attribute of the submit button.

So long as contactForm.valid remains false, the submit button remains disabled.

Displaying the Validation/Error messages

We need to provide a short and meaningful error message to the user.

Angular creates a FormControl for each and every field, which has ngModel directive applied. The FormControl exposes the state of form element like valid, dirty, touched, etc.

There are two ways in which you can get the reference to the FormControl.

One way is to use the contactForm variable. We can use the contactForm.controls.firstname.valid to find out if the firstname is valid.

The other way is to create a new local variable for each FormControl For Example, the following firstname="ngModel" creates the firstname variable with the FormControl instance.

Now, we have a reference to the firstname FormControl instance, we can check its status. We use the valid property to check if the firstname has any errors.

valid: returns either invalid status or null which means a valid status

Why check dirty and touched?

We do not want the application to display the error when the form is displayed for the first time. We want to display errors only after the user has attempted to change the value. The dirty & touched properties help us do that.

dirty: A control is dirty if the user has changed the value in the UI.
touched: A control is touched if the user has triggered a blur event on it.

Error message

The error message ” “Invalid First Name” ” is not helpful. The firstname has two validators. required and minlength

Any errors generated by the failing validation is updated in the errors object. The errors object returns the error object or null if there are no errors.

Note that the minlength validators return the {{firstname.errors.minlength?.requiredLength}}, which we use the display the error message.

Final Template

Summary

Angular template-driven form validation uses the directives known as validators. The validators handle form validations and display validation messages. The Angular comes up with several built-in validators for this purpose. They are minlength, maxlength, email, pattern, required, etc.

10 thoughts on “Template driven form validation in Angular”

  1. ” *ngIf=”!address?.valid && (address?.dirty || address?.touched)”>
    *ngIf=”address.errors?.[‘required’]” class=”error-msg”>Address is mandatory
    Address should be min of 5 charecters

  2. If U R using conditional validation messages, U should follow this new Ang-13/14 syntax

    Address is mandatory
    Address should be min of 5 charecters

  3. Can you please add the source code for template driven form via GitHub/StackBlitz to refer too. As I am getting many errors. Don’t know what I am doing wrong.

  4. i have searched multiple websites . and finally landed on yours now my consept and understanding is clear as hell thanks to you

  5. Very good example!
    I post here a simplifed version of the Component Class: it works like a charm.

    ——————- ——————- ——————-

    import { Component, OnInit } from “@angular/core”;

    @Component({
    selector: “my-app”,
    templateUrl: “./app.component.html”,
    styleUrls: [“./app.component.css”]
    })
    export class AppComponent implements OnInit {
    title = “Template driven forms”;

    contact: Contact;

    ngOnInit() {
    this.contact = {
    firstname: “”,
    lastname: “”,
    gender: “male”,
    isToc: true,
    email: “”
    };
    }

    onSubmit(contactForm) {
    console.log(contactForm.value);
    }
    }

    export class Contact {
    firstname: string;
    lastname: string;
    gender: string;
    isToc: boolean;
    email: string;
    }

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top