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
FormsModule
in 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
ngModel
directive 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