Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit d049dbb

Browse files
docs(reactive-forms): add reactive forms guide
1 parent 42d08b7 commit d049dbb

38 files changed

+3767
-6
lines changed

public/docs/_examples/forms/ts/app/hero-form.component.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ <h1>Hero Form</h1>
4444
</div>
4545

4646
<!-- #docregion submit-button -->
47-
<button type="submit" class="btn btn-default" [disabled]="!heroForm.form.valid">Submit</button>
47+
<button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button>
4848
<!-- #enddocregion submit-button -->
4949
<!-- #docregion new-hero-button-form-reset -->
5050
<button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button>
@@ -84,7 +84,7 @@ <h2>You submitted the following:</h2>
8484
<div class="col-xs-9 pull-left">{{ model.power }}</div>
8585
</div>
8686
<br>
87-
<button class="btn btn-default" (click)="submitted=false">Edit</button>
87+
<button class="btn btn-primary" (click)="submitted=false">Edit</button>
8888
</div>
8989
<!-- #enddocregion submitted -->
9090
</div>
@@ -138,7 +138,7 @@ <h1>Hero Form</h1>
138138

139139
<!-- #enddocregion powers -->
140140
<!-- #docregion start -->
141-
<button type="submit" class="btn btn-default">Submit</button>
141+
<button type="submit" class="btn btn-success">Submit</button>
142142

143143
</form>
144144
</div>
@@ -176,7 +176,7 @@ <h1>Hero Form</h1>
176176
</div>
177177

178178
<!-- #enddocregion ngModel-2-->
179-
<button type="submit" class="btn btn-default">Submit</button>
179+
<button type="submit" class="btn btn-success">Submit</button>
180180

181181
</form>
182182
</div>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// #docregion
2+
import { Component } from '@angular/core';
3+
4+
@Component({
5+
moduleId: module.id,
6+
selector: 'my-app',
7+
template: `
8+
<div class="container">
9+
<h1>Reactive Forms</h1>
10+
<hero-detail></hero-detail>
11+
</div>`
12+
})
13+
export class AppComponent { }
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// #docregion
2+
import { Component } from '@angular/core';
3+
4+
@Component({
5+
moduleId: module.id,
6+
selector: 'my-app',
7+
template: `
8+
<div class="container">
9+
<h1>Reactive Forms</h1>
10+
<hero-list></hero-list>
11+
</div>`
12+
})
13+
export class AppComponent { }
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// #docplaster
2+
// #docregion
3+
// #docregion v1
4+
import { NgModule } from '@angular/core';
5+
import { BrowserModule } from '@angular/platform-browser';
6+
import { ReactiveFormsModule } from '@angular/forms'; // <-- #1 import module
7+
8+
import { AppComponent } from './app.component';
9+
import { HeroDetailComponent } from './hero-detail.component'; // <-- #1 import component
10+
// #enddocregion v1
11+
import { HeroListComponent } from './hero-list.component';
12+
13+
import { HeroService } from './hero.service'; // <-- #1 import service
14+
// #docregion v1
15+
16+
@NgModule({
17+
imports: [
18+
BrowserModule,
19+
ReactiveFormsModule // <-- #2 add to Angular module imports
20+
],
21+
declarations: [
22+
AppComponent,
23+
HeroDetailComponent, // <-- #3 declare app component
24+
// #enddocregion v1
25+
HeroListComponent
26+
// #docregion v1
27+
],
28+
// #enddocregion v1
29+
exports: [ // export for the DemoModule
30+
AppComponent,
31+
HeroDetailComponent,
32+
HeroListComponent
33+
],
34+
providers: [ HeroService ], // <-- #4 provide HeroService
35+
// #docregion v1
36+
bootstrap: [ AppComponent ]
37+
})
38+
export class AppModule { }
39+
// #enddocregion v1
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// #docregion
2+
// #docregion model-classes
3+
export class Hero {
4+
id = 0;
5+
name = '';
6+
addresses: Address[];
7+
}
8+
9+
export class Address {
10+
street = '';
11+
city = '';
12+
state = '';
13+
zip = '';
14+
}
15+
// #enddocregion model-classes
16+
17+
export const heroes: Hero[] = [
18+
{
19+
id: 1,
20+
name: 'Whirlwind',
21+
addresses: [
22+
{street: '123 Main', city: 'Anywhere', state: 'CA', zip: '94801'},
23+
{street: '456 Maple', city: 'Somewhere', state: 'VA', zip: '23226'},
24+
]
25+
},
26+
{
27+
id: 2,
28+
name: 'Bombastic',
29+
addresses: [
30+
{street: '789 Elm', city: 'Smallville', state: 'OH', zip: '04501'},
31+
]
32+
},
33+
{
34+
id: 3,
35+
name: 'Magneta',
36+
addresses: [ ]
37+
},
38+
];
39+
40+
export const states = ['CA', 'MD', 'OH', 'VA'];
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<div class="container">
2+
<h1>Reactive Forms</h1>
3+
<h4><i>Pick a demo:</i>
4+
<select [selectedIndex]="demo - 1" (change)="selectDemo($event.target.selectedIndex)">
5+
<option *ngFor="let demo of demos">{{demo}}</option>
6+
</select>
7+
</h4>
8+
9+
<hr>
10+
11+
<div class="demo">
12+
<hero-list *ngIf="demo===final"></hero-list>
13+
14+
<hero-detail-1 *ngIf="demo===1"></hero-detail-1>
15+
<hero-detail-2 *ngIf="demo===2"></hero-detail-2>
16+
<hero-detail-3 *ngIf="demo===3"></hero-detail-3>
17+
<hero-detail-4 *ngIf="demo===4"></hero-detail-4>
18+
19+
<div *ngIf="demo >= 5 && demo !== final" >
20+
21+
<p *ngIf="!heroes"><b><i>Loading heroes ... </i></b></p>
22+
<h3 *ngIf="heroes">Select a hero:</h3>
23+
24+
<nav>
25+
<button (click)="getHeroes()" class="btn btn-primary">Refresh</button>
26+
<a *ngFor="let hero of heroes" (click)="select(hero)">{{hero.name}}</a>
27+
</nav>
28+
29+
<div *ngIf="selectedHero">
30+
<hr>
31+
<h2>Hero Detail</h2>
32+
<h3>Editing: {{selectedHero.name}}</h3>
33+
<hero-detail-5 [hero]=selectedHero *ngIf="demo===5"></hero-detail-5>
34+
<hero-detail-6 [hero]=selectedHero *ngIf="demo===6"></hero-detail-6>
35+
<hero-detail-7 [hero]=selectedHero *ngIf="demo===7"></hero-detail-7>
36+
</div>
37+
</div>
38+
</div>
39+
</div>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* tslint:disable:member-ordering */
2+
// #docregion
3+
import { Component } from '@angular/core';
4+
5+
import { Hero } from './data-model';
6+
import { HeroService } from './hero.service';
7+
8+
@Component({
9+
moduleId: module.id,
10+
selector: 'my-app',
11+
templateUrl: 'demo.component.html'
12+
})
13+
export class DemoComponent {
14+
15+
demos: string[] = [
16+
'Simple FormControl',
17+
'Simple FormBuilder group',
18+
'Group with multiple controls',
19+
'Nested FormBuilder group',
20+
'PatchValue',
21+
'SetValue',
22+
'FormArray',
23+
'Final'].map(n => n + ' Demo');
24+
25+
final = this.demos.length;
26+
demo = this.final; // current demo
27+
28+
heroes: Hero[];
29+
selectedHero: Hero;
30+
31+
constructor(private heroService: HeroService) { }
32+
33+
getHeroes() {
34+
this.selectedHero = undefined;
35+
this.heroes = undefined;
36+
return this.heroService.getHeroes()
37+
.then(heroes => this.heroes = heroes);
38+
}
39+
40+
select(hero: Hero) { this.selectedHero = hero; }
41+
42+
selectDemo(demo: number) {
43+
this.demo = demo + 1;
44+
this.getHeroes();
45+
}
46+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { NgModule } from '@angular/core';
2+
import { BrowserModule } from '@angular/platform-browser';
3+
import { ReactiveFormsModule } from '@angular/forms';
4+
5+
import { AppModule } from './app.module';
6+
import { DemoComponent } from './demo.component';
7+
import { components } from './hero-detail-versions.component';
8+
9+
@NgModule({
10+
imports: [
11+
BrowserModule,
12+
ReactiveFormsModule,
13+
AppModule,
14+
],
15+
declarations: [ DemoComponent, ...components ],
16+
bootstrap: [ DemoComponent ]
17+
})
18+
export class DemoModule { }
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!-- #docregion basic-form-->
2+
<h2>Hero Detail</h2>
3+
<h3><i>A simple form with a single FormControl</i></h3>
4+
<form [formGroup]="heroForm" novalidate>
5+
<div class="form-group">
6+
<label>Name:</label>
7+
<input class="form-control" formControlName="name">
8+
</div>
9+
</form>
10+
<!-- #enddocregion basic-form-->
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!-- #docregion basic-form-->
2+
<h2>Hero Detail</h2>
3+
<h3><i>A simple form with a single FormControl using FormBuilder</i></h3>
4+
<form [formGroup]="heroForm" novalidate>
5+
<div class="form-group">
6+
<label>Name:</label>
7+
<input class="form-control" formControlName="name">
8+
</div>
9+
</form>
10+
<!-- #enddocregion basic-form-->
11+
12+
<!-- #docregion form-value-json -->
13+
<p>Form: {{ heroForm.value | json }}</p>
14+
<!-- #enddocregion form-value-json -->
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!-- #docregion -->
2+
<h2>Hero Detail</h2>
3+
<h3><i>A simple form with multiple FormControls in a single FormBuilder group</i></h3>
4+
<form [formGroup]="heroForm" novalidate>
5+
<div class="form-group">
6+
<label>Name:</label>
7+
<input class="form-control" formControlName="name">
8+
</div>
9+
<div class="form-group">
10+
<label>Street:</label>
11+
<input class="form-control" formControlName="street">
12+
</div>
13+
<div class="form-group">
14+
<label>City:</label>
15+
<input class="form-control" formControlName="city">
16+
</div>
17+
<div class="form-group">
18+
<label>State:</label>
19+
<select class="form-control" formControlName="state">
20+
<option *ngFor="let state of states">{{state}}</option>
21+
</select>
22+
</div>
23+
<div class="form-group">
24+
<label>Zip Code:</label>
25+
<input class="form-control" formControlName="zip">
26+
</div>
27+
</form>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<form [formGroup]="heroForm" novalidate>
2+
<div class="form-group">
3+
<label>Name:</label>
4+
<input class="form-control" formControlName="name">
5+
</div>
6+
<!-- #docregion add-group-->
7+
<div formGroupName="address" class="well well-lg">
8+
<h4>Secret Lair</h4>
9+
<div class="form-group">
10+
<label>Street:</label>
11+
<input class="form-control" formControlName="street">
12+
</div>
13+
<div class="form-group">
14+
<label>City:</label>
15+
<input class="form-control" formControlName="city">
16+
</div>
17+
<div class="form-group">
18+
<label>State:</label>
19+
<select class="form-control" formControlName="state">
20+
<option *ngFor="let state of states">{{state}}</option>
21+
</select>
22+
</div>
23+
<div class="form-group">
24+
<label>Zip Code:</label>
25+
<input class="form-control" formControlName="zip">
26+
</div>
27+
</div>
28+
<!-- #enddocregion add-group-->
29+
</form>
30+
31+
<p>heroForm value: {{ heroForm.value | json}}</p>
32+
<h4>Extra info for the curious:</h4>
33+
<!-- #docregion inspect-value -->
34+
<p>Name value: {{ heroForm.get('name').value }}</p>
35+
<!-- #enddocregion inspect-value -->
36+
37+
<!-- #docregion inspect-child-control -->
38+
<p>Street value: {{ heroForm.get('address.street').value}}</p>
39+
<!-- #enddocregion inspect-child-control -->
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<!-- #docplaster-->
2+
<h3><i>Using FormArray to add groups</i></h3>
3+
4+
<form [formGroup]="heroForm" novalidate>
5+
<p>Form Changed: {{ heroForm.dirty }}</p>
6+
7+
<div class="form-group">
8+
<label>Name:</label>
9+
<input class="form-control" formControlName="name">
10+
</div>
11+
<!-- #docregion form-array-->
12+
<!-- #docregion form-array-skeleton -->
13+
<div formArrayName="secretLairs" class="well well-lg">
14+
<div *ngFor="let address of secretLairs.controls; let i=index" [formGroupName]="i" >
15+
<!-- The repeated address template -->
16+
<!-- #enddocregion form-array-skeleton -->
17+
<h4>Address #{{i + 1}}</h4>
18+
<div style="margin-left: 1em;">
19+
<div class="form-group">
20+
<label>Street:</label>
21+
<input class="form-control" formControlName="street">
22+
</div>
23+
<div class="form-group">
24+
<label>City:</label>
25+
<input class="form-control" formControlName="city">
26+
</div>
27+
<div class="form-group">
28+
<label>State:</label>
29+
<select class="form-control" formControlName="state">
30+
<option *ngFor="let state of states">{{state}}</option>
31+
</select>
32+
</div>
33+
<div class="form-group">
34+
<label>Zip Code:</label>
35+
<input class="form-control" formControlName="zip">
36+
</div>
37+
</div>
38+
<br>
39+
<!-- End of the repeated address template -->
40+
<!-- #docregion form-array-skeleton -->
41+
</div>
42+
<!-- #enddocregion form-array-skeleton -->
43+
<!-- #enddocregion form-array-->
44+
<!-- #docregion add-lair -->
45+
<button (click)="addLair()" type="button">Add a Secret Lair</button>
46+
<!-- #enddocregion add-lair -->
47+
<!-- #docregion form-array-->
48+
<!-- #docregion form-array-skeleton -->
49+
</div>
50+
<!-- #enddocregion form-array-skeleton -->
51+
<!-- #enddocregion form-array-->
52+
</form>
53+
54+
<p>heroForm value: {{ heroForm.value | json}}</p>

0 commit comments

Comments
 (0)