Template-Driven Forms

Handling forms in vanilla JavaScript is incredibly tedious. You have to query the DOM, attach listeners to every input, handle validation states, and extract the values manually. Angular provides two radically different approaches to form handling: Template-Driven and Reactive.

What is a Template-Driven Form?

As the name implies, the majority of the form logic (validations, state tracking) is defined directly inside the HTML Template. Under the hood, Angular uses the FormsModule and heavily relies on the [(ngModel)] directive.

Importing the FormsModule

Before you can use ngModel, you must import the FormsModule into your component (or module).

import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms'; // <--- Import here!

@Component({
  selector: 'app-login',
  standalone: true,
  imports: [FormsModule], // <--- Add to imports array!
  templateUrl: './login.component.html'
})
export class LoginComponent { ... }

Building the Form (HTML)

You build a standard HTML form, but give it a specific Angular template reference variable (e.g. #f="ngForm"). Each input must have a name attribute and the ngModel directive to register it with Angular.

<!-- HTML View -->
<form (ngSubmit)="onSubmit(loginForm)" #loginForm="ngForm">
  
  <div>
    <label>Email:</label>
    <!-- Use ngModel to register the input -->
    <input type="email" name="email" ngModel required email>
  </div>

  <div>
    <label>Password:</label>
    <input type="password" name="password" ngModel required minlength="6">
  </div>

  <!-- Disable the button if the overall form is invalid! -->
  <button type="submit" [disabled]="!loginForm.valid">Login</button>

</form>

Handling the Submission (TypeScript)

When the user clicks submit, the (ngSubmit) event fires, passing the entire Form object to our class.

// .ts class
import { NgForm } from '@angular/forms';

export class LoginComponent {
  onSubmit(form: NgForm) {
    console.log("Form Submitted!", form.value);
    // form.value outputs: { email: 'test@test.com', password: 'secretpassword' }
    
    // Reset the form back to pristine state
    form.reset(); 
  }
}

Validation States

Angular automatically attaches CSS classes (like ng-valid, ng-invalid, ng-touched, ng-dirty) to your input fields as the user types. You can use these classes to easily highlight invalid boxes with red borders in your CSS.

When to use Template-Driven Forms?

Template-driven forms are excellent for simple, static forms (like a basic Login or Contact Us page). However, for massively complex, dynamic enterprise forms (like a tax return system), you should strictly use Reactive Forms, which we will cover next.