Angular Template-driven Forms
▌Introduction
We will practice Template-driven Forms which contains textbox, radio buttons, checkbox and drop-down list.
▌Environment
▋Angular 2.4.0
▋Angular CLI
1.0.0-beta.31
▌Implement
The expected layout should be looked like this.
We will create each Html element one by one.
▋Form
<form novalidate #form="ngForm" (ngSubmit)="onSubmit(form)">
</form>
u novalidate :Disable the validation
when the form is submit.
u Set a
variable syntax #form to ngForm,
so that we can use ngForm in the template.
u Set event
binding (ngSubmit) and reference to function onSubmit with parameter form
=> ngForm
▋Radio Buttons
▋ HTML
<div class="form-horizontal">
<div class="form-group required">
<label class="control-label col-md-2">State</label>
<div class="col-md-3">
<input type="radio" value="enabled" name="status" #status="ngModel" [(ngModel)]="defaultStatus"> Enable
<input type="radio" value="disabled" name="status" #status="ngModel" [(ngModel)]="defaultStatus"> Disable
</div>
</div>
</div>
u name is a must!
u Set the value for the checkboxes
u Set variable syntax #status to ngModel
for later usage.
u If we DO NOT need to set the default checked/unchecked, then just put
ngModel to the element like this,
<input type="radio" value="disabled" name="status" #status="ngModel" ngModel/>
<input type="radio" value="disabled" name="status" #status="ngModel" ngModel/>
But in this sample, we would like to set the default checked/unchecked
value to them, so we use the two-way binding to ngModel.
▋ Component
import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
@Component({
selector: 'app-account-create',
templateUrl: './account-create.component.html'
})
export class AccountCreateComponent implements OnInit {
private defaultStatus: string;
ngOnInit() {
this.defaultStatus = "enabled";
}
//Sdubmit
private onSubmit(form: NgForm) {
}
}
TIP :
We can use <pre>{{form.value | json}}</pre> to make sure that the ngForm has
the correct data.
▋Textbox
<div class="form-horizontal">
<div class="form-group required">
<label class="control-label col-md-2">ID</label>
<div class="col-md-3" [ngClass]="{'has-error': id.invalid && id.dirty}">
<input type="text" class="form-control" required name="id" #id="ngModel" ngModel /
</div>
</div>
</div>
ID is a
required input, so we add required on the element and use #id (NgModel) to check
invalid
and dirty
value and set the ngClass.
Here are some
useful properties of NgModel.
<pre>dirty : {{id.dirty}}</pre>
<pre>disabled : {{id.disabled}}</pre>
<pre>enabled : {{id.enabled}}</pre>
<pre>errors : {{id.errors | json}}</pre>
<pre>invalid : {{id.invalid}}</pre>
<pre>name : {{id.name}}</pre>
<pre>pristine : {{id.pristine}}</pre>
<pre>touched : {{id.touched}}</pre>
<pre>untouched : {{id.untouched}}</pre>
<pre>valid : {{id.valid}}</pre>
<pre>value : {{id.value}}</pre>
▋Textbox with complicated validation
We will
validate that the “Password” and “Confirm Password” should be the same, or show
an alert message.
<div class="form-group required">
<label class="control-label col-md-2">Password</label>
<div class="col-md-3" [ngClass]="{'has-error': password.invalid && password.dirty}">
<input type="password" class="form-control" required name="password" #password="ngModel" ngModel />
<span class="label label-danger" *ngIf="password.dirty && password.value!=confirmPassword.value">Password not match!</span>
</div>
</div>
<div class="form-group required">
<label class="control-label col-md-2">Confirm Password</label>
<div class="col-md-3" [ngClass]="{'has-error': confirmPassword.invalid && confirmPassword.dirty}">
<input type="password" class="form-control" required name="confirmPassword" #confirmPassword="ngModel" ngModel />
<span class="label label-danger" *ngIf="confirmPassword.dirty && password.value!=confirmPassword.value">Password not match!</span>
</div>
</div>
▋Drop-down list
Just add the name,
ngModel
on <select>.
▋HTML
<div class="form-group required">
<label class="control-label col-md-2">Department</label>
<div class="col-md-3">
<select class="form-control" name="department" #department="ngModel" ngModel>
<option *ngFor="let dept of departmentList" [ngValue]="dept">{{dept.name}}</option>
</select>
</div>
</div>
▋Component
constructor(private deptSvc: DepartmentService) {
}
ngOnInit() {
//...
this.deptSvc.getAll().subscribe(data => {
this.departmentList = data;
});
}
▋Checkbox
<div class="form-group required">
<label class="control-label col-md-2">Account Role</label>
<div class="col-md-3">
<input type="checkbox" name="isManager" ngModel> Admin
<input type="checkbox" name="isReviewer" ngModel> Review
<input type="checkbox" name="isDeleter" ngModel> Delete
</div>
</div>
▋Submit and cancel buttons
Here
we can use form.invalid to disable or enable the Submit button.
<input type="submit" value="Save" class="btn btn-success" [disabled]="form.invalid" />
<input type="button" value="Back" class="btn btn-warning" [routerLink]="['/Cms/Layout/Account/List']" />
▋Submit!
Let’s
first create the classes for the data from the Form.
▋account.ts
import { Department } from './department';
import { Role } from './role';
export class Account {
id: string;
password: string;
confirmPassword: string;
name: string;
email: string;
status: string;
department: Department;
jobTitle: string;
isManager: boolean;
isReviewer: boolean;
isDeleter: boolean;
public constructor(
fields?: {
id?: string;
password?: string;
confirmPassword?: string;
name?: string;
email?:string;
status?: string;
department?: number;
jobTitle?: string;
isManager?: boolean;
isReviewer?: boolean;
isDeleter?: boolean;
}) {
if (fields) {
Object.assign(this, fields);
}
else {
this.isManager = false;
this.isReviewer = false;
this.isDeleter = false;
this.department= new Department();
}
}
}
▋account.ts
export class Department {
id: string;
name: string;
}
▋role.ts
export class Role {
name: string
}
At last, we could complete the submit function J
private onSubmit(form: NgForm) {
let act: Account = null;
if (form && form.value) {
act = form.value;
//Post it to backend....
}
}
▋Demo
▌Summary
From the tutorial, we found that Angular Template-driven
Forms are really easy and quick to implement. However, if we want to create a dynamic
form, using Model-driven Forms will be more suitable and flexible. We will talk
about it in the next article.
▌Reference
沒有留言:
張貼留言