Build Your First Angular Website

Contact Form Validations

We've created our contact form and are able to submit it using the processForm() method on our class:

<!-- form goes here -->
<form (ngSubmit)="processForm()">

  <!-- name -->
  <div class="field">
    <input type="text" name="name" class="input" placeholder="Your Name" [(ngModel)]="name">
  </div>

  <!-- email -->
  <div class="field">
    <input type="email" name="email" class="input" placeholder="Your Email" [(ngModel)]="email">
  </div>

  <!-- message -->
  <div class="field">
    <textarea class="textarea" name="message" placeholder="What's on your mind?" [(ngModel)]="message"></textarea>
  </div>

  <button type="submit" class="button is-danger is-large">Submit</button>

</form>

Next up let's add validation for this form.

How We Add Validation

Since this is a template-driven form, we are going to add validation inside of our template. No need to touch our class for some simple validation.

The steps for adding validation will be:

  • Create the rules
  • Create local template variables
  • Show errors or success based on local template variables

Create the Rules

Let's use our template to create our rules. We'll use the same syntax for HTML validation rules. Here are our rules:

  • name: required and minimum length 3
  • email: must be a valid email
  • message: required

Update your two inputs and textarea to have the following:

<input 
  type="text" 
  name="name" 
  class="input" 
  placeholder="Your Name" 
  [(ngModel)]="name"
  required
  minlength="3">

<input 
  type="email" 
  name="email" 
  class="input" 
  placeholder="Your Email" 
  [(ngModel)]="email"
  required
  email>

<textarea 
  class="textarea" 
  name="message" 
  placeholder="What's on your mind?" 
  [(ngModel)]="message"
  required></textarea>

Notice that we've added the required attribute to each. We've also got minlength="3" for name and email for email.

We've also broken this out to multiple lines for readability since our lines were getting pretty long.

Local Template Variables

The next step is to create local variables for each input so that we can access them from within our template. This basically means we can reference each input from within our template without having to create any variables within our class.

You can create a template variable using the #variableName="ngModel" syntax. This binds that DOM element to the ngModel directive so that we can have access to the element. We can then see if this input is valid or not.

Update your template to have the following template variables:

<input 
  type="text" 
  name="name" 
  class="input" 
  placeholder="Your Name" 
  [(ngModel)]="name"
  required
  minlength="3"
  #nameInput="ngModel">

<input 
  type="email" 
  name="email" 
  class="input" 
  placeholder="Your Email" 
  [(ngModel)]="email"
  required
  email
  #emailInput="ngModel">

<textarea 
  class="textarea" 
  name="message" 
  placeholder="What's on your mind?" 
  [(ngModel)]="message"
  required
  #messageInput="ngModel"></textarea>

Validation States

Now that we have our template variables, we have access to a few things. If we look into our nameInput, we can see that we have things like:

  • nameInput.errors (Object): An object that shows all the validations
  • nameInput.valid (Boolean): Is the field valid?
  • nameInput.invalid (Boolean): Is the field invalid?
  • nameInput.dirty (Boolean): Has the field been typed into?
  • nameInput.touched (Boolean): Has the field been clicked into?
  • nameInput.untouched (Boolean): Opposite of touched

For more info on the validation states, check out our Angular Forms Course.

Adding Our Error/Success Messages

With these variables, we can add success and error messages using the *ngIf directive. For example, our name input will have the following validations:

<!-- name -->
<div class="field">
  <input 
    type="text" 
    name="name" 
    class="input" 
    placeholder="Your Name" 
    [(ngModel)]="name"
    required
    minlength="3"
    #nameInput="ngModel">

  <div class="help is-error" *ngIf="nameInput.invalid && nameInput.dirty">
    Name is required and needs to be at least 3 characters long.
  </div>
</div>

Now this error will only show if name is not valid and name has been typed into. Go ahead and do the same for our other inputs. You could create multiple *ngIfs to handle each validation separately.

Here's the full final code:

<!-- form goes here -->
<form (ngSubmit)="processForm()">

  <!-- name -->
  <div class="field">
    <input 
      type="text" 
      name="name" 
      class="input" 
      placeholder="Your Name" 
      [(ngModel)]="name"
      required
      minlength="3"
      #nameInput="ngModel">

    <div class="help is-error" *ngIf="nameInput.invalid && nameInput.dirty">
      Name is required and needs to be at least 3 characters long.
    </div>
  </div>

  <!-- email -->
  <div class="field">          
    <input 
      type="email" 
      name="email" 
      class="input" 
      placeholder="Your Email" 
      [(ngModel)]="email"
      required
      email
      #emailInput="ngModel">

    <div class="help is-error" *ngIf="emailInput.invalid && emailInput.dirty">
      Needs to be a valid email.
    </div>
  </div>

  <!-- message -->
  <div class="field">
    <textarea 
      class="textarea" 
      name="message" 
      placeholder="What's on your mind?" 
      [(ngModel)]="message"
      required
      #messageInput="ngModel"></textarea>

      <div class="help is-error" *ngIf="emailInput.invalid && emailInput.dirty">
        Your message is required!
      </div>
  </div>

  <button type="submit" class="button is-danger is-large">Submit</button>

</form>