Angular template driven form validation

Updated : Oct 25, 2019 in Angular

Angular 4 template driven form validation

This article, we will learn Angular 4 template driven form validation

template driven forms we use directives to create model, wherein mode driven we create a model in component and then use directives to map elements.

In template-driven angular creates the FormGroups and FromControls by using the directives we add to the template, wherein model driven we create the FormGroups and FormControls.

Step1: Create a form

File: templatedriven.html

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

Step2:  Create an instance for the form using ngForm,

ngForm by default will be hidden so to make it expose we need to use local template reference variable with prefix #

<form #myForm ="ngForm" novalidate>
. . . .
<pre>{{myForm.value|json}}</pre>
</form>

Output: 
{
}

If we display the value of our form in JSON format it shows empty object { } because ngForm is alone not able to detect the controls of the form. So for that, we need to use the name and ngModelattributesfor the controls.

<form novalidate>
            <div class="form-group">
                <label>First Name</label>
                <input type="text" name="firstName"  ngModel class="form-control required />                
            </div>
            <div class="form-group">
                <label>Last Name</label>
                <input type="text" name="lastName" ngModel class="form-control" required />
            </div>
<pre>{{myForm.value|json}}</pre>
</form>

Output: All this will give us a one-way binding

Two-way binding: To achieve two-way binding we must use ngModel, so that when using makes any changes it automatically updates the component variables.

<form #f="ngForm">
            <div class="form-group">
                <label>First Name</label>
                <input type="text" name="firstName" [(ngModel)]="firstName" class="form-control" />  
            </div>
            <div class="form-group">
                <label>Last Name</label>
                <input type="text" name="lastName" [(ngModel)]="lastName" class="form-control" />
                
            <pre>{{f.value|json}}</pre>
 </form>

Now let’s create a component with variables.

File: app.TemplateFormComponent.ts

import { Component, Pipe,ViewChild } from '@angular/core';

@Component({
    selector: 'my-app',
    templateUrl: `./templatedriven.html`,
})
export class TemplateFormComponent{
    firstName = "";
    lastName = "";
}

(Or)

We can create component variables via model

import { Component, Pipe,ViewChild } from '@angular/core';

class Person {
    firstName: string;
    lastName: string
    constructor() { }
}

@Component({
    selector: 'my-app',
    templateUrl: `./templatedriven.html`,
})
export class TemplateFormComponent{
    person = new Person();
}

Following changes to be made in templatedriven.html

<input type="text" name="firstName" [(ngModel)]="person.firstName" class="form-control" />
<input type="text" name="firstName" [(ngModel)]="person.lastName" class="form-control" />

Validations with template driven

Step3: Validations

As we have provided validations in model driven using HTML5 attributes, in template driven also we use the same.

<div class="form-group">
                <label>First Name</label>
                <input type="text" name="firstName" [(ngModel)]="person.firstName" class="form-control" value="" required pattern="[a-zA-Z0-9 ]+"/>              
            </div>

For shorter validation expression instead of f.form.controls.firstname? We can get access to instance of ngModel by using local reference template variables

Ex: #first=”ngModel”

<div class="form-group">
                <label>First Name</label>
                <input type="text" name="firstName" [(ngModel)]="person.firstName" class="form-control" #first="ngModel" value="" required pattern="[a-zA-Z0-9 ]+"/>    
</div>

This syntax looks more simple and easy to understand.

Now we need to show the error message,

<div class="form-group">
                <label>First Name</label>
                <input type="text" name="firstName" [(ngModel)]="person.firstName" class="form-control" #first="ngModel" value="" required pattern="[a-zA-Z0-9 ]+"/>
                <div class="form-control-feedback" *ngIf="first.errors &amp;&amp; (first.dirty || first.touched)">
                    <p *ngIf="first.errors.required">First Name is required</p>
                    <p *ngIf="first.errors.pattern">First Name cannot contain special charactes !, @, #, $ etc..</p>
                </div>
            </div>
