@title Forms @intro A form creates a cohesive, effective, and compelling data entry experience. An Angular form coordinates a set of data-bound user controls, tracks changes, validates input, and presents errors. @description Forms are the mainstay of business applications. You use forms to log in, submit a help request, place an order, book a flight, schedule a meeting, and perform countless other data-entry tasks. In developing a form, it's important to create a data-entry experience that guides the user efficiently and effectively through the workflow. Developing forms requires design skills (which are out of scope for this page), as well as framework support for *two-way data binding, change tracking, validation, and error handling*, which you'll learn about on this page. This page shows you how to build a simple form from scratch. Along the way you'll learn how to: * Build an Angular form with a component and template. * Use `ngModel` to create two-way data bindings for reading and writing input-control values. * Track state changes and the validity of form controls. * Provide visual feedback using special CSS classes that track the state of the controls. * Display validation errors to users and enable/disable form controls. * Share information across HTML elements using template reference variables. You can run the in Plunker and download the code from there. ## Template-driven forms You can build forms by writing templates in the Angular [template syntax](guide/template-syntax) with the form-specific directives and techniques described in this page.
You can also use a reactive (or model-driven) approach to build forms. However, this page focuses on template-driven forms.
You can build almost any form with an Angular template—login forms, contact forms, and pretty much any business form. You can lay out the controls creatively, bind them to data, specify validation rules and display validation errors, conditionally enable or disable specific controls, trigger built-in visual feedback, and much more. Angular makes the process easy by handling many of the repetitive, boilerplate tasks you'd otherwise wrestle with yourself. You'll learn to build a template-driven form that looks like this:
Clean Form
The *Hero Employment Agency* uses this form to maintain personal information about heroes. Every hero needs a job. It's the company mission to match the right hero with the right crisis. Two of the three fields on this form are required. Required fields have a green bar on the left to make them easy to spot. If you delete the hero name, the form displays a validation error in an attention-grabbing style:
Invalid, Name Required
Note that the *Submit* button is disabled, and the "required" bar to the left of the input control changes from green to red.
You can customize the colors and location of the "required" bar with standard CSS.
You'll build this form in small steps: 1. Create the `Hero` model class. 1. Create the component that controls the form. 1. Create a template with the initial form layout. 1. Bind data properties to each form control using the `ngModel` two-way data-binding syntax. 1. Add a `name` attribute to each form-input control. 1. Add custom CSS to provide visual feedback. 1. Show and hide validation-error messages. 1. Handle form submission with *ngSubmit*. 1. Disable the form’s *Submit* button until the form is valid. ## Setup Follow the [setup](guide/setup) instructions for creating a new project named angular-forms. ## Create the Hero model class As users enter form data, you'll capture their changes and update an instance of a model. You can't lay out the form until you know what the model looks like. A model can be as simple as a "property bag" that holds facts about a thing of application importance. That describes well the `Hero` class with its three required fields (`id`, `name`, `power`) and one optional field (`alterEgo`). In the `app` directory, create the following file with the given content: It's an anemic model with few requirements and no behavior. Perfect for the demo. The TypeScript compiler generates a public field for each `public` constructor parameter and automatically assigns the parameter’s value to that field when you create heroes. The `alterEgo` is optional, so the constructor lets you omit it; note the question mark (?) in `alterEgo?`. You can create a new hero like this: ## Create a form component An Angular form has two parts: an HTML-based _template_ and a component _class_ to handle data and user interactions programmatically. Begin with the class because it states, in brief, what the hero editor can do. Create the following file with the given content: There’s nothing special about this component, nothing form-specific, nothing to distinguish it from any component you've written before. Understanding this component requires only the Angular concepts covered in previous pages. * The code imports the Angular core library and the `Hero` model you just created. * The `@Component` selector value of "hero-form" means you can drop this form in a parent template with a `` tag. * The `templateUrl` property points to a separate file for the template HTML. * You defined dummy data for `model` and `powers`, as befits a demo. Down the road, you can inject a data service to get and save real data or perhaps expose these properties as inputs and outputs (see [Input and output properties](guide/template-syntax#inputs-outputs) on the [Template Syntax](guide/template-syntax) page) for binding to a parent component. This is not a concern now and these future changes won't affect the form. * You added a `diagnostic` property to return a JSON representation of the model. It'll help you see what you're doing during development; you've left yourself a cleanup note to discard it later. ### Why the separate template file? Why don't you write the template inline in the component file as you often do elsewhere? There is no "right" answer for all occasions. Inline templates are useful when they are short. Most form templates aren't short. TypeScript and JavaScript files generally aren't the best place to write (or read) large stretches of HTML, and few editors help with files that have a mix of HTML and code. Form templates tend to be large, even when displaying a small number of fields, so it's usually best to put the HTML template in a separate file. You'll write that template file in a moment. First, revise the `app.module.ts` and `app.component.ts` to make use of the new `HeroFormComponent`. ## Revise *app.module.ts* `app.module.ts` defines the application's root module. In it you identify the external modules you'll use in the application and declare the components that belong to this module, such as the `HeroFormComponent`. Because template-driven forms are in their own module, you need to add the `FormsModule` to the array of `imports` for the application module before you can use forms. Replace the contents of the "QuickStart" version with the following:
There are three changes: 1. You import `FormsModule` and the new `HeroFormComponent`. 1. You add the `FormsModule` to the list of `imports` defined in the `ngModule` decorator. This gives the application access to all of the template-driven forms features, including `ngModel`. 1. You add the `HeroFormComponent` to the list of `declarations` defined in the `ngModule` decorator. This makes the `HeroFormComponent` component visible throughout this module.
If a component, directive, or pipe belongs to a module in the `imports` array, ​_don't_​ re-declare it in the `declarations` array. If you wrote it and it should belong to this module, ​_do_​ declare it in the `declarations` array.
## Revise *app.component.ts* `AppComponent` is the application's root component. It will host the new `HeroFormComponent`. Replace the contents of the "QuickStart" version with the following:
There are only two changes. The `template` is simply the new element tag identified by the component's `selector` property. This displays the hero form when the application component is loaded. You've also dropped the `name` field from the class body.
## Create an initial HTML form template Create the template file with the following contents: The language is simply HTML5. You're presenting two of the `Hero` fields, `name` and `alterEgo`, and opening them up for user input in input boxes. The *Name* `` control has the HTML5 `required` attribute; the *Alter Ego* `` control does not because `alterEgo` is optional. You added a *Submit* button at the bottom with some classes on it for styling. *You're not using Angular yet*. There are no bindings or extra directives, just layout.
In template driven forms, if you've imported `FormsModule`, you don't have to do anything to the `
` tag in order to make use of `FormsModule`. Continue on to see how this works.
The `container`, `form-group`, `form-control`, and `btn` classes come from [Twitter Bootstrap](http://getbootstrap.com/css/). These classes are purely cosmetic. Bootstrap gives the form a little style.
Angular forms don't require a style library
Angular makes no use of the `container`, `form-group`, `form-control`, and `btn` classes or the styles of any external library. Angular apps can use any CSS library or none at all.
To add the stylesheet, open `index.html` and add the following link to the ``: ## Add powers with _*ngFor_ The hero must choose one superpower from a fixed list of agency-approved powers. You maintain that list internally (in `HeroFormComponent`). You'll add a `select` to the form and bind the options to the `powers` list using `ngFor`, a technique seen previously in the [Displaying Data](guide/displaying-data) page. Add the following HTML *immediately below* the *Alter Ego* group: This code repeats the `