Binding Form Controls to a Domain Model
Initialize the domain model within your component:
constructor(){
this.student = new Student();
}
Use ngModel
to bind to the form controls to a domain model with two-way model binding.
Name: <input [(ngModel)]="student.name" type="text">
Password: <input [(ngModel)]="student.password" type="text">
When the button is clicked, pass the domain model as an argument:
<button type="button" (click)="addNewGroup(student)">Create</button>
Implement the addNewGroup
method. To reset the form, update the domain model with a new model:
addNewGroup(student:Student) {
alert('added ' + student.name);
this.student = new Student();
}
Demo Plnkr
Adding Validators to the Form
To add form validation, add ngFormModel
to the form element and add ngControl
decorators to each input element (ngControl
is syntactic sugar for [ngFormControl]="studentForm.controls['name']"
):
<form [ngFormModel]="studentForm" />
<input type="text" ngControl="name" />
<input type="text" ngControl="password" />
</form>
The ngFormModel
maps to a ControlGroup
property of your component. Initialize the ControlGroup
with a configuration object whose property names correspond to the values from the ngControl
attributes:
constructor(fb: FormBuilder){
this.student = new Student();
this.studentForm = fb.group({
'name': new Control(this.student.name, Validators.required),
'password': new Control(this.student.password, Validators.required)
});
}
In the above example, the built-in required
validator is used to indicate that name and password are required fields. You can then check whether the entire form is valid using the valid
property on the form model:
addNewGroup(student:Student) {
if (this.studentForm.valid) {
alert('added ' + student.name);
this.student = new Student();
}
else {
alert('form is not valid!');
}
}
Demo Plnkr
Showing Validation Messages
If you want to bind to validation messages in the view, you can export the Control as a local template variable and access it's validation properties: valid, dirty, pending, pristine, and the errors object.
<input ngControl="name" #name="ngForm" type="text">
<span [hidden]="name.valid"><b>Required</b></span>
Demo Plnkr
If you want to create your own custom validator, create a method that returns a validation object whose boolean
properties correspond to validation errors. For example, you can create a validator that ensures that the first letter of a password must be numeric:
interface ValidationResult {
[key:string]:boolean;
}
class PasswordValidator {
static startsWithNumber(control: Control): ValidationResult {
if ( control.value && control.value.length > 0){
if (isNaN(control.value[0]))
return { 'startsWithNumber': true };
}
return null;
}
}
Compose validators together into one validator and pass it to the Control
constructor using the built-in Validators.compose
:
this.studentForm = fb.group({
'name': new Control(this.student.name, Validators.required),
'password': new Control(this.student.password, Validators.compose([Validators.required,PasswordValidator.startsWithNumber])),
});
If you have multiple validators on the same Control
, use the errors
object to distinguish between them:
<input ngControl="password" #password="ngForm" />
<span [hidden]="!password.control.hasError('required')"><b>Required</b></span>
<span [hidden]="!password.control.hasError('startsWithNumber')"><b>Must start with number</b></span>
Demo Plnkr
Binding to Radio Button Lists
In Angular2, there is no built-in support yet to bind to radio button lists. Check this post to find out how to do this:
Angular2 - Radio Button Binding