import {bootstrap, NgIf, NgFor, EventEmitter, Component, View} from 'angular2/angular2'; import { FormBuilder, Validators, formDirectives, ControlGroup, Control, ControlArray } from 'angular2/forms'; import {ObservableWrapper} from 'angular2/src/facade/async'; import {print} from 'angular2/src/facade/lang'; // HeaderFields renders the bound header control group. It can used as follows: // // // // This component is self-contained and can be tested in isolation. @Component({selector: 'survey-header', properties: ['header']}) @View({ template: `
Title is required
Description is required
`, directives: [formDirectives, NgIf] }) class HeaderFields { header: ControlGroup; } // SurveyQuestion renders an individual question. It can used as follows: // // // // SurveyQuestion uses EventEmitter to fire the delete action. // This component is self-contained and can be tested in isolation. @Component({selector: 'survey-question', events: ['destroy'], properties: ['question', 'index']}) @View({ template: `

Question #{{index}}

Type is required
Question is required
Length is required
`, directives: [formDirectives, NgIf] }) class SurveyQuestion { question: ControlGroup; index: number; destroy: EventEmitter; constructor() { this.destroy = new EventEmitter(); } deleteQuestion(): void { // Invoking an injected event emitter will fire an event, // which in this case will result in calling `deleteQuestion(i)` ObservableWrapper.callNext(this.destroy, null); } } // SurveyBuilder is a form that allows you to create a survey. @Component({selector: 'survey-builder-app', appInjector: [FormBuilder]}) @View({ template: `

Create New Survey

`, directives: [formDirectives, NgFor, HeaderFields, SurveyQuestion] }) class SurveyBuilder { form: ControlGroup; constructor(public builder: FormBuilder) { this.form = builder.group({ "header": builder.group({ "title": ["", Validators.required], "description": ["", Validators.required], "date": "" }), "questions": builder.array([]) }); } addQuestion(): void { var newQuestion: ControlGroup = this.builder.group( { "type": ["", Validators.required], "questionText": ["", Validators.required], "responseLength": [100, Validators.required] }, { // Optional controls can be dynamically added or removed from the form. // Here, the responseLength field is optional and not included by default. "optionals": {"responseLength": false} }); // Every Control has an observable of value changes. You can subscribe to this observable // to update the form, update the application model, etc. // These observables can also be transformed and combined. This enables implementing // complex form interactions in a declarative fashion. // // We are disabling the responseLength control when the question type is checkbox. var typeCtrl: Control = newQuestion.controls['type']; ObservableWrapper.subscribe(typeCtrl.valueChanges, (v) => v == 'text' || v == 'textarea' ? newQuestion.include('responseLength') : newQuestion.exclude('responseLength')); (this.form.controls['questions']).push(newQuestion); } destroyQuestion(index: number): void { (this.form.controls['questions']).removeAt(index); } submitForm(): void { print('Submitting a form'); print(` value: ${ this.form.value }`); print(` valid: ${ this.form.valid }`); print(` errors: ${ this.form.errors }`); } } export function main() { bootstrap(SurveyBuilder); }