Paul Gschwendtner e4fb93c28a build: switch playground examples to bazel (#28490)
Currently all playground examples are built with `tsc`
and served with the `gulp serve` task. In order to be able
to test these examples easily with Ivy, we now build and
serve the examples using Bazel. This allows us to expand our
Ivy test coverage and additionally it allows us to move forward
with the overall Bazel migration. Building & serving individual
examples is now very easy and doesn't involve building everything
inside of `/modules`.

PR Close #28490
2019-02-04 16:51:11 -05:00

182 lines
5.1 KiB
TypeScript

/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/* tslint:disable:no-console */
import {Component, Directive, Host, NgModule} from '@angular/core';
import {FormControl, FormGroup, FormsModule, NG_VALIDATORS, NgForm} from '@angular/forms';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
/**
* 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.
*/
export function creditCardValidator(c: FormControl): {[key: string]: boolean} {
if (c.value && /^\d{16}$/.test(c.value)) {
return null;
} else {
return {'invalidCreditCard': true};
}
}
export const creditCardValidatorBinding = {
provide: NG_VALIDATORS,
useValue: creditCardValidator,
multi: true
};
@Directive({selector: '[credit-card]', providers: [creditCardValidatorBinding]})
export class CreditCardValidator {
}
/**
* This is a component that displays an error message.
*
* For instance,
*
* <show-error control="creditCard" [errors]="['required', 'invalidCreditCard']"></show-error>
*
* 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',
inputs: ['controlPath: control', 'errorTypes: errors'],
template: `
<span *ngIf="errorMessage !== null">{{errorMessage}}</span>
`
})
export class ShowError {
formDir: NgForm;
controlPath: string;
errorTypes: string[];
constructor(@Host() formDir: NgForm) { this.formDir = formDir; }
get errorMessage(): string {
const form: FormGroup = this.formDir.form;
const control = form.get(this.controlPath);
if (control && control.touched) {
for (let i = 0; i < this.errorTypes.length; ++i) {
if (control.hasError(this.errorTypes[i])) {
return this._errorMessage(this.errorTypes[i]);
}
}
}
return null;
}
private _errorMessage(code: string): string {
const config: {[key: string]: string} = {
'required': 'is required',
'invalidCreditCard': 'is invalid credit card number',
};
return config[code];
}
}
@Component({
selector: 'template-driven-forms',
template: `
<h1>Checkout Form</h1>
<form (ngSubmit)="onSubmit()" #f="ngForm">
<p>
<label for="firstName">First Name</label>
<input type="text" id="firstName" name="firstName" [(ngModel)]="model.firstName" required>
<show-error control="firstName" [errors]="['required']"></show-error>
</p>
<p>
<label for="middleName">Middle Name</label>
<input type="text" id="middleName" name="middleName" [(ngModel)]="model.middleName">
</p>
<p>
<label for="lastName">Last Name</label>
<input type="text" id="lastName" name="lastName" [(ngModel)]="model.lastName" required>
<show-error control="lastName" [errors]="['required']"></show-error>
</p>
<p>
<label for="country">Country</label>
<select id="country" name="country" [(ngModel)]="model.country">
<option *ngFor="let c of countries" [value]="c">{{c}}</option>
</select>
</p>
<p>
<label for="creditCard">Credit Card</label>
<input type="text" id="creditCard" name="creditCard" [(ngModel)]="model.creditCard" required credit-card>
<show-error control="creditCard" [errors]="['required', 'invalidCreditCard']"></show-error>
</p>
<p>
<label for="amount">Amount</label>
<input type="number" id="amount" name="amount" [(ngModel)]="model.amount" required>
<show-error control="amount" [errors]="['required']"></show-error>
</p>
<p>
<label for="email">Email</label>
<input type="email" id="email" name="email" [(ngModel)]="model.email" required>
<show-error control="email" [errors]="['required']"></show-error>
</p>
<p>
<label for="comments">Comments</label>
<textarea id="comments" name="comments" [(ngModel)]="model.comments">
</textarea>
</p>
<button type="submit" [disabled]="!f.form.valid">Submit</button>
</form>
`
})
export class TemplateDrivenForms {
model = new CheckoutModel();
countries = ['US', 'Canada'];
onSubmit(): void {
console.log('Submitting:');
console.log(this.model);
}
}
@NgModule({
declarations: [TemplateDrivenForms, CreditCardValidator, ShowError],
bootstrap: [TemplateDrivenForms],
imports: [BrowserModule, FormsModule]
})
export class ExampleModule {
}
platformBrowserDynamic().bootstrapModule(ExampleModule);