Build Your First Angular Website: Lesson 10 of 18

Contact Form Validations

Up Next

Routing to Two Pages

Autoplaying in 7 seconds!

Cancel

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.

Table of Contents

    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>

    Chris Sevilleja

    176 posts

    Founder of Scotch.io. Google Developer Expert in Web Technologies. Slapping the keyboard until something good happens.