In this article, I will guide you about template form. when to use template driven form.
In Real life example, when you visit hospital a paper present to you and requested to write basic info about your self. as well as in school admission form also an example. These information uploaded to software. so form is basically a paper that collect information. In technical prospective, angular provide us template driven form to collect information about the things.
Note: If your are using form in angular must import FormModule in AppModule.
When your app have basic and simple requirement for forms such as sign in, you should use template-driven forms.
Example Template Driven Form
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; //import FormsModule import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule, FormsModule //Add in Imports Array ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } <form #SingUpForm="ngForm"> //we create a variable in template.In angular it is called template reference //variable
The ngForm does the following:
They are firstName, lastname, and other fields. We need to bind them to formControl instance. We do this by using the ngModel
directive.
<input type="text" name="firstname" ngModel> <form #singUpForm="ngForm" (ngSubmit)="onSubmit(singUpForm)"> <p> <label for="firstname">First Name</label> <input type="text" name="firstname" ngModel> </p> <p> <label for="lastname">Last Name</label> <input type="text" name="lastname" ngModel> </p> <p> <label for="email">Email </label> <input type="text" id="email" name="email" ngModel> </p> <p> <label for="gender">Geneder</label> <input type="radio" value="male" name="gender" ngModel> Male <input type="radio" value="female" name="gender" ngModel> Female </p> <p> <label for="isMarried">Married</label> <input type="checkbox" name="isMarried" ngModel> </p> <select name="country" ngModel> <option [ngValue]="c.id" *ngFor="let c of countryList"> {{c.name}} </option> </select> <p> <button type="submit">Submit</button> </p> </form> import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'Template driven forms'; countryList:country[] = [ new country("1", "Pakistan"), new country('2', 'UAE'), new country('3', 'USA') ]; } export class country { id:string; name:string; constructor(id:string, name:string) { this.id=id; this.name=name; } onSubmit(contactForm) { console.log(contactForm.value); } }
The Built-in validators use the HTML5 validation attributes like required, minlength, maxlength & pattern. Angular interprets these validation attributes and add the validator functions to FormControl instance.
The required validator returns true only if the form control has non-empty value entered.
This Validator requires the control value must not have less number of characters than the value specified in the validator.
For Example, minlength validator ensures that the user name value has at least 20 characters.
<input type="text" id="userName" name="userName" required minlength="20">
This Validator requires that the number of characters must not exceed the value of the attribute.
For Example, maxlength validator ensures that the user name value has maximum value up to 20 characters.
<input type="text" id="userName" name="userName" required maxlength="20">
This Validator requires that the control value must match the regex pattern provided in the attribute. For example, the pattern ^[a-zA-Z]+$ ensures that the only letters are allowed (even spaces are not allowed). Let us apply this pattern to the username.
<input type="text" id="userName" name="username" pattern="^[a-zA-Z]+$">
This Validator requires that the control value must be a valid email address.
<input type="text" id="email" name="email" required email>
Similar to model-driven forms we can access each model form controls state by going through the top-level form group.
The ngForm directive makes the top-level FormGroup available to us via its form property, so we can show the valid, dirty or touched state of our email field like so:
<pre>Valid? {{f.form.controls.email?.valid}}</pre> <pre>Dirty? {{f.form.controls.email?.dirty}}</pre> <pre>Touched? {{f.form.controls.email?.touched}}</pre>
The ? is called the Elvis operator. only try to call the property on the right of ? if the property on the left of ? is not null. In template-driven forms the controls can sometimes be null when Angular is building the page, so to be safe we use the Elvis operator.
<pre>Valid? {{f.form.controls.email?.valid}}</pre>
<form (ngSubmit)="onSubmit()" #myForm="ngForm"> @ViewChild('myForm') form: any; onSubmit() { if (this.form.valid) { console.log("Form Submitted!"); this.form.reset(); } }
The ngModelGroup directive allows you to group together related inputs so that you structure the object represented by the form in a useful and predictable way. ngModelGroup is often used in combination with fieldset as they mostly represent the same idea of “grouping together inputs.”
import {Component, ViewChild} from "@angular/core"; @Component({ selector: 'app', template: ` <form #formRef="ngForm" (ngSubmit)="onSubmit(formRef.value)" > <fieldset ngModelGroup="login"> <input #usernameRef="ngModel" name="username" [(ngModel)]="username" type="text" required minlength="3" > <div *ngIf="usernameRef.errors?.required">This field is required</div> <div *ngIf="usernameRef.errors?.minlength">This field must be longer than {{usernameRef.errors?.minlength.requiredLength}} characters. You only typed {{usernameRef.errors?.minlength.actualLength}}</div> <input type="password" ngModel name="password"> </fieldset> <button type="submit">Submit</button> </form> {{formRef.value | json}} {{formRef.valid | json}} ` }) export class AppComponent { username = "Zeeshan"; onSubmit(formValue){ console.log(formValue); } }
{ "login": { "username": "Zeeshan", "password": "" } } true import {Component, ViewChild} from "@angular/core"; @Component({ selector: 'app', template: ` <form #formRef="ngForm" (ngSubmit)="onSubmit(formRef.value)" > <fieldset ngModelGroup="login"> <input #usernameRef="ngModel" name="username" [(ngModel)]="username" type="text" required minlength="3" > <div *ngIf="usernameRef.errors?.required">This field is required</div> <div *ngIf="usernameRef.errors?.minlength">This field must be longer than {{usernameRef.errors?.minlength.requiredLength}} characters. You only typed {{usernameRef.errors?.minlength.actualLength}}</div> <input type="password" ngModel name="password"> </fieldset> <fieldset ngModelGroup="signUp"> <input #usernameRef="ngModel" name="username" [(ngModel)]="username" type="text" required minlength="3" > <div *ngIf="usernameRef.errors?.required">This field is required</div> <div *ngIf="usernameRef.errors?.minlength">This field must be longer than {{usernameRef.errors?.minlength.requiredLength}} characters. You only typed {{usernameRef.errors?.minlength.actualLength}}</div> <input type="password" ngModel name="password"> </fieldset> <button type="submit">Submit</button> </form> {{formRef.value | json}} {{formRef.valid | json}} ` }) export class AppComponent { username = "Zeeshan"; onSubmit(formValue){ console.log(formValue); } }
{ "login": { "username": "Zeeshan", "password": "" }, "signUp": { "username": "Zeeshan", "password": "" } } true
Angular creates a FormControl for each and every field, which has ngModel directive applied. The FormControl exposes the state of form element like valid, dirty, touched, etc.
There are two ways in which you can get the reference to the FormControl.
<input type="text" id="firstname" name="firstname" required minlength="10" #firstname="ngModel">
Now, we have a reference to the firstname FormControl instance, we can check its status. We use the valid property to check if the firstname has any errors.
<div *ngIf="!firstname?.valid && (firstname?.dirty || firstname?.touched)"> Invalid First Name </div>