import { bootstrap, NgIf, NgFor, Component, Directive, View, Host, NgValidator, forwardRef, Binding } from 'angular2/bootstrap'; import {FORM_DIRECTIVES, NgControl, Validators, NgForm} from 'angular2/forms'; import {RegExpWrapper, print, isPresent, CONST_EXPR} from 'angular2/src/core/facade/lang'; /** * A domain model we are binding the form controls to. */ class CheckoutModel { firstName: string; middleName: string; lastName: string; country: string = "Canada"; creditCard: string; amount: number; email: string; comments: string; } /** * Custom validator. */ const creditCardValidatorBinding = CONST_EXPR(new Binding(NgValidator, {toAlias: forwardRef(() => CreditCardValidator)})); @Directive({selector: '[credit-card]', bindings: [creditCardValidatorBinding]}) class CreditCardValidator { get validator() { return CreditCardValidator.validate; } static validate(c): StringMap { if (isPresent(c.value) && RegExpWrapper.test(new RegExp("^\\d{16}$"), c.value)) { return null; } else { return {"invalidCreditCard": true}; } } } /** * This is a component that displays an error message. * * For instance, * * * * Will display the "is required" error if the control is empty, and "invalid credit card" if the * control is not empty * but not valid. * * In a real application, this component would receive a service that would map an error code to an * actual error message. * To make it simple, we are using a simple map here. */ @Component({selector: 'show-error', properties: ['controlPath: control', 'errorTypes: errors']}) @View({ template: ` {{errorMessage}} `, directives: [NgIf] }) class ShowError { formDir; controlPath: string; errorTypes: List; constructor(@Host() formDir: NgForm) { this.formDir = formDir; } get errorMessage() { var c = this.formDir.form.find(this.controlPath); for (var i = 0; i < this.errorTypes.length; ++i) { if (isPresent(c) && c.touched && c.hasError(this.errorTypes[i])) { return this._errorMessage(this.errorTypes[i]); } } return null; } _errorMessage(code) { var config = {'required': 'is required', 'invalidCreditCard': 'is invalid credit card number'}; return config[code]; } } @Component({selector: 'template-driven-forms'}) @View({ template: `

Checkout Form

`, directives: [FORM_DIRECTIVES, NgFor, CreditCardValidator, ShowError] }) class TemplateDrivenForms { model = new CheckoutModel(); countries = ['US', 'Canada']; onSubmit() { print("Submitting:"); print(this.model); } } export function main() { bootstrap(TemplateDrivenForms); }