@ -3,27 +3,17 @@
|
||||
|
||||
<h1>Reactive Form</h1>
|
||||
|
||||
<!-- #docregion cross-validation -->
|
||||
<form [formGroup]="heroForm" #formDir="ngForm">
|
||||
<!-- #enddocregion cross-validation -->
|
||||
|
||||
<div [hidden]="formDir.submitted">
|
||||
|
||||
<!-- #docregion cross-validation -->
|
||||
<!-- #docregion cross-validation-error-class -->
|
||||
<div class="cross-validation" [class.cross-validation-error]="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)">
|
||||
<!-- #enddocregion cross-validation-error-class -->
|
||||
<!-- #enddocregion cross-validation -->
|
||||
<div class="form-group">
|
||||
|
||||
<label for="name">Name</label>
|
||||
<!-- #docregion name-with-error-msg -->
|
||||
<!-- #docregion cross-validation -->
|
||||
<!-- #docregion cross-validation-error-class-->
|
||||
<input id="name" class="form-control"
|
||||
formControlName="name" required >
|
||||
<!-- #enddocregion cross-validation -->
|
||||
<!-- #enddocregion cross-validation-error-class-->
|
||||
|
||||
<div *ngIf="name.invalid && (name.dirty || name.touched)"
|
||||
class="alert alert-danger">
|
||||
@ -43,27 +33,16 @@
|
||||
|
||||
<div class="form-group">
|
||||
<label for="alterEgo">Alter Ego</label>
|
||||
<!-- #docregion cross-validation -->
|
||||
<!-- #docregion cross-validation-error-class-->
|
||||
<input id="alterEgo" class="form-control"
|
||||
formControlName="alterEgo" >
|
||||
<!-- #enddocregion cross-validation -->
|
||||
<!-- #enddocregion cross-validation-error-class -->
|
||||
</div>
|
||||
|
||||
<!-- #docregion cross-validation-error-message -->
|
||||
<!-- #docregion cross-validation -->
|
||||
<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
|
||||
Name cannot match alter ego.
|
||||
</div>
|
||||
<!-- #enddocregion cross-validation -->
|
||||
<!-- #enddocregion cross-validation-error-message -->
|
||||
|
||||
<!-- #docregion cross-validation -->
|
||||
<!-- #docregion cross-validation-error-class-->
|
||||
</div>
|
||||
<!-- #enddocregion cross-validation -->
|
||||
<!-- #enddocregion cross-validation-error-class -->
|
||||
|
||||
<div class="form-group">
|
||||
<label for="power">Hero Power</label>
|
||||
@ -82,9 +61,7 @@
|
||||
<button type="button" class="btn btn-default"
|
||||
(click)="formDir.resetForm({})">Reset</button>
|
||||
</div>
|
||||
<!-- #docregion cross-validation -->
|
||||
</form>
|
||||
<!-- #enddocregion cross-validation -->
|
||||
|
||||
<div class="submitted-message" *ngIf="formDir.submitted">
|
||||
<p>You've submitted your hero, {{ heroForm.value.name }}!</p>
|
||||
|
@ -5,23 +5,19 @@ import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { forbiddenNameValidator } from '../shared/forbidden-name.directive';
|
||||
import { identityRevealedValidator } from '../shared/identity-revealed.directive';
|
||||
|
||||
// #docregion cross-validation-component
|
||||
@Component({
|
||||
selector: 'app-hero-form-reactive',
|
||||
templateUrl: './hero-form-reactive.component.html',
|
||||
styleUrls: ['./hero-form-reactive.component.css'],
|
||||
})
|
||||
export class HeroFormReactiveComponent implements OnInit {
|
||||
// #enddocregion cross-validation-component
|
||||
|
||||
powers = ['Really Smart', 'Super Flexible', 'Weather Changer'];
|
||||
|
||||
hero = { name: 'Dr.', alterEgo: 'Dr. What', power: this.powers[0] };
|
||||
|
||||
// #docregion cross-validation-component
|
||||
heroForm: FormGroup;
|
||||
|
||||
// #docregion cross-validation-register
|
||||
ngOnInit(): void {
|
||||
this.heroForm = new FormGroup({
|
||||
'name': new FormControl(this.hero.name, [
|
||||
@ -33,12 +29,8 @@ export class HeroFormReactiveComponent implements OnInit {
|
||||
'power': new FormControl(this.hero.power, Validators.required)
|
||||
}, { validators: identityRevealedValidator }); // <-- add custom validator at the FormGroup level
|
||||
}
|
||||
// #enddocregion cross-validation-register
|
||||
// #enddocregion cross-validation-component
|
||||
|
||||
get name() { return this.heroForm.get('name'); }
|
||||
|
||||
get power() { return this.heroForm.get('power'); }
|
||||
// #docregion cross-validation-component
|
||||
}
|
||||
// #enddocregion cross-validation-component
|
||||
|
@ -2,14 +2,13 @@
|
||||
import { Directive } from '@angular/core';
|
||||
import { AbstractControl, FormGroup, NG_VALIDATORS, ValidationErrors, Validator, ValidatorFn } from '@angular/forms';
|
||||
|
||||
// #docregion cross-validation-directive-with-validator
|
||||
// #docregion cross-validation-validator
|
||||
/** A hero's name can't match the hero's alter ego */
|
||||
export const identityRevealedValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
|
||||
const name = control.get('name');
|
||||
const alterEgo = control.get('alterEgo');
|
||||
|
||||
return name && alterEgo && name.value !== alterEgo.value ? null : { 'identityRevealed': { value: true } };
|
||||
return name && alterEgo && name.value !== alterEgo.value ? null : { 'identityRevealed': true };
|
||||
};
|
||||
// #enddocregion cross-validation-validator
|
||||
|
||||
@ -24,5 +23,3 @@ export class IdentityRevealedValidatorDirective implements Validator {
|
||||
}
|
||||
}
|
||||
// #enddocregion cross-validation-directive
|
||||
// #enddocregion cross-validation-directive-with-validator
|
||||
|
||||
|
@ -2,28 +2,18 @@
|
||||
<div class="container">
|
||||
|
||||
<h1>Template-Driven Form</h1>
|
||||
<!-- #docregion cross-validation -->
|
||||
<!-- #docregion cross-validation-register-validator -->
|
||||
<form #heroForm="ngForm" appIdentityRevealed>
|
||||
<!-- #enddocregion cross-validation-register-validator -->
|
||||
<!-- #enddocregion cross-validation -->
|
||||
<div [hidden]="heroForm.submitted">
|
||||
<!-- #docregion cross-validation -->
|
||||
<!-- #docregion cross-validation-error-class -->
|
||||
<div class="cross-validation" [class.cross-validation-error]="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)">
|
||||
<!-- #enddocregion cross-validation-error-class -->
|
||||
<!-- #enddocregion cross-validation -->
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<!-- #docregion name-with-error-msg -->
|
||||
<!-- #docregion name-input -->
|
||||
<!-- #docregion cross-validation -->
|
||||
<!-- #docregion cross-validation-error-class -->
|
||||
<input id="name" name="name" class="form-control"
|
||||
required minlength="4" appForbiddenName="bob"
|
||||
[(ngModel)]="hero.name" #name="ngModel" >
|
||||
<!-- #enddocregion cross-validation-error-class-->
|
||||
<!-- #enddocregion cross-validation-->
|
||||
<!-- #enddocregion name-input -->
|
||||
|
||||
<div *ngIf="name.invalid && (name.dirty || name.touched)"
|
||||
@ -45,28 +35,16 @@
|
||||
|
||||
<div class="form-group">
|
||||
<label for="alterEgo">Alter Ego</label>
|
||||
<!-- #docregion cross-validation -->
|
||||
<!-- #docregion cross-validation-error-class -->
|
||||
<input id="alterEgo" class="form-control"
|
||||
name="alterEgo" [(ngModel)]="hero.alterEgo" >
|
||||
<!-- #enddocregion cross-validation-error-class -->
|
||||
<!-- #enddocregion cross-validation -->
|
||||
</div>
|
||||
|
||||
<!-- #docregion cross-validation -->
|
||||
<!-- #docregion cross-validation-error-message -->
|
||||
<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
|
||||
Name cannot match alter ego.
|
||||
</div>
|
||||
<!-- #enddocregion cross-validation-error-message -->
|
||||
<!-- #enddocregion cross-validation -->
|
||||
|
||||
<!-- #docregion cross-validation-->
|
||||
<!-- #docregion cross-validation-error-class -->
|
||||
</div>
|
||||
<!-- #enddocregion cross-validation-error-class -->
|
||||
<!-- #enddocregion cross-validation -->
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="power">Hero Power</label>
|
||||
@ -90,9 +68,5 @@
|
||||
<p>You've submitted your hero, {{ heroForm.value.name }}!</p>
|
||||
<button (click)="heroForm.resetForm({})">Add new hero</button>
|
||||
</div>
|
||||
|
||||
<!-- #docregion cross-validation -->
|
||||
</form>
|
||||
<!-- #enddocregion cross-validation -->
|
||||
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user