Angular 8/7 Form Validation with Bootstrap using Template driven Validation

In this tutorial, we will discuss how to implement simple form validation in Angular 8 application using Template-driven validation method.

For form validation tutorial we will use Bootstrap UI library to ease our task. In this form example, we will have Input field, Select box with single and multiple selections, Textarea and a checkbox.

On the form, we will add a template variable to get its reference in our component class using @ViewChild decorator. In component, we will define a method which will be called on clicking submit button on the form.

Let’s get started quickly!

Create an Angular Project

First, create a new Angular 8 project using Ng CLI tool by running following command in terminal:

$ ng new ng-form-validation-demo

Add Bootstrap Style

To use bootstrap UI components like form inputs, add bootstrap.css file in the index.html file in the head section:

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">

Import FormModule

We need to import FormModule to use Form control fields and NgModel in app.module.ts file:

// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { FormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Implement Form in Component Template

Now we will add a form in app.component.html file as shown below:

<form #MyForm="ngForm" (submit)="submitForm()">

    <div class="form-group">
        <label>Email address</label>
        <input type="text" class="form-control" name="email-field" placeholder="name@example.com" required
            [(ngModel)]="model.name">
    </div>
    <div class="form-group">
        <label for="exampleFormControlSelect1">Example select</label>
        <select class="form-control" id="exampleFormControlSelect1" name="single-select" required
            [(ngModel)]="modelSingleSelect">
            <option></option>
            <option>2</option>
            <option>3</option>
            <option>4</option>
            <option>5</option>
        </select>
    </div>
    <div class="form-group">
        <label for="exampleFormControlSelect2">Example multiple select</label>
        <select multiple class="form-control" id="exampleFormControlSelect2" name="multi-select" required
            [(ngModel)]="multiSelect">
            <option></option>
            <option>2</option>
            <option>3</option>
            <option>4</option>
            <option>5</option>
        </select>
    </div>
    <div class="form-group">
        <label for="exampleFormControlTextarea1">Example textarea</label>
        <textarea class="form-control" id="exampleFormControlTextarea1" rows="3" name="textarea-field" required
            [(ngModel)]="model.textareaField"></textarea>
    </div>
    <div class="custom-control custom-checkbox mb-3">
        <input type="checkbox" class="custom-control-input" id="customControlValidation1" name="condition-check" required  [(ngModel)]="model.checkbox">
        <label class="custom-control-label" for="customControlValidation1">Check this custom checkbox</label>
    </div>

    <button class="btn btn-primary">Submit</button>

</form>

In the form element, we have added template reference variable #MyForm of type ngForm with a (submit) event handler.

Update component class with submit method

// app.component.ts
import { Component, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';

export interface FormObject {
  email: string;
  singleSelect: string;
  multiSelect: string;
  textarea: string;
  radio: string;
  checkbox: any;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  model: FormObject;

  @ViewChild('MyForm', { static: false }) MyForm: NgForm;

  constructor() {
    this.model = ({} as FormObject);
  }

  submitForm() {
    console.log(this.MyForm.form.valid);
    this.MyForm.form.markAllAsTouched();
  }

}

Above component is having an interface FormObject defined.

To get form reference in class we used @ViewChild decorator.

@ViewChild('MyForm', { static: false }) MyForm: NgForm;

Here we also declared a model variable of type formObject and initialized in the class constructor.

...  
constructor() {
    this.model = ({} as FormObject);
  }
...

In the submitForm method, we are calling markAllAsTouched() method to validate form fields

Error handling in the form

To show red color border on fields, just add following CSS style in styles.css file at the project root.

/* You can add global styles to this file, and also import other style files */

.form-control.ng-touched.ng-invalid{
    border-color: #dc3545;
}

.custom-control-input.ng-invalid.ng-touched + label.custom-control-label{
    color: #dc3545;
}

.custom-control-input.ng-invalid.ng-touched + label.custom-control-label:before,
.custom-control-input.ng-invalid.ng-touched + label.custom-control-label:after
{
    border-color: #dc3545;
}
.custom-control-input.ng-invalid.ng-touched:focus~label.custom-control-label:before{
     box-shadow: 0 0 0 0.2rem rgba(220,53,69,.25);
}

 

That’s it! here we discussed how to quickly add a Form in Angular project with validations using Template-driven method.

Leave a Comment

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