Angular 9/8 Form Validation with Template Driven Form using Bootstrap

Last updated on by Digamber
In this Angular 9/8 Form tutorial, we are going to learn how to implement simple validation rules with the template-driven approach using Bootstrap forms.

Angular 9 Template-driven Form Validation

To validate the form, we will also look at how to use Bootstrap UI library to facilitate our form validation task. In this Angular form example, we will create a basic form with some Input fields, such as name, email, password and hobbies.

In the previous tutorial, we implemented Angular form validation with Reactive Forms using Angular Material. However, we are going to take the diverse approach in this article.

By the end of this tutorial, you will understand following things:

  • How to quickly validate a form with template-driven approach in Angular 9.
  • How to create a form with Bootstrap form template.
  • How to bind ngModel directive with input controls to set the properties on the component.
  • How to submit the form with template driven approach.

Setting Up Angular Project

Run the below command to generate a brand new Angular 9 project using Angular CLI.

ng new angular-template-driven-form

Head over to the Angular form project.

cd angular-template-driven-form

Install Bootstrap in Angular 9

Install Bootstrap UI framework via NPM using following command.

npm install bootstrap

Add the Bootstrap CSS path in styles array inside the angular.json file.

"styles": [
    "src/styles.css",
    "node_modules/bootstrap/dist/css/bootstrap.min.css"
]

Now we have configured Angular and Bootstrap, run the command to open the app in the browser.

ng serve --open

Importing FormsModule

To get started with Form control and NgModel Angular Forms service, we require to import FormsModule in app.module.ts file.

// app/app.module.ts

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

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

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

export class AppModule { }

Create Form with Bootstrap From Template

Create a simple form in Angular using Bootstrap form component, open the app.component.html file and replace existing code with the following code.

<form novalidate>
  <div class="form-group">
    <label>Name</label>
    <input type="text" class="form-control">
  </div>

  <div class="form-group">
    <label>Email</label>
    <input type="email" class="form-control">
  </div>

  <div class="form-group">
    <label>Password</label>
    <input type="password" class="form-control">
  </div>

  <div class="form-group">
    <label>Hobbies</label>
    <select class="form-control">
      <option value="">Select an option</option>
      <option *ngFor="let hoby of Hobbies" [value]="hoby">
        {{hoby}}
      </option>
    </select>
  </div>

  <div class="form-group">
    <button class="btn btn-danger btn-block">Submit</button>
  </div>
</form>

Also, add the following options array for select drop-down input field in the app.component.ts file.

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  Hobbies: string[] = [
    'Acrobatics',
    'Acting',
    'Animation',
    'Astronomy',
    'Baking'
  ];
}

Implement Template-driven Form in Angular

Now we will add the template-driven form using ngModel directive in Angular component. Add the following code in the app.component.html file to initialize the Angular 9 template-driven form.

<form #userForm="ngForm" (ngSubmit)="onSubmit(userForm)">
  <div class="form-group">
    <label>Name</label>
    <input type="text" name="name" class="form-control" [(ngModel)]="model.name" required>
  </div>

  <div class="form-group">
    <label>Email</label>
    <input type="email" class="form-control" name="email" [(ngModel)]="model.email" required>
  </div>

  <div class="form-group">
    <label>Password</label>
    <input type="password" class="form-control" name="password" [(ngModel)]="model.password" required>
  </div>

  <div class="form-group">
    <label>Hobbies</label>
    <select class="form-control" name="hobbies" [(ngModel)]="hobbies">
      <option value="">Select an option</option>
      <option *ngFor="let hoby of Hobbies" [value]="hoby">
        {{hoby}}
      </option>
    </select>
  </div>

  <div class="form-group">
    <button class="btn btn-danger btn-block">Submit</button>
  </div>
</form>

To initiate the template-driven form, add a reference to the NgForm. Declare a template variable with the form by adding the #userForm="ngForm".

To submit the form add onSubmit(userForm) event on the form tag. When a user clicks on the submit button, then the input value will be passed through the onSubmit() method.

We also need to add a `name` property to the Angular 9 form To register the form control in the form, and it is required to be added.

The ngModel directive formulates a FormControl instance in the Angular form and attaches it with the form control item.