<div class="form-group">
                <label>Last Name</label>
                <input type="text" name="lastName" [(ngModel)]="lastName" class="form-control" #last="ngModel" value="" required pattern="[a-zA-Z0-9 ]{0,6}"/>
                <div class="form-control-feedback" *ngIf="last.errors &amp;&amp; (last.dirty || last.touched)">
                    <p *ngIf="last.errors.required">Last Name is required</p>
                    <p *ngIf="last.errors.pattern">Last Name cannot exceed 6 characters</p>
                </div>
            </div>

Validation Styling:

For providing validation styling we can either use bootstrap class has-danger, has-success

<div class="form-group" [ngClass]="{
      'has-danger': first.invalid &amp;&amp; (first.dirty || first.touched),
      'has-success': first.valid &amp;&amp; (first.dirty || first.touched)
 }">
                <label>First Name</label>
                <input type="text" name="firstName" [(ngModel)]="person.firstName" class="form-control" #first="ngModel" value="" required pattern="[a-zA-Z0-9 ]+"/>
                <div class="form-control-feedback" *ngIf="first.errors &amp;&amp; (first.dirty || first.touched)">
                    <p *ngIf="first.errors.required">First Name is required</p>
                    <p *ngIf="first.errors.pattern">First Name cannot contain special charactes !, @, #, $ etc..</p>
                </div>
            </div>

(Or)

We can make styling with the following styles.

@Component({
    selector: 'my-app',
    templateUrl: `./templatedriven.html`,
    styles: [
        `
.ng-valid[required], .ng-valid.required  {
  border-left: 5px solid #42A948; /* green */
}

.ng-invalid:not(form)  {
  border-left: 5px solid #a94442; /* red */
}

`
    ]
})

Submitting and Resetting Form

Submitting form will be the same as that we have done in the model driven forms using ngSubmit built-in directive.

<form #f="ngForm" (ngSubmit)="onSubmit()">
. . . .
</form>

Add the function onSubmit() in your component class

export class TemplateFormComponent{
    person = new Person();
    firstName = "";
    lastName = "";
    message = "";
    
    onSubmit() {
        this.message = "Form Submitted";
    }
}

Resetting Form:

you can see also Custom Validations in Angular

As we have done resetting in model driven forms using reset() on the myform model, but in template driven we don’t have access to the form model in the component.

So to achieve this we can use @ViewChild decorator.

@ViewChild: This decorator gives the reference of anything from the template in the component.

Create a component variable with @ViewChild decorator applied to it.

@ViewChild('f') form: any;

Now we can call the reset() in onSubmit() as we have used in model driven forms.

export class TemplateFormComponent{
    person = new Person();
    firstName = "";
    lastName = "";
    message = "";
    @ViewChild('f') form: any;

    onSubmit(form:any) {
        this.message = form.firstName + " " + form.lastName;
        this.form.reset();
    }
}

To disable the button until the form gets valid,

<form #f="ngForm" (ngSubmit)="onSubmit(f.value)">
. . . . 
<button type="submit" class="btn btn-primary" [disabled]="!f.valid">Submit</button> </form

OutPut :

Angular  template driven form validation
Angular template driven form validation

Latest posts by DuttaluruVijayakumar (see all)
Like
Like Love Haha Wow Sad Angry

Subscribe
Notify of
guest
5 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Dedra Philip
February 3, 2020 3:53 pm

There are no words to show my appreciation!

Ha Sukeforth
April 9, 2020 2:26 pm

tҺe website іѕ really good, I love it!

Yuki Topolansky
April 9, 2020 6:07 pm

First time visiting your website, I love your blog!

Tinhoc 10B
April 19, 2020 3:28 pm

I have found the assistance fascinating in the article. You are certainly a wise person

Meaghan Kantrowitz
April 25, 2020 9:37 pm

First time visiting your website, I really like your web site!

5
0
Would love your thoughts, please comment.x
()
x