← Back to Chapters

Template-Driven Forms

? Template-Driven Forms

? Quick Overview

Template-driven forms in Angular allow you to create forms using HTML template syntax and Angular directives like ngModel and ngForm. These forms are simple to use, easy to set up, and best suited for smaller or less complex form scenarios.

? Key Concepts

  • Template-driven approach: Most of the form logic lives in the HTML template instead of the TypeScript class.
  • FormsModule: Must be imported in app.module.ts to use template-driven features like ngModel.
  • [(ngModel)]: Two-way data binding between form inputs and component properties.
  • ngForm directive: Applied automatically to forms and can be accessed using a template reference variable like #userForm="ngForm".
  • Validation: Uses standard HTML validation attributes such as required, minlength, etc., combined with Angular state.

? Syntax & Theory

  • Import FormsModule in your root or feature module to enable template-driven forms.
  • Use [(ngModel)] on input elements to bind them to properties in your component class.
  • Attach a template reference variable like #userForm="ngForm" to the <form> tag to access form state (valid, invalid, touched, etc.).
  • Use (ngSubmit) on the form to handle submission in the component class.
  • Template-driven forms are ideal when you want less boilerplate and do not need highly dynamic form structures.

? Code Examples

? View Code Example: app.module.ts
// app.module.ts - register FormsModule to enable template-driven forms
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],
  bootstrap: [AppComponent]
})
export class AppModule {}
? View Code Example: app.component.ts
// app.component.ts - component backing the template-driven form
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  user = { name: '', email: '' };

  submitForm() {
    console.log('Form Submitted', this.user);
  }
}
? View Code Example: app.component.html
<!-- app.component.html - template-driven form with two-way binding and validation -->
<form #userForm="ngForm" (ngSubmit)="submitForm()">
  <label>Name:</label>
  <input
    type="text"
    name="name"
    [(ngModel)]="user.name"
    required
  >
  <br><br>

  <label>Email:</label>
  <input
    type="email"
    name="email"
    [(ngModel)]="user.email"
    required
  >
  <br><br>

  <button type="submit" [disabled]="!userForm.form.valid">
    Submit
  </button>
</form>

? Live Output & Explanation

In the template-driven form above:

  • [(ngModel)]="user.name" and [(ngModel)]="user.email" create two-way data binding between the input fields and the user object in the component.
  • #userForm="ngForm" creates a local reference to the form’s Angular NgForm instance, letting you access properties like userForm.form.valid.
  • The submit button is disabled until the form is valid using [disabled]="!userForm.form.valid", ensuring users cannot submit incomplete data.
  • When the form is submitted, submitForm() runs and logs the user object to the console.

?️ Example Console Output

After entering a valid name and email and clicking Submit, the browser console might show:

// Output shown in the browser console when form is submitted
Form Submitted { name: 'Alex', email: 'alex@example.com' }

✅ Tips & Best Practices

  • Use template-driven forms for simple forms with fewer fields and straightforward validation.
  • Always import FormsModule in the module where you want to use [(ngModel)].
  • Make sure each input using ngModel also has a name attribute so Angular can track its state.
  • Use built-in HTML validators like required, minlength, and type="email" to enforce validation rules.
  • For more complex, dynamic, or large forms, prefer reactive forms for better scalability and control.

? Try It Yourself

  • Create a contact form with name, email, and message fields using template-driven forms.
  • Add validation so that the email must be in a valid format and the message has a minimum length (for example, 10 characters).
  • Display the current form data live below the form using property binding, updating as the user types.
  • Show a success message (e.g., “Thank you for contacting us!”) when the form is submitted and valid.