Template-driven forms in Angular are a way to create forms using Angular's powerful template syntax. This approach is more declarative and relies heavily on Angular's directives to bind form elements to data models.
Key Concepts
- FormsModule: To use template-driven forms, you need to import the
FormsModulein your Angular module. - ngModel Directive: This directive binds form inputs to model properties.
- Form Validation: Angular provides built-in validators and allows you to create custom validators.
- Form Submission: Handling form submission and accessing form data.
Setting Up Template-driven Forms
Step 1: Import FormsModule
First, you need to import the FormsModule in your Angular module.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, FormsModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }Step 2: Create a Form in the Template
Create a form in your component's template using Angular's template syntax.
<!-- app.component.html -->
<form #userForm="ngForm" (ngSubmit)="onSubmit(userForm)">
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name" ngModel required>
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" ngModel required email>
</div>
<button type="submit" [disabled]="userForm.invalid">Submit</button>
</form>Step 3: Handle Form Submission
In your component class, handle the form submission and access the form data.
// app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
onSubmit(form: any): void {
console.log('Form Data: ', form.value);
}
}Form Validation
Angular provides several built-in validators such as required, minlength, maxlength, email, etc. You can also create custom validators.
Built-in Validators
<!-- app.component.html -->
<form #userForm="ngForm" (ngSubmit)="onSubmit(userForm)">
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name" ngModel required minlength="3">
<div *ngIf="userForm.controls.name?.invalid && userForm.controls.name?.touched">
<small *ngIf="userForm.controls.name?.errors?.required">Name is required.</small>
<small *ngIf="userForm.controls.name?.errors?.minlength">Name must be at least 3 characters long.</small>
</div>
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" ngModel required email>
<div *ngIf="userForm.controls.email?.invalid && userForm.controls.email?.touched">
<small *ngIf="userForm.controls.email?.errors?.required">Email is required.</small>
<small *ngIf="userForm.controls.email?.errors?.email">Invalid email address.</small>
</div>
</div>
<button type="submit" [disabled]="userForm.invalid">Submit</button>
</form>Custom Validators
You can create custom validators by defining a function that returns an object if the validation fails or null if it passes.
// app.component.ts
import { Component } from '@angular/core';
import { NgModel } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
onSubmit(form: any): void {
console.log('Form Data: ', form.value);
}
validateName(control: NgModel): { [key: string]: boolean } | null {
const name = control.value;
if (name && name.length < 3) {
return { 'nameInvalid': true };
}
return null;
}
}<!-- app.component.html -->
<form #userForm="ngForm" (ngSubmit)="onSubmit(userForm)">
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name" ngModel [ngModelOptions]="{ updateOn: 'blur' }" #name="ngModel" [ngModel]="validateName(name)">
<div *ngIf="name.invalid && name.touched">
<small *ngIf="name.errors?.nameInvalid">Name must be at least 3 characters long.</small>
</div>
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" ngModel required email>
<div *ngIf="userForm.controls.email?.invalid && userForm.controls.email?.touched">
<small *ngIf="userForm.controls.email?.errors?.required">Email is required.</small>
<small *ngIf="userForm.controls.email?.errors?.email">Invalid email address.</small>
</div>
</div>
<button type="submit" [disabled]="userForm.invalid">Submit</button>
</form>Practical Exercise
Exercise 1: Create a Registration Form
Create a registration form with the following fields:
- Username (required, minimum length 5)
- Password (required, minimum length 8)
- Email (required, valid email)
Solution
<!-- registration.component.html -->
<form #registrationForm="ngForm" (ngSubmit)="onSubmit(registrationForm)">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username" ngModel required minlength="5">
<div *ngIf="registrationForm.controls.username?.invalid && registrationForm.controls.username?.touched">
<small *ngIf="registrationForm.controls.username?.errors?.required">Username is required.</small>
<small *ngIf="registrationForm.controls.username?.errors?.minlength">Username must be at least 5 characters long.</small>
</div>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password" ngModel required minlength="8">
<div *ngIf="registrationForm.controls.password?.invalid && registrationForm.controls.password?.touched">
<small *ngIf="registrationForm.controls.password?.errors?.required">Password is required.</small>
<small *ngIf="registrationForm.controls.password?.errors?.minlength">Password must be at least 8 characters long.</small>
</div>
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" ngModel required email>
<div *ngIf="registrationForm.controls.email?.invalid && registrationForm.controls.email?.touched">
<small *ngIf="registrationForm.controls.email?.errors?.required">Email is required.</small>
<small *ngIf="registrationForm.controls.email?.errors?.email">Invalid email address.</small>
</div>
</div>
<button type="submit" [disabled]="registrationForm.invalid">Register</button>
</form>// registration.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-registration',
templateUrl: './registration.component.html',
styleUrls: ['./registration.component.css']
})
export class RegistrationComponent {
onSubmit(form: any): void {
console.log('Registration Form Data: ', form.value);
}
}Summary
In this section, you learned about template-driven forms in Angular. You covered:
- Setting up template-driven forms by importing
FormsModule. - Using the
ngModeldirective to bind form inputs to model properties. - Implementing form validation using built-in and custom validators.
- Handling form submission and accessing form data.
Next, you will learn about reactive forms, which provide a more programmatic approach to form handling in Angular.
Angular 2+ Course
Module 1: Introduction to Angular
Module 2: TypeScript Basics
- Introduction to TypeScript
- TypeScript Variables and Data Types
- Functions and Arrow Functions
- Classes and Interfaces
