# Building a template-driven form {@a template-driven} This tutorial shows you how to create a template-driven form whose control elements are bound to data properties, with input validation to maintain data integrity and styling to improve the user experience. Template-driven forms use [two-way data binding](guide/architecture-components#data-binding "Intro to 2-way data binding") to update the data model in the component as changes are made in the template and vice versa.
Angular supports two design approaches for interactive forms. You can build forms by writing templates using Angular [template syntax and directives](guide/glossary#template "Definition of template terms") with the form-specific directives and techniques described in this tutorial, or you can use a reactive (or model-driven) approach to build forms. Template-driven forms are suitable for small or simple forms, while reactive forms are more scalable and suitable for complex forms. For a comparison of the two approaches, see [Introduction to Forms](guide/forms-overview "Overview of Angular forms.")
You can build almost any kind of form with an Angular template—login forms, contact forms, and pretty much any business form. You can lay out the controls creatively and bind them to the data in your object model. You can specify validation rules and display validation errors, conditionally enable or disable specific controls, trigger built-in visual feedback, and much more. This tutorial shows you how to build a form from scratch, using a simplified sample form like the one from the [Tour of Heroes tutorial](tutorial "Tour of Heroes") to illustrate the techniques.
Run or download the example app: .
## Objectives This tutorial teaches you how to do the following: * Build an Angular form with a component and template. * Use `ngModel` to create two-way data bindings for reading and writing input-control values. * Provide visual feedback using special CSS classes that track the state of the controls. * Display validation errors to users and enable or disable form controls based on the form status. * Share information across HTML elements using [template reference variables](guide/template-reference-variables). ## Prerequisites Before going further into template-driven forms, you should have a basic understanding of the following. * [TypeScript](https://www.typescriptlang.org/ "The TypeScript language") and HTML5 programming. * Angular app-design fundamentals, as described in [Angular Concepts](guide/architecture "Introduction to Angular concepts."). * The basics of [Angular template syntax](guide/template-syntax "Template syntax guide"). * The form-design concepts that are presented in [Introduction to Forms](guide/forms-overview "Overview of Angular forms."). {@a intro} ## Build a template-driven form Template-driven forms rely on directives defined in the `FormsModule`. * The `NgModel` directive reconciles value changes in the attached form element with changes in the data model, allowing you to respond to user input with input validation and error handling. * The `NgForm` directive creates a top-level `FormGroup` instance and binds it to a `
` element to track aggregated form value and validation status. As soon as you import `FormsModule`, this directive becomes active by default on all `` tags. You don't need to add a special selector. * The `NgModelGroup` directive creates and binds a `FormGroup` instance to a DOM element. ### The sample application The sample form in this guide is used by the *Hero Employment Agency* to maintain personal information about heroes. Every hero needs a job. This form helps the agency match the right hero with the right crisis. The form highlights some design features that make it easier to use. For instance, the two required fields have a green bar on the left to make them easy to spot. These fields have initial values, so the form is valid and the **Submit** button is enabled. As you work with this form, you will learn how to include validation logic, how to customize the presentation with standard CSS, and how to handle error conditions to ensure valid input. If the user deletes the hero name, for example, the form becomes invalid. The app detects the changed status, and displays a validation error in an attention-grabbing style. In addition, the **Submit** button is disabled, and the "required" bar to the left of the input control changes from green to red. ### Step overview In the course of this tutorial, you bind a sample form to data and handle user input using the following steps. 1. Build the basic form. * Define a sample data model. * Include required infrastructure such as the `FormsModule`. 2. Bind form controls to data properties using the `ngModel` directive and two-way data-binding syntax. * Examine how `ngModel` reports control states using CSS classes. * Name controls to make them accessible to `ngModel`. 3. Track input validity and control status using `ngModel`. * Add custom CSS to provide visual feedback on the status. * Show and hide validation-error messages. 4. Respond to a native HTML button-click event by adding to the model data. 5. Handle form submission using the [`ngSubmit`](api/forms/NgForm#properties) output property of the form. * Disable the **Submit** button until the form is valid. * After submit, swap out the finished form for different content on the page. {@a step1} ## Build the form You can recreate the sample application from the code provided here, or you can examine or download the . 1. The provided sample application creates the `Hero` class which defines the data model reflected in the form. 2. The form layout and details are defined in the `HeroFormComponent` class. The component's `selector` value of "app-hero-form" means you can drop this form in a parent template using the `` tag. 3. The following code creates a new hero instance, so that the initial form can show an example hero. This demo uses dummy data for `model` and `powers`. In a real app, you would inject a data service to get and save real data, or expose these properties as inputs and outputs. 4. The application enables the Forms feature and registers the created form component. 5. The form is displayed in the application layout defined by the root component's template. The initial template defines the layout for a form with two form groups and a submit button. The form groups correspond to two properties of the Hero data model, name and alterEgo. Each group has a label and a box for user input. * The **Name** `` control element has the HTML5 `required` attribute. * The **Alter Ego** `` control element does not because `alterEgo` is optional. The **Submit** button has some classes on it for styling. At this point, the form layout is all plain HTML5, with no bindings or directives. 6. The sample form uses some style classes from [Twitter Bootstrap](https://getbootstrap.com/css/): `container`, `form-group`, `form-control`, and `btn`. To use these styles, the app's style sheet imports the library. 7. The form makes the hero applicant choose one superpower from a fixed list of agency-approved powers. The predefined list of `powers` is part of the data model, maintained internally in `HeroFormComponent`. The Angular [NgForOf directive](api/common/NgForOf "API reference") iterates over the data values to populate the `` tag next to the **Name** label. 3. Add the `ngModel` directive, using two-way data binding syntax `[(ngModel)]="..."`.
This example has a temporary diagnostic interpolation after each input tag, `{{model.name}}`, to show the current data value of the corresponding property. The note reminds you to remove the diagnostic lines when you have finished observing the two-way data binding at work.
{@a ngForm} ### Access the overall form status When you imported the `FormsModule` in your component, Angular automatically created and attached an [NgForm](api/forms/NgForm "API reference for NgForm") directive to the `` tag in the template (because `NgForm` has the selector `form` that matches `` elements). To get access to the `NgForm` and the overall form status, declare a [template reference variable](guide/template-reference-variables). 1. Edit the template file `hero-form.component.html`. 2. Update the `` tag with a template reference variable, `#heroForm`, and set its value as follows. The `heroForm` template variable is now a reference to the `NgForm` directive instance that governs the form as a whole. 3. Run the app. 4. Start typing in the **Name** input box. As you add and delete characters, you can see them appear and disappear from the data model. For example: The diagnostic line that shows interpolated values demonstrates that values are really flowing from the input box to the model and back again. ### Naming control elements When you use `[(ngModel)]` on an element, you must define a `name` attribute for that element. Angular uses the assigned name to register the element with the `NgForm` directive attached to the parent `` element. The example added a `name` attribute to the `` element and set it to "name", which makes sense for the hero's name. Any unique value will do, but using a descriptive name is helpful. 1. Add similar `[(ngModel)]` bindings and `name` attributes to **Alter Ego** and **Hero Power**. 2. You can now remove the diagnostic messages that show interpolated values. 3. To confirm that two-way data binding works for the entire hero model, add a new binding at the top to the component's `diagnostic` property. After these revisions, the form template should look like the following: * Notice that each `` element has an `id` property. This is used by the `