@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 We’ve all used a form to log in, submit a help request, place an order, book a flight, schedule a meeting, and perform countless other data entry tasks. Forms are the mainstay of business applications. Any seasoned web developer can slap together an HTML form with all the right tags. It's more challenging to create a cohesive data entry experience that guides the user efficiently and effectively through the workflow behind the form. *That* takes design skills that are, to be frank, well out of scope for this guide. It also takes framework support for **two-way data binding, change tracking, validation, and error handling** ... which we shall cover in this guide on Angular forms. We will build a simple form from scratch, one step at a time. Along the way we'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 Run the . ## Template-driven forms Many of us will build forms by writing templates in the Angular [template syntax](./template-syntax.html) with the form-specific directives and techniques described in this guide. That's not the only way to create a form but it's the way we'll cover in this guide.We can build almost any form we need with an Angular template — login forms, contact forms, pretty much any business form. We 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. It will be pretty easy because Angular handles many of the repetitive, boilerplate tasks we'd otherwise wrestle with ourselves. We'll discuss and learn to build a template-driven form that looks like this:
Clean Form
Here at the *Hero Employment Agency* we use this form to maintain personal information about heroes. Every hero needs a job. It's our 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 we 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 changed from green to red. We'll customize the colors and location of the "required" bar with standard CSS. We'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](setup.html) instructions for creating a new project named angular-forms. ## Create the Hero model class As users enter form data, we'll capture their changes and update an instance of a model. We can't lay out the form until we 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 our `Hero` class with its three required fields (`id`, `name`, `power`) and one optional field (`alterEgo`). In the `!{_appDir}` directory, create the following file with the given content: {@example 'forms/ts/src/app/hero.ts'} It's an anemic model with few requirements and no behavior. Perfect for our demo. The TypeScript compiler generates a public field for each `public` constructor parameter and assigns the parameter’s value to that field automatically when we create new heroes. The `alterEgo` is optional, so the constructor lets us omit it; note the (?) in `alterEgo?`. We 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. We 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 we've written before. Understanding this component requires only the Angular concepts covered in previous guides. 1. The code imports the Angular core library, and the `Hero` model we just created. 1. The `@Component` selector value of "hero-form" means we can drop this form in a parent template with a `` tag. 1. The `moduleId: module.id` property sets the base for module-relative loading of the `templateUrl`. 1. The `templateUrl` property points to a separate file for the template HTML. 1. We defined dummy data for `model` and `powers`, as befits a demo. Down the road, we can inject a data service to get and save real data or perhaps expose these properties as [inputs and outputs](./template-syntax.html#inputs-outputs) for binding to a parent component. None of this concerns us now and these future changes won't affect our form. 1. We threw in a `diagnostic` property to return a JSON representation of our model. It'll help us see what we're doing during our development; we've left ourselves a cleanup note to discard it later. ### Why the separate template file? Why don't we write the template inline in the component file as we often do elsewhere? There is no “right” answer for all occasions. We like inline templates when they are short. Most form templates won't be short. TypeScript and JavaScript files generally aren't the best place to write (or read) large stretches of HTML and few editors are much help with files that have a mix of HTML and code. We also like short files with a clear and obvious purpose like this one. Form templates tend to be quite large even when displaying a small number of fields so it's usually best to put the HTML template in a separate file. We'll write that template file in a moment. Before we do, we'll take a step back and 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 we identify the external modules we'll use in our application and declare the components that belong to this module, such as our `HeroFormComponent`. Because template-driven forms are in their own module, we need to add the `FormsModule` to the array of `imports` for our application module before we can use forms. Replace the contents of the "QuickStart" version with the following: {@example 'forms/ts/src/app/app.module.ts'} There are three changes: 1. We import `FormsModule` and our new `HeroFormComponent`. 1. We add the `FormsModule` to the list of `imports` defined in the `ngModule` decorator. This gives our application access to all of the template-driven forms features, including `ngModel`. 1. We add the `HeroFormComponent` to the list of `declarations` defined in the `ngModule` decorator. This makes the `HeroFormComponent` component visible throughout this module. ~~~ {.alert.is-important} 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 our new `HeroFormComponent`. Replace the contents of the "QuickStart" version with the following: {@example 'forms/ts/src/app/app.component.ts'} There are only two changes. The `template` is simply the new element tag identified by the component's `selector` property. This will display the hero form when the application component is loaded. We've also dropped the `name` field from the class body. ## Create an initial HTML form template Create the new template file with the following contents: {@example 'forms/ts/src/app/hero-form.component.html' region='start'} That is plain old HTML 5. We'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. We've got a *Submit* button at the bottom with some classes on it for styling. **We are not using Angular yet**. There are no bindings, no extra directives, just layout. The `container`, `form-group`, `form-control`, and `btn` classes come from [Twitter Bootstrap](http://getbootstrap.com/css/). Purely cosmetic. We're using Bootstrap to give the form a little style! ~~~ {.callout.is-important}
Angular forms do not 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. ~~~ Let's add the stylesheet. Open `index.html` and add the following link to the ``: ## Add powers with _*ngFor_ Our hero must choose one super power from a fixed list of Agency-approved powers. We maintain that list internally (in `HeroFormComponent`). We'll add a `select` to our form and bind the options to the `powers` list using `ngFor`, a technique seen previously in the [Displaying Data](./displaying-data.html) guide. Add the following HTML *immediately below* the *Alter Ego* group: This code repeats the `