This tutorial is out of date and no longer maintained.
In this tutorial we will explore the way to bind these few types of controls to our form: text, number, radio, select (primitive type), select (object), multiple select, checkbox (boolean), and checkbox (toggle value).
Feel free to skip some of the control types (as some of them are really simple).
If you are new to Angular 2 forms, do refer to these articles for basics.
View Angular 2 - Different form controls (final) scotch on plnkr
We will build a form to capture user information based on these interfaces.
export interface User {
name: string; // text
age?: number; // number
language?: string; // radio
role?: string; // select (primitive)
theme?: Theme; // select (object)
topics?: string[]; // multiple select
isActive?: boolean; // checkbox
toggle?: string; // checkbox toggle either 'toggled' or 'untoggled'
}
export interface Theme {
display: string;
backgroundColor: string;
fontColor: string;
}
Here is how the UI will look:
Here’s our file structure:
|- app/
|- app.component.html
|- app.component.ts
|- app.module.ts
|- main.ts
|- theme.interface.ts
|- user.interface.ts
|- index.html
|- styles.css
|- tsconfig.json
In order to use the forms module, we need to npm install @angular/forms
npm package and import the forms module in the application module.
- npm install @angular/forms --save
Here’s the module for our application app.module.ts
:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule, FormsModule ], // import forms module
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Let’s move on to create our app component.
import { Component, OnInit } from '@angular/core';
import { User } from './user.interface';
import { Theme } from './theme.interface';
@Component({
moduleId: module.id,
selector: 'my-app',
templateUrl: 'app.component.html',
directives: []
})
export class AppComponent implements OnInit {
public user: User;
/* standing data goes here*/
...
/* end standing data */
ngOnInit() {
// initialize user model here
}
public save(isValid: boolean, f: User) {
console.log(f);
}
}
We need to include some data for setup as well:
...
/* standing data goes here*/
public languages = [
{ value: 'en', display: 'English' },
{ value: 'es', display: 'Spanish' }
];
public roles = [
{ value: 'admin', display: 'Administrator' },
{ value: 'guest', display: 'Guest' },
{ value: 'custom', display: 'Custom' }
];
public themes: Theme[] = [
{ backgroundColor: 'black', fontColor: 'white', display: 'Dark' },
{ backgroundColor: 'white', fontColor: 'black', display: 'Light' },
{ backgroundColor: 'grey', fontColor: 'white', display: 'Sleek' }
];
public topics = [
{ value: 'game', display: 'Gaming' },
{ value: 'tech', display: 'Technology' },
{ value: 'life', display: 'Lifestyle' },
];
public toggles = [
{ value: 'toggled', display: 'Toggled' },
{ value: 'untoggled', display: 'UnToggled' },
];
/* end standing data */
...
Then, we need to initialize our user model:
...
ngOnInit() {
// initialize user model here
this.user = {
name: '',
language: this.languages[0].value, // default to English
role: null,
theme: this.themes[0], // default to dark theme
isActive: false,
toggle: this.toggles[1].value, // default to untoggled
topics: [this.topics[1].value] // default to Technology
}
}
...
This is how our HTML view will look like.
<form #f="ngForm" novalidate>
<!-- We'll add our form controls here -->
<button type="submit" (click)="save(f.value, f.valid)">Submit</button>
</form>
Let’s start to look into each type of control.
Getting text input is very straightforward. You need the name
attribute, and ngModel
.
...
<div>
<label>Name</label>
<input type="text" name="name" [(ngModel)]="user.name">
</div>
...
Getting number input is also very straightforward.
...
<div>
<label>Age</label>
<input type="number" name="age" [(ngModel)]="user.age">
</div>
...
Binding radio input is not that easy prior Angular RC 2. With the new form in RC 3 onward, we can directly bind to ngModel
, bind the value
property.
We have this list of preferred languages:
public languages = [
{ value: 'en', display: 'English' },
{ value: 'es', display: 'Spanish' }
];
When select, we want only the value Hammerhead or Great White Shark.
...
<div>
<label>Language</label>
<div *ngFor="let language of languages">
<label>
<input type="radio" name="language" [(ngModel)]="user.language"
[value]="language.value">
{{language.display}}
</label>
</div>
</div>
...
You can bind select to ngModel
. Loop through your option
list, set the value
property.
We have a list of roles:
public roles = [
{ value: 'admin', display: 'Administrator' },
{ value: 'guest', display: 'Guest' },
{ value: 'custom', display: 'Custom' }
];
When value selected, we expected it to return string value admin, guest, or custom. Here’s how your HTML will look like.
...
<div>
<label>Role</label>
<select name="role" [(ngModel)]="user.role">
<option *ngFor="let role of roles" [value]="role.value">
{{role.display}}
</option>
</select>
</div>
...
Similar to the last example, but this time, instead of a simple type, we want the whole object when it’s selected.
Here is the list of themes:
public themes: Theme[] = [
{ backgroundColor: 'black', fontColor: 'white', display: 'Dark' },
{ backgroundColor: 'white', fontColor: 'black', display: 'Light' },
{ backgroundColor: 'grey', fontColor: 'white', display: 'Sleek' }
];
When selected, for example Light theme, we expect { backgroundColor: 'white', fontColor: 'black', display: 'Light' }
to be returned. Instead of binding to the value property, we bind to ngValue
property.
...
<div>
<label>Theme</label>
<select name="theme" [(ngModel)]="user.theme">
<option *ngFor="let theme of themes" [ngValue]="theme">
{{theme.display}}
</option>
</select>
</div>
...
We can select more than 1 topics. E.g. when selecting game and tech, it should return ['game', 'tech']
.
public topics = [
{ value: 'game', display: 'Gaming' },
{ value: 'tech', display: 'Technology' },
{ value: 'life', display: 'Lifestyle' },
];
Similar to select, but this time our model is array of string.
...
<div>
<label>Topics</label>
<select multiple name="topics" [(ngModel)]="user.topics">
<option *ngFor="let topic of topics" [value]="topic.value">
{{topic.display}}
</option>
</select>
</div>
...
By default, checkboxes return boolean. Bind ngModel
and define the name attribute as usual.
...
<div>
<label>
<input type="checkbox" name="isActive" [(ngModel)]="user.isActive">
Is Active
</label>
</div>
...
In this case, we want to display a checkbox. Instead of boolean, we expecting value. When checked, it should return toggled, else return value untoggled.
This is the list of toggles:
public toggles = [
{ value: 'toggled', display: 'Toggled' },
{ value: 'untoggled', display: 'UnToggled' },
];
First, we define a hidden input to bind to the real model. Then we create the checkbox input, handle the checked
property and change
event. Change event fire every time value change, and it has $event
that we can read from.
In our case, we read the $event.target.checked
to find out if the checkbox is checked, then update model value accordingly.
...
<div>
<input type="hidden" name="toggle" [(ngModel)]="user.toggle">
<div>
<label>
<input type="checkbox"
[checked]="user.toggle === toggles[0].value"
(change)="$event.target.checked? (user.toggle = toggles[0].value) : (user.toggle = toggles[1].value)">
{{ toggles[0].display }}
</label>
</div>
</div>
...
During development, it’s good that you can visualize the value. Angular provided a very useful json
Pipe.
...
<pre>{{your_form or control_name | json }}</pre>
...
That’s it. Hope it helps your journey in Angular 2. Happy coding!
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!