docs: improve accessibility of form-validation example (#41283)
PR Close #41283
This commit is contained in:
parent
6967f3ca28
commit
253ed5d484
@ -54,7 +54,7 @@ function getPage(sectionTag: string) {
|
|||||||
page = {
|
page = {
|
||||||
section,
|
section,
|
||||||
form: section.element(by.css('form')),
|
form: section.element(by.css('form')),
|
||||||
title: section.element(by.css('h1')),
|
title: section.element(by.css('h2')),
|
||||||
nameInput: section.element(by.css('#name')),
|
nameInput: section.element(by.css('#name')),
|
||||||
alterEgoInput: section.element(by.css('#alterEgo')),
|
alterEgoInput: section.element(by.css('#alterEgo')),
|
||||||
powerSelect: section.element(by.css('#power')),
|
powerSelect: section.element(by.css('#power')),
|
||||||
|
@ -3,7 +3,8 @@ import { Component } from '@angular/core';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
template: `<app-hero-form-template></app-hero-form-template>
|
template: `<h1>Form validation example</h1>
|
||||||
|
<app-hero-form-template></app-hero-form-template>
|
||||||
<hr>
|
<hr>
|
||||||
<app-hero-form-reactive></app-hero-form-reactive>`
|
<app-hero-form-reactive></app-hero-form-reactive>`
|
||||||
})
|
})
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<!-- #docregion -->
|
<!-- #docregion -->
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
<h1>Reactive Form</h1>
|
<h2>Reactive Form</h2>
|
||||||
|
|
||||||
<form [formGroup]="heroForm" #formDir="ngForm">
|
<form [formGroup]="heroForm" #formDir="ngForm">
|
||||||
|
|
||||||
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<!-- #docregion name-with-error-msg -->
|
<!-- #docregion name-with-error-msg -->
|
||||||
<input id="name" class="form-control"
|
<input type="text" id="name" class="form-control"
|
||||||
formControlName="name" required >
|
formControlName="name" required>
|
||||||
|
|
||||||
<div *ngIf="name.invalid && (name.dirty || name.touched)"
|
<div *ngIf="name.invalid && (name.dirty || name.touched)"
|
||||||
class="alert alert-danger">
|
class="alert alert-danger">
|
||||||
@ -33,8 +33,8 @@
|
|||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="alterEgo">Alter Ego</label>
|
<label for="alterEgo">Alter Ego</label>
|
||||||
<input id="alterEgo" class="form-control"
|
<input type="text" id="alterEgo" class="form-control"
|
||||||
formControlName="alterEgo" >
|
formControlName="alterEgo">
|
||||||
|
|
||||||
<div *ngIf="alterEgo.pending">Validating...</div>
|
<div *ngIf="alterEgo.pending">Validating...</div>
|
||||||
<div *ngIf="alterEgo.invalid" class="alert alert-danger alter-ego-errors">
|
<div *ngIf="alterEgo.invalid" class="alert alert-danger alter-ego-errors">
|
||||||
@ -54,7 +54,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="power">Hero Power</label>
|
<label for="power">Hero Power</label>
|
||||||
<select id="power" class="form-control"
|
<select id="power" class="form-control"
|
||||||
formControlName="power" required >
|
formControlName="power" required>
|
||||||
<option *ngFor="let p of powers" [value]="p">{{p}}</option>
|
<option *ngFor="let p of powers" [value]="p">{{p}}</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
@ -63,7 +63,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-default"
|
<p>Complete the form to enable the Submit button.</p>
|
||||||
|
<button type="submit"
|
||||||
|
class="btn btn-default"
|
||||||
[disabled]="heroForm.invalid">Submit</button>
|
[disabled]="heroForm.invalid">Submit</button>
|
||||||
<button type="button" class="btn btn-default"
|
<button type="button" class="btn btn-default"
|
||||||
(click)="formDir.resetForm({})">Reset</button>
|
(click)="formDir.resetForm({})">Reset</button>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* #docregion */
|
/* #docregion */
|
||||||
.cross-validation-error input {
|
.cross-validation-error input {
|
||||||
border-left: 5px solid red;
|
border-left: 5px solid #a94442;
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<!-- #docregion -->
|
<!-- #docregion -->
|
||||||
<div class="container">
|
<div>
|
||||||
|
|
||||||
<h1>Template-Driven Form</h1>
|
<h2>Template-Driven Form</h2>
|
||||||
<!-- #docregion cross-validation-register-validator -->
|
<!-- #docregion cross-validation-register-validator -->
|
||||||
<form #heroForm="ngForm" appIdentityRevealed>
|
<form #heroForm="ngForm" appIdentityRevealed>
|
||||||
<!-- #enddocregion cross-validation-register-validator -->
|
<!-- #enddocregion cross-validation-register-validator -->
|
||||||
@ -11,13 +11,13 @@
|
|||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<!-- #docregion name-with-error-msg -->
|
<!-- #docregion name-with-error-msg -->
|
||||||
<!-- #docregion name-input -->
|
<!-- #docregion name-input -->
|
||||||
<input id="name" name="name" class="form-control"
|
<input type="text" id="name" name="name" class="form-control"
|
||||||
required minlength="4" appForbiddenName="bob"
|
required minlength="4" appForbiddenName="bob"
|
||||||
[(ngModel)]="hero.name" #name="ngModel" >
|
[(ngModel)]="hero.name" #name="ngModel">
|
||||||
<!-- #enddocregion name-input -->
|
<!-- #enddocregion name-input -->
|
||||||
|
|
||||||
<div *ngIf="name.invalid && (name.dirty || name.touched)"
|
<div *ngIf="name.invalid && (name.dirty || name.touched)"
|
||||||
class="alert alert-danger">
|
class="alert">
|
||||||
|
|
||||||
<div *ngIf="name.errors.required">
|
<div *ngIf="name.errors.required">
|
||||||
Name is required.
|
Name is required.
|
||||||
@ -35,14 +35,16 @@
|
|||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="alterEgo">Alter Ego</label>
|
<label for="alterEgo">Alter Ego</label>
|
||||||
<input id="alterEgo" class="form-control" name="alterEgo"
|
<input type="text"
|
||||||
|
id="alterEgo"
|
||||||
|
name="alterEgo"
|
||||||
#alterEgo="ngModel"
|
#alterEgo="ngModel"
|
||||||
[(ngModel)]="hero.alterEgo"
|
[(ngModel)]="hero.alterEgo"
|
||||||
[ngModelOptions]="{ updateOn: 'blur' }"
|
[ngModelOptions]="{ updateOn: 'blur' }"
|
||||||
appUniqueAlterEgo>
|
appUniqueAlterEgo>
|
||||||
|
|
||||||
<div *ngIf="alterEgo.pending">Validating...</div>
|
<div *ngIf="alterEgo.pending">Validating...</div>
|
||||||
<div *ngIf="alterEgo.invalid" class="alert alert-danger alter-ego-errors">
|
<div *ngIf="alterEgo.invalid" class="alert alter-ego-errors">
|
||||||
<div *ngIf="alterEgo.errors?.uniqueAlterEgo">
|
<div *ngIf="alterEgo.errors?.uniqueAlterEgo">
|
||||||
Alter ego is already taken.
|
Alter ego is already taken.
|
||||||
</div>
|
</div>
|
||||||
@ -50,7 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- #docregion cross-validation-error-message -->
|
<!-- #docregion cross-validation-error-message -->
|
||||||
<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
|
<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert">
|
||||||
Name cannot match alter ego.
|
Name cannot match alter ego.
|
||||||
</div>
|
</div>
|
||||||
<!-- #enddocregion cross-validation-error-message -->
|
<!-- #enddocregion cross-validation-error-message -->
|
||||||
@ -58,19 +60,22 @@
|
|||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="power">Hero Power</label>
|
<label for="power">Hero Power</label>
|
||||||
<select id="power" name="power" class="form-control"
|
<select id="power"
|
||||||
required [(ngModel)]="hero.power" #power="ngModel" >
|
name="power"
|
||||||
|
required [(ngModel)]="hero.power"
|
||||||
|
#power="ngModel">
|
||||||
<option *ngFor="let p of powers" [value]="p">{{p}}</option>
|
<option *ngFor="let p of powers" [value]="p">{{p}}</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<div *ngIf="power.errors && power.touched" class="alert alert-danger">
|
<div *ngIf="power.errors && power.touched" class="alert">
|
||||||
<div *ngIf="power.errors.required">Power is required.</div>
|
<div *ngIf="power.errors.required">Power is required.</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-default"
|
<p>Complete the form to enable the Submit button.</p>
|
||||||
|
<button type="submit"
|
||||||
[disabled]="heroForm.invalid">Submit</button>
|
[disabled]="heroForm.invalid">Submit</button>
|
||||||
<button type="button" class="btn btn-default"
|
<button type="button"
|
||||||
(click)="heroForm.resetForm({})">Reset</button>
|
(click)="heroForm.resetForm({})">Reset</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -6,3 +6,24 @@
|
|||||||
.ng-invalid:not(form) {
|
.ng-invalid:not(form) {
|
||||||
border-left: 5px solid #a94442; /* red */
|
border-left: 5px solid #a94442; /* red */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alert div {
|
||||||
|
background-color: #fed3d3;
|
||||||
|
color: #820000;
|
||||||
|
padding: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
width: 100%;
|
||||||
|
padding: .5rem;
|
||||||
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
<base href="/">
|
<base href="/">
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css">
|
|
||||||
<link rel="stylesheet" href="assets/forms.css">
|
<link rel="stylesheet" href="assets/forms.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ Before reading about form validation, you should have a basic understanding of t
|
|||||||
|
|
||||||
* [TypeScript](https://www.typescriptlang.org/ "The TypeScript language") and HTML5 programming.
|
* [TypeScript](https://www.typescriptlang.org/ "The TypeScript language") and HTML5 programming.
|
||||||
|
|
||||||
* Fundamental concepts of [Angular app design](guide/architecture "Introduction to Angular app-design concepts").
|
* Fundamental concepts of [Angular application design](guide/architecture "Introduction to Angular application-design concepts").
|
||||||
|
|
||||||
* The [two types of forms that Angular supports](guide/forms-overview "Introduction to Angular forms").
|
* The [two types of forms that Angular supports](guide/forms-overview "Introduction to Angular forms").
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user