Skip to content

Commit b096240

Browse files
committed
example(forms): added a example of using forms
1 parent edc3709 commit b096240

File tree

2 files changed

+208
-0
lines changed

2 files changed

+208
-0
lines changed
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
import {bootstrap, Component, Decorator, Template, If, For, EventEmitter} from 'angular2/angular2';
2+
import {FormBuilder, Validators, FormDirectives, ControlGroup} from 'angular2/forms';
3+
4+
// HeaderFields renders the bound header control group. It can used as follows:
5+
//
6+
// <survey-header [header]="header"></survey-header>
7+
//
8+
// This component is self-contained and can be tested in isolation.
9+
@Component({
10+
selector: 'survey-header',
11+
bind: {
12+
"header" : "header"
13+
}
14+
})
15+
@Template({
16+
inline: `
17+
<div [control-group]="header">
18+
<div>
19+
<label>Title:</label> <br/>
20+
<input type="text" control="title"/>
21+
<div *if="! header.controls.title.valid && header.controls.title.dirty">
22+
Title is required
23+
</div>
24+
</div>
25+
26+
<div>
27+
<label>Description:</label> <br/>
28+
<textarea control="description"></textarea>
29+
<div *if="! header.controls.description.valid && header.controls.description.dirty">
30+
Description is required
31+
</div>
32+
</div>
33+
34+
<div>
35+
<label>Publish Date:</label> <br/>
36+
<input type="date" control="date"/>
37+
</div>
38+
</div>
39+
`,
40+
directives: [FormDirectives, If]
41+
})
42+
class HeaderFields {
43+
header:ControlGroup;
44+
}
45+
46+
47+
48+
// SurveyQuestion renders an individual question. It can used as follows:
49+
//
50+
// <survey-question [question]="question" [index]="i" (delete)="onDelete()"></survey-question>
51+
//
52+
// SurveyQuestion uses EventEmitter to fire the delete action.
53+
// This component is self-contained and can be tested in isolation.
54+
@Component({
55+
selector: 'survey-question',
56+
bind: {
57+
"question" : "question",
58+
"index" : "index"
59+
}
60+
})
61+
@Template({
62+
inline: `
63+
<h2>Question #{{index}}</h2>
64+
65+
<button (click)="deleteQuestion()">Delete</button>
66+
67+
<div [control-group]="question">
68+
<div>
69+
<label>Type:</label> <br/>
70+
<select control="type">
71+
<option value=""></option>
72+
<option value="text">Text</option>
73+
<option value="checkbox">Checkbox</option>
74+
<option value="textarea">Textarea</option>
75+
</select>
76+
<div *if="! question.controls.type.valid && question.controls.type.dirty">
77+
Type is required
78+
</div>
79+
</div>
80+
81+
<div>
82+
<label>Question:</label> <br/>
83+
<input type="text" control="questionText">
84+
<div *if="! question.controls.questionText.valid && question.controls.questionText.dirty">
85+
Question is required
86+
</div>
87+
</div>
88+
89+
<div *if="question.contains('responseLength')">
90+
<label>Response Length:</label> <br/>
91+
<input type="number" control="responseLength">
92+
<div *if="! question.controls.responseLength.valid && question.controls.responseLength.dirty">
93+
Length is required
94+
</div>
95+
</div>
96+
</div>
97+
`,
98+
directives: [FormDirectives, If]
99+
})
100+
class SurveyQuestion {
101+
question:ControlGroup;
102+
index:number;
103+
onDelete:Function;
104+
105+
constructor(@EventEmitter("delete") onDelete:Function) {
106+
this.onDelete = onDelete;
107+
}
108+
109+
deleteQuestion() {
110+
// Invoking an injected event emitter will fire an event,
111+
// which in this case will result in calling `deleteQuestion(i)`
112+
this.onDelete();
113+
}
114+
}
115+
116+
117+
118+
// SurveyBuilder is a form that allows you to create a survey.
119+
@Component({
120+
selector: 'survey-builder-app',
121+
services: [FormBuilder]
122+
})
123+
@Template({
124+
inline: `
125+
<h1>Create New Survey</h1>
126+
127+
<div [control-group]="form">
128+
<survey-header [header]="form.controls.header"></survey-header>
129+
130+
<button (click)="addQuestion()">Add Question</button>
131+
<survey-question
132+
*for="var q of form.controls.questions.controls; var i=index"
133+
[question]="q"
134+
[index]="i + 1"
135+
(delete)="deleteQuestion(i)">
136+
</survey-question>
137+
138+
<button (click)="submitForm()">Submit</button>
139+
</div>
140+
`,
141+
directives: [FormDirectives, For, HeaderFields, SurveyQuestion]
142+
})
143+
class SurveyBuilder {
144+
form:ControlGroup;
145+
builder:FormBuilder;
146+
147+
constructor(b:FormBuilder) {
148+
this.builder = b;
149+
this.form = b.group({
150+
"header" : b.group({
151+
"title" : ["", Validators.required],
152+
"description" : ["", Validators.required],
153+
"date" : ""
154+
}),
155+
"questions": b.array([])
156+
});
157+
}
158+
159+
addQuestion() {
160+
var newQuestion = this.builder.group({
161+
"type": ["", Validators.required],
162+
"questionText": ["", Validators.required],
163+
"responseLength": [100, Validators.required]
164+
}, {
165+
// Optional controls can be dynamically added or removed from the form.
166+
// Here, the responseLength field is optional and not included by default.
167+
"optionals": {
168+
"responseLength": false
169+
}
170+
});
171+
172+
// Every Control has an observable of value changes. You can subscribe to this observable
173+
// to update the form, update the application model, etc.
174+
// These observables can also be transformed and combined. This enables implementing
175+
// complex form interactions in a declarative fashion.
176+
//
177+
// We are disabling the responseLength control when the question type is checkbox.
178+
newQuestion.controls.type.valueChanges.subscribe((v) =>
179+
v == 'text' || v == 'textarea' ?
180+
newQuestion.include('responseLength') : newQuestion.exclude('responseLength'));
181+
182+
this.form.controls.questions.push(newQuestion);
183+
}
184+
185+
deleteQuestion(index:number) {
186+
this.form.controls.questions.removeAt(index);
187+
}
188+
189+
submitForm() {
190+
console.log("Submitting a form")
191+
console.log("value", this.form.value, "valid", this.form.valid, "errors", this.form.errors);
192+
}
193+
}
194+
195+
export function main() {
196+
bootstrap(SurveyBuilder);
197+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html>
3+
<title>Survey Builder</title>
4+
<body>
5+
<survey-builder-app>
6+
Loading...
7+
</survey-builder-app>
8+
9+
$SCRIPTS$
10+
</body>
11+
</html>

0 commit comments

Comments
 (0)