From the hobbies option, a user can select one hoby, add a select field to the form and define the options as Hobbies using *ngFor directive. The ngFor directive will iterate over Hobbies array and create the option tag for every option described in the array.

Open the app.component.ts file and add the following code.

import { Component } from '@angular/core';

export class User {
  public name: string;
  public email: string;
  public password: string;
  public hobbies: string;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  model = new User();

  Hobbies: string[] = [
    'Acrobatics',
    'Acting',
    'Animation',
    'Astronomy',
    'Baking'
  ];

  constructor() { }

  onSubmit(form) {
    console.log(form.value)
  }
}

Define a property class for the form model; it carries the form field’s value and set the model instance with User Class.

Adding Validation in Template-driven Form

Our Angular form is working correctly, but we have to add validation in our form and convey a strong message to the user if the form fields are invalid.

<form #userForm="ngForm" (ngSubmit)="userForm.form.valid && onSubmit(userForm)">
  <div class="form-group">
    <label>Name</label>
    <input type="text" name="name" class="form-control" [(ngModel)]="model.name" #name="ngModel"
      [ngClass]="{ 'is-invalid': userForm.submitted && name.invalid }" required>
    <div class="invalid-feedback" *ngIf="userForm.submitted && name.invalid">
      <p *ngIf="name.errors.required">Name is required</p>
    </div>
  </div>
</form>

We add the required validation in the name field, to access the form control inside the template. We created the name variable and assigned to “ngModel”.

To add the Bootstrap form validation, we implemented the validation to the class. Class validation applies only when the user submits the form and form is invalid.

To show the error message we used the Angular *ngIf directive and checking the input condition on submission and if the form is invalid.

Same way we applied the form validation in other input fields. Open the app.component.html file and add the following code.

<form #userForm="ngForm" (ngSubmit)="userForm.form.valid && onSubmit(userForm)">
  <div class="form-group">
    <label>Name</label>
    <input type="text" name="name" class="form-control" [(ngModel)]="model.name" #name="ngModel"
      [ngClass]="{ 'is-invalid': userForm.submitted && name.invalid }" required>
    <div class="invalid-feedback" *ngIf="userForm.submitted && name.invalid">
      <p *ngIf="name.errors.required">Name is required</p>
    </div>
  </div>

  <div class="form-group">
    <label>Email</label>
    <input type="email" class="form-control" name="email" [(ngModel)]="model.email" #email="ngModel"
      [ngClass]="{ 'is-invalid': userForm.submitted && email.invalid }" email required>
    <div *ngIf="userForm.submitted && email.invalid" class="invalid-feedback">
      <div *ngIf="email.errors.required">Email is required</div>
      <div *ngIf="email.errors.email">Must be a valid email address</div>
    </div>
  </div>

  <div class="form-group">
    <label>Password</label>
    <input type="password" class="form-control" name="password" [(ngModel)]="model.password" #password="ngModel"
      [ngClass]="{ 'is-invalid': userForm.submitted && password.invalid }" minlength="8" required>
    <div *ngIf="userForm.submitted && password.invalid" class="invalid-feedback">
      <div *ngIf="password.errors.required">Password is required</div>
      <div *ngIf="password.errors.minlength">Password should be at least 8 characters long</div>
    </div>
  </div>

  <div class="form-group">
    <label>Hobbies</label>
    <select class="form-control" name="hobbies" [(ngModel)]="hobbies">
      <option value="">Select an option</option>
      <option *ngFor="let hoby of Hobbies" [value]="hoby">
        {{hoby}}
      </option>
    </select>
  </div>

  <div class="form-group">
    <button class="btn btn-danger btn-block">Submit</button>
  </div>
</form>

Conclusion

Finally, we have completed the Angular 9/8 Forms tutorial, and In this tutorial, we learned how to create Angular form with the template-driven approach.

We learnt how to implement Bootstrap in Angular and create forms with Bootstrap.

We looked at how to work with the ngModel directive to handle the Angular form data.

We looked at how to add validation in template-driven forms as well as how to submit a form.

To get the full code of this tutorial visit this GitHub repository.

Thanks a lot for reading this tutorial.

Digamber
Digamber

Digamber Rawat is from Dev Bhoomi Uttarakhand, located in northwestern part of India. He is a Data Scientist by profession and a primary author of this blog.