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

Commit f971685

Browse files
committed
docs(cb-form-validation): ward's tweaks
renamed from cb-validation to cb-form-validation other refactorings and text changes
1 parent 3b4a5d5 commit f971685

28 files changed

+358
-306
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
// #docplaster
21
// #docregion
32
import { Component } from '@angular/core';
43

54
@Component({
65
selector: 'my-app',
76
template: `<hero-form-template></hero-form-template>
87
<hr>
9-
<hero-form-model></hero-form-model>`
8+
<hero-form-reactive></hero-form-reactive>`
109
})
1110
export class AppComponent { }
12-
// #enddocregion
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// #docregion
2+
import { NgModule } from '@angular/core';
3+
import { BrowserModule } from '@angular/platform-browser';
4+
5+
import { AppComponent } from './app.component';
6+
import { HeroFormTemplateModule } from './template/hero-form-template.module';
7+
import { HeroFormReactiveModule } from './reactive/hero-form-reactive.module';
8+
9+
@NgModule({
10+
imports: [
11+
BrowserModule,
12+
HeroFormTemplateModule,
13+
HeroFormReactiveModule
14+
],
15+
declarations: [ AppComponent ],
16+
bootstrap: [ AppComponent ]
17+
})
18+
export class AppModule { }
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
// #docplaster
21
// #docregion
32
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
43

54
import { AppModule } from './app.module';
65

76
platformBrowserDynamic().bootstrapModule(AppModule);
8-
// #enddocregion
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!-- #docregion -->
2+
<div class="container">
3+
<div [hidden]="submitted">
4+
<h1>Hero Form (Reactive)</h1>
5+
<form [formGroup]="heroForm" *ngIf="active" (ngSubmit)="onSubmit()">
6+
<div class="form-group">
7+
<!-- #docregion name-with-error-msg -->
8+
<label for="name">Name</label>
9+
<input type="text" id="name" class="form-control"
10+
formControlName="name"
11+
[ngClass]="{'required': isRequired('name')}">
12+
<div *ngIf="formError.name" class="alert alert-danger">
13+
{{ formError.name }}
14+
</div>
15+
<!-- #enddocregion name-with-error-msg -->
16+
</div>
17+
18+
<div class="form-group">
19+
<label for="alterEgo">Alter Ego</label>
20+
<input type="text" id="alterEgo" class="form-control"
21+
formControlName="alterEgo"
22+
[ngClass]="{'required': isRequired('alterEgo')}" >
23+
</div>
24+
25+
<div class="form-group">
26+
<label for="power">Hero Power</label>
27+
<select id="power" class="form-control"
28+
formControlName="power"
29+
[ngClass]="{'required': isRequired('power')}" >
30+
<option *ngFor="let p of powers" [value]="p">{{p}}</option>
31+
</select>
32+
<div *ngIf="formError.power" class="alert alert-danger">
33+
{{ formError.power }}
34+
</div>
35+
</div>
36+
37+
<button type="submit" class="btn btn-default"
38+
[disabled]="!heroForm.valid">Submit</button>
39+
<button type="button" class="btn btn-default"
40+
(click)="newHero()">New Hero</button>
41+
</form>
42+
</div>
43+
44+
<hero-submitted [hero]="model" [(submitted)]="submitted"></hero-submitted>
45+
</div>
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/* tslint:disable: member-ordering forin */
2+
// #docplaster
3+
// #docregion
4+
import { Component, OnInit } from '@angular/core';
5+
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
6+
7+
import { Hero } from '../shared/hero';
8+
9+
@Component({
10+
moduleId: module.id,
11+
selector: 'hero-form-reactive',
12+
templateUrl: 'hero-form-reactive.component.html'
13+
})
14+
// #docregion class
15+
export class HeroFormReactiveComponent implements OnInit {
16+
17+
powers = ['Really Smart', 'Super Flexible', 'Weather Changer'];
18+
19+
model = new Hero(18, 'Dr. WhatIsHisWayTooLongName', this.powers[0], 'Dr. What');
20+
21+
submitted = false;
22+
23+
onSubmit() {
24+
this.submitted = true;
25+
this.model = this.heroForm.value;
26+
}
27+
// #enddocregion class
28+
29+
// Reset the form with a new hero AND restore 'pristine' class state
30+
// by toggling 'active' flag which causes the form
31+
// to be removed/re-added in a tick via NgIf
32+
// TODO: Workaround until NgForm has a reset method (#6822)
33+
// #docregion new-hero
34+
active = true;
35+
36+
// #docregion class
37+
newHero() {
38+
this.model = new Hero(42, '', '');
39+
this.buildForm();
40+
this.onValueChanged('');
41+
// #enddocregion class
42+
43+
this.active = false;
44+
setTimeout(() => this.active = true, 0);
45+
// #docregion class
46+
}
47+
48+
//// New with Reactive Form
49+
50+
heroForm: FormGroup;
51+
constructor(private builder: FormBuilder) { }
52+
53+
ngOnInit(): void { this.buildForm(); }
54+
55+
formError = {
56+
'name': '',
57+
'power': ''
58+
};
59+
60+
validationMessages = {
61+
'name': {
62+
'required': 'Name is required.',
63+
'minlength': 'Name must be at least 4 characters long.',
64+
'maxlength': 'Name cannot be more than 24 characters long.'
65+
},
66+
'power': {
67+
'required': 'Power is required.'
68+
}
69+
};
70+
71+
buildForm(): void {
72+
this.heroForm = this.builder.group({
73+
'name': [this.model.name, [
74+
Validators.required,
75+
Validators.minLength(4),
76+
Validators.maxLength(24)
77+
]
78+
],
79+
'alterEgo': [this.model.alterEgo],
80+
'power': [this.model.power, Validators.required]
81+
});
82+
this.heroForm.valueChanges
83+
.subscribe(data => this.onValueChanged(data));
84+
}
85+
86+
onValueChanged(data: any) {
87+
const controls = this.heroForm ? this.heroForm.controls : {};
88+
for (const field in this.formError) {
89+
// clear previous error message (if any)
90+
this.formError[field] = '';
91+
const control = controls[field];
92+
if (control && control.dirty && !control.valid) {
93+
const messages = this.validationMessages[field];
94+
for (const key in control.errors) {
95+
this.formError[field] += messages[key] + ' ';
96+
}
97+
}
98+
}
99+
}
100+
101+
isRequired(controlName: string): boolean {
102+
const msgs = this.validationMessages[controlName];
103+
return msgs && msgs['required'];
104+
}
105+
}
106+
// #enddocregion class
107+
// #enddocregion
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// #docregion
2+
import { NgModule } from '@angular/core';
3+
import { ReactiveFormsModule } from '@angular/forms';
4+
5+
import { SharedModule } from '../shared/shared.module';
6+
import { HeroFormReactiveComponent } from './hero-form-reactive.component';
7+
8+
@NgModule({
9+
imports: [ SharedModule, ReactiveFormsModule ],
10+
declarations: [ HeroFormReactiveComponent ],
11+
exports: [ HeroFormReactiveComponent ]
12+
})
13+
export class HeroFormReactiveModule { }
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
// #docplaster
21
// #docregion
32
export class Hero {
4-
53
constructor(
64
public id: number,
75
public name: string,
86
public power: string,
97
public alterEgo?: string
108
) { }
11-
129
}
13-
// #enddocregion
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// #docregion
2+
import { NgModule } from '@angular/core';
3+
import { CommonModule } from '@angular/common';
4+
5+
import { SubmittedComponent } from './submitted.component';
6+
7+
@NgModule({
8+
imports: [ CommonModule],
9+
declarations: [ SubmittedComponent ],
10+
exports: [ CommonModule, SubmittedComponent ]
11+
})
12+
export class SharedModule { }
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// #docregion
2+
import { Component, EventEmitter, Input, Output } from '@angular/core';
3+
4+
import { Hero } from './hero';
5+
6+
@Component({
7+
selector: 'hero-submitted',
8+
template: `
9+
<div *ngIf="submitted">
10+
<h2>You submitted the following:</h2>
11+
<div class="row">
12+
<div class="col-xs-3">Name</div>
13+
<div class="col-xs-9 pull-left">{{ hero.name }}</div>
14+
</div>
15+
<div class="row">
16+
<div class="col-xs-3">Alter Ego</div>
17+
<div class="col-xs-9 pull-left">{{ hero.alterEgo }}</div>
18+
</div>
19+
<div class="row">
20+
<div class="col-xs-3">Power</div>
21+
<div class="col-xs-9 pull-left">{{ hero.power }}</div>
22+
</div>
23+
<br>
24+
<button class="btn btn-default" (click)="onClick()">Edit</button>
25+
</div>`
26+
})
27+
export class SubmittedComponent {
28+
@Input() hero: Hero;
29+
@Input() submitted = false;
30+
@Output() submittedChange = new EventEmitter<boolean>();
31+
onClick() { this.submittedChange.emit(false); }
32+
}

0 commit comments

Comments
 (0)