Angular Template Driven Forms example

Template driven Forms in Angular is one of the two ways of building forms in Angular. In this tutorial, we will learn how to build a simple Template-driven Form. First, we build a simple HTML form using a few form elements. Then use the ngForm directive to convert them to Template-driven Form, which creates the top-level FormGroup control. Next, we use the ngModel directive to create the FormControl instance for each of the HTML form elements. Later, we will learn how to submit the form data to the component class. We will also learn how to initialize or reset the form data and use the data binding to access the data in the component class.

If you have not gone through our Angular Forms Tutorial, we strongly recommend you to do so. In that article. we have covered fundamental concepts of the Angular Forms Module.

What is Template-driven form?

In Template Driven Forms we specify behaviors/validations using directives and attributes in our template and let it work behind the scenes. All things happen in Templates hence very little code is required in the component class. This is different from the reactive forms, where we define the logic and controls in the component class.

The Template-driven forms 

  1. The form is set up using ngForm directive
  2. controls are set up using the ngModel directive
  3. ngModel also provides the two-way data binding
  4. The Validations are configured in the template via directives

Template-driven forms are

  1. Contains little code in the component class 
  2. Easier to set up 

While they are

  1. Difficult to add controls dynamically
  2. Unit testing is a challenge

Create the Example Application

Use ng new to create a new application.

Run ng serve and verify if everything is installed correctly.

Import FormsModule

To work with Template-driven forms, we must import the FormsModule. The FormsModule contains all the form directives and constructs for working with forms.

How we import FormsModule depends on whether our Component is Standalone Component or Module Based Component. If you created the application in Angular 17 or above then it defaults to Standalone component else it will be using the Module based Component.

Standalone Components

If you are using Standalone component, then open the app.component.ts and import the FormsModule. In a Standalone Component you will see the standalone: true, flag in the component decorator. If not then it is a module based component.

Add the FormsModule to imports metadata of component decorator as shown below

Module Based Components

If you are using the module based component, then we usually import the FormsModule in root module or in a shared module. (You can also import it in the ngModule to which component belongs).

Open the app.module.ts and add the following import.

Next, add the FormsModule to the imports metadata property array

HTML Form

The first task is to build the template. The following is a regular HTML form. We enclose it in a <form> tag. We have included two text input (firstName & lastName), a email (email), a radio button (gender), a checkbox (isMarried), and a select options list (country). These are form elements.

Component Class (Standalone component)

We have exported a class Country. countryList is an array of Country, which we used in the country dropdown.

This is a standalone component. For Module based component remove the statements imports: [CommonModule, FormsModule] & standalone: true . Rest of the code is same for both.

ngForm

Once, we have a form with few form elements, the angular automatically converts it into a Template-driven form. This is done by the ngForm directive.

The ngForm directive is what makes the Angular template-driven forms work. But we do not need to do anything explicitly.

When we include FormsModule, the Angular is going to look out for any <form> tag in our HTML template. The ngForm directive automatically detects the <form> tag and automatically binds to it. You do not have to do anything on your part to invoke and bind the ngForm directive.

The ngForm does the following

  1. Binds itself to the <Form> directive
  2. Creates a top-level FormGroup instance
  3. Creates FormControl instance for each of child control, which has ngModel directive.
  4. Creates FormGroup instance for each of the  NgModelGroup directive.

We can export the ngForm instance into a local template variable using ngForm as the key (ex: #contactForm="ngForm"). This allows us to access the many properties and methods of ngForm using the template variable contactForm

Hence, update the form element as shown below.

FormControl

The FormControl is the basic building block of the Angular Forms. It represents a single input field in an Angular form. The Angular Forms Module binds the input element to a FormControl. We use the FormControl instance to track the value, user interaction and validation status of an individual form element. Each individual Form element is a FormControl.

We have six form elements in our HTML template. They are firstName, lastname, email, gender, isMarried & country. We need to bind them to FormControl instance. We do this by using the ngModel directive. Add the ngModel directive to every control as shown below.

ngModel will use the name attribute to create the FormControl instance for each of the Form field it is attached.

Submitting the Form

Now have the template ready, except for the final piece i.e. submitting data to the component.

We use the ngSubmit event, to submit the form data to the component class. We use the event binding (parentheses) to bind ngSubmit to OnSubmit method in the component class. When the user clicks on the submit button, the ngSubmit event will fire.

We are passing the local template variable contactForm in onSubmit method. contactForm holds the reference to the ngForm directive. We can use this in our component class to extract the data from the form fields.

Final Template

Our final template is as shown below.

Receiving the form data in Component

We need to receive the data in component class from our form. To do this we need to create the onSubmit method in our component class. The submit method receives the reference to the ngForm directive, which we named is as contactForm. The contactForm exposes the value method which returns the form fields as a Json object.

You can print the value to the console using the console.log(contactForm.value)

Run the code now and enter some data into the form. Open the Developer Console in your browser and check the output, when you submit the data.

Angular template driven forms
Angular template-driven forms in Action

Local Variable

We can assign the ngForm, FormControl or FormGroup instance to a template local variable. This allows us to check the status of the form like whether the form is valid, submitted, and value of the form elements, etc

ngForm

We have access to the ngForm instance via the local template variable #contactForm.

Now, we can make use of some of the properties & methods to know the status of form. For Example

value: The value property returns the object containing the value of every FormControl
valid: Returns true if the form is Valid else returns false.
touched: True if the user has entered a value in at least in one field.
submitted: Returns true if the form is submitted. else false.

FormControl

Similarly, we can also get access to the FormControl instance by assigning the ngModel to a local variable as shown below

Now, the variable #fname holds the reference to the firstname FormControl. We can then access the properties of FormControl like value, valid, isvalid, tocuhed etc

value: Returns the current value of the control
valid: Returns true if the value is Valid else false
invalid: True if the value is invalid else false
touched: Returns true if the value is entered in the element

Nested FormGroup

The FormGroup is a collection of FormControl. It can also contain other FormGroup's.

The ngForm directive creates the top Level FormGroup behind the scene, when we use the <Form> directive.

We can add new FormGroup using the ngModelGroup directive. Let us add street, city & Pincode form controls and group them under the address FormGroup

All you need to do is to enclose the fields inside a div element with ngModelGroup directive applied on it as shown below

Run the App and submit. The resultant object is as shown below.

Setting the Initial Value

The form is usually pre-filled with some default data. In the case of editing, we have to show the user the current data. You can refer to the next tutorial on How to set value in the template-driven form.

Validating the Form

Validating the form is another important task. We have covered it in Validation in template-driven form tutorial.

Summary

Angular Template-driven Forms is simpler compared to the reactive forms. The FormsModule is imported first either in the component (in case of standalone components) or in the ngModule. Then we create the HTML form. The Angular detects the <form> tag and converts the form to the Angular Form. ngModel directive added to each form element, which converts them to FormControl. To create a nested Form, use the ngModelGroup directive. Finally, submit event is subscribed via event binding.

Validating and displaying error messages are equally important. We have covered it in a separate tutorial. The following is the list of tutorials on Angular Template Driven forms

  1. Angular Forms Tutorial: Fundamental & Concepts
  2. Set Value in Template Driven forms in Angular
  3. Select Options Dropdown
  4. Validation in Template-Driven Forms
  5. Custom Validator in Template-Driven Forms

10 thoughts on “Angular Template Driven Forms example”

  1. What about the final TypeScript file? It keeps on saying contactForm is undefined even when I try to define my version of it

  2. First version of app.component.html has an error:

    country

    {{c.name}}

    ————>>>> this should be a closing tag

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top