Unit 3 Angular Template Driven Forms and Reactive Forms
Unit 3 Angular Template Driven Forms and Reactive Forms
DIRECTIVES DETAILS
Reconciles value changes in the attached form element with changes in
NgModel the data model, allowing you to respond to user input with input
validation and error handling.
Creates a top-level FormGroup instance and binds it to a <form>
element to track aggregated form value and validation status. As soon
NgForm
as you import FormsModule, this directive becomes active by default
on all <form> tags. You don't need to add a special selector.
NgModelGroup Creates and binds a FormGroup instance to a DOM element.
Reconciles value changes in the attached form element with changes in
NgModel the data model, allowing you to respond to user input with input
validation and error handling.
Step overview
A sample form to data and handle user input using the following steps.
1) Build the basic form.
o Define a sample data model
o Include required infrastructure such as the FormsModule
2) Bind form controls to data properties using the ngModel directive and two-way data-binding
syntax.
o Examine how ngModel reports control states using CSS classes
o Name controls to make them accessible to ngModel
3) Track input validity and control status using ngModel.
o Add custom CSS to provide visual feedback on the status
BINDINGS DETAILS
1) Property binding
Property binding in Angular helps you set values for properties of HTML elements or directives. Use
property binding to do things such as toggle button features, set paths programmatically, and share
values between components.
a) Binding to a property
To bind to an element's property, enclose it in square brackets, [], which identifies the property as a
target property.
A target property is the DOM property to which you want to assign a value.
To assign a value to a target property for the image element's src property, type the following code:
src/app/app.component.html
In most cases, the target name is the name of a property, even when it appears to be the name of an
attribute.
In this example, src is the name of the <img> element property.
The brackets, [], cause Angular to evaluate the right-hand side of the assignment as a dynamic
expression.
Without the brackets, Angular treats the right-hand side as a string literal and sets the property to that
static value.
To assign a string to a property, type the following code: src/app/app.component.html
<app-item-detail childItem="parentItem"></app-item-detail>
b) Setting an element property to a component property value
To bind the src property of an <img> element to a component's property, place src in square brackets
followed by an equal sign and then the property.
Using the property itemImageUrl, type the following code:
src/app/app.component.html
content_copy<img alt="item" [src]="itemImageUrl">
Declare the itemImageUrl property in the class, in this case AppComponent.
src/app/app.component.ts
content_copyitemImageUrl = '../assets/phone.svg';
ColSpan and colSpan
A common point of confusion is between the attribute, colspan, and the property, colSpan. Notice that
these two names differ by only a single letter.
To use property binding using colSpan, type the following:
src/app/app.component.html
content_copy<!-- Notice the colSpan property is camel case -->
<tr><td [colSpan]="1 + 1">Three-Four</td></tr>
To disable a button while the component's isUnchanged property is true, type the following:
src/app/app.component.html
content_copy<!-- Bind button disabled state to `isUnchanged` property -->
<button type="button" [disabled]="isUnchanged">Disabled Button</button>
To set a property of a directive, type the following:
src/app/app.component.html
content_copy<p [ngClass]="classes">[ngClass]
binding to the classes property making this blue</p>
To set the model property of a custom component for parent and child components to communicate with
each other, type the following:
src/app/app.component.html
content_copy<app-item-detail [childItem]="parentItem"></app-item-detail>
To use a Boolean value to disable a button's features, bind the disabled DOM attribute to a Boolean
property in the class.
Prepared By: Department of Computer Engineering Page 3
Subject Name: Modern Practical Tools Unit No: III Subject Code: 4340705
src/app/app.component.html
content_copy<!-- Bind button disabled state to `isUnchanged` property -->
<button type="button" [disabled]="isUnchanged">Disabled Button</button>
Because the value of the property isUnchanged is true in the AppComponent, Angular disables the
button.
src/app/app.component.ts
content_copyisUnchanged = true;
2) Event binding
Event binding lets you listen for and respond to user actions such as keystrokes, mouse movements,
clicks, and touches.
Binding to events
To bind to an event you use the Angular event binding syntax. This syntax consists of a target event
name within parentheses to the left of an equal sign, and a quoted template statement to the right.
Create the following example; the target event name is click and the template statement is onSave().
Event binding syntax: content_copy<button (click)="onSave()">Save</button>
The event binding listens for the button's click events and calls the component's onSave() method
whenever a click occurs.
To determine an event target, Angular checks if the name of the target event matches an event property
of a known directive.
Create the following example: (Angular checks to see if myClick is an event on the
custom ClickDirective)
src/app/app.component.html
content_copy<h4>myClick is an event on the custom ClickDirective:</h4>
<button type="button" (myClick)="clickMessage=$event" clickable>click with myClick</button>
{{clickMessage}}
If the target event name, myClick fails to match an output property of ClickDirective, Angular will
instead bind to the myClick event on the underlying DOM element.
3. In the src/polyfills.ts file, before importing zone.js, import the newly created zone-flags.
4. content_copyimport './zone-flags';
After those steps, if you add event listeners for the scroll event, the listeners will be passive.
3.4 NgModel
The ngmodel directive binds the value of HTML controls (input, select, textarea) to application data.
With the ng-model directive you can bind the value of an input field to a variable created in Angular.
The binding goes both ways. If the user changes the value inside the input field, the Angular property
will also change its value.
The ngmodel directive is not part of the Angular Core library. It is part of the FormsModule library.
You need to import the FormsModule package into your Angular module.
If you want to create a form in angular app then you need to import FormsModule from @angular/forms
library. so let's add following code to app.module.ts file.
In app.module.ts: import { FormsModule } from '@angular/forms';
We will write code of HTML form with ngModel. so add following code to app.component.html file.
In app.component.html:
<input [(ngModel)]="CopyText">
<strong>{{CopyText}}</strong>
<input type="text” value="{{CopyText}}">
The square indicates the Property binding [ ] & parentheses indicates the event binding ( ). The above
syntax sets up both property & event binding.
The two way data binding is nothing but both property binding & event binding applied together.
Property Binding is one way from view to component. The event binding is one way from component to
view. The value that is declared for ngmodule is displayed using string interpolation {{ }}.
This two-way binding with [()] syntax is also known as 'banana-in-a-box syntax'.
In event binding we use (input) event to bind the data to it like (input)="name=$event.target.value" also
known as event binding.We combine both event and property binding in this ngmodel.
<div *ngIf="name.errors?.['required']">
Name is required.
</div>
<div *ngIf="name.errors?.['minlength']">
Name must be at least 4 characters long.
</div>
<div *ngIf="name.errors?.['forbiddenName']">
Name cannot be Bob.
</div>
</div>
When instantiating a FormGroup, pass in a collection of child controls as the first argument. The key for
each child registers the name for the control.
FormGroup is intended for use cases where the keys are known ahead of time. If you need to
dynamically add and remove controls, use FormRecord instead.
FormGroup accepts an optional type parameter TControl, which is an object type with inner control
types as values.
Constructor
Creates a new FormGroup instance.
This class is "final" and should not be extended.
constructor(controls: TControl, validatorOrOpts?: ValidatorFn | AbstractControlOptions | ValidatorFn[],
asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[])
3.8 Using Reactive Forms: Form Controls, Form Groups, Form Builders
Form Controls
There are three steps to using form controls.
1. Register the reactive forms module in your application. This module declares the reactive-form
directives that you need to use reactive forms.
2. Generate a new component and instantiate a new FormControl.
3. Register the FormControl in the template.
You can then display the form by adding the component to the template.
Form Groups
Forms typically contain several related controls. Reactive forms provide two ways of grouping multiple
related controls into a single input form.
Just as a form control instance gives you control over a single input field, a form group instance tracks
the form state of a group of form control instances (for example, a form).
Each control in a form group instance is tracked by name when creating the form group. The following
example shows how to manage multiple form control instances in a single group
Form Builders
Creating form control instances manually can become repetitive when dealing with multiple forms.
The FormBuilder service provides convenient methods for generating controls.
Use the following steps to take advantage of this service.
1. Import the FormBuilder class.
2. Inject the FormBuilder service.
3. Generate the form contents.
Control State
Control state is centered around three pairs of state:
o Pristine vs. Dirty
o Touched vs. Untouched
o Valid vs. Invalid
Each form control and the form itself is assigned one value from each pair of states depending on the
control. By default, all controls and pristine and untouched. They become touched when they gain and
lose focus, they become dirty when their values are changed.
All controls are valid or invalid based on the value of the control in concert with any validation rules
applied to the control.
Validity
To add validation to a template-driven form, you add the same validation attributes as you would
with native HTML form validation. Angular uses directives to match these attributes with validator
functions in the framework.
Every time the value of a form control changes, Angular runs validation and generates either a list of
validation errors that results in an INVALID status, or null, which results in a VALID status.
You can then inspect the control's state by exporting ngModel to a local template variable.
Error Messages
ngMessages is a directive that is designed to show and hide messages based on the state of a key/value
object that it listens on. The directive itself complements error message reporting with
the ngModel $error object (which stores a key/value state of validation errors).
ngMessages manages the state of internal messages within its container element. The internal messages
use the ngMessage directive and will be inserted/removed from the page depending on if they're present
within the key/value object. By default, only one message will be displayed at a time and this depends
on the prioritization of the messages within the template. (This can be changed by using the ng-
messages-multiple or multiple attribute on the directive container.)
A remote template can also be used (With ngMessagesInclude) to promote message reusability and
messages can also be overridden.
A default message can also be displayed when no ngMessage directive is inserted, using
the ngMessageDefault directive.
Parameter:
Properties
Property Description