Differenzansicht 12-validation
im Vergleich zu 11-forms

← Zurück zur Übersicht | Demo | Quelltext auf GitHub
src/app/books-admin/book-form/book-form.ng.html CHANGED
@@ -1,14 +1,32 @@
1
  @let c = bookForm.controls;
2
 
3
  <form [formGroup]="bookForm" (ngSubmit)="submitForm()">
 
4
  <label for="title">Title</label>
5
- <input id="title" [formControl]="c.title" />
 
 
 
 
 
 
 
 
6
 
7
  <label for="subtitle">Subtitle</label>
8
  <input id="subtitle" [formControl]="c.subtitle" />
9
 
 
10
  <label for="isbn">ISBN</label>
11
- <input id="isbn" [formControl]="c.isbn" />
 
 
 
 
 
 
 
 
12
 
13
  <fieldset>
14
  <legend>Authors</legend>
@@ -29,5 +47,5 @@
29
  <label for="imageUrl">Thumbnail URL</label>
30
  <input type="url" id="imageUrl" [formControl]="c.imageUrl" />
31
 
32
- <button type="submit">Save</button>
33
  </form>
 
1
  @let c = bookForm.controls;
2
 
3
  <form [formGroup]="bookForm" (ngSubmit)="submitForm()">
4
+ @let titleInvalid = isInvalid(c.title);
5
  <label for="title">Title</label>
6
+ <input
7
+ id="title"
8
+ [formControl]="c.title"
9
+ [attr.aria-describedby]="titleInvalid ? 'title-error' : null"
10
+ [attr.aria-invalid]="titleInvalid"
11
+ />
12
+ @if (titleInvalid) {
13
+ <small id="title-error">The title is invalid.</small>
14
+ }
15
 
16
  <label for="subtitle">Subtitle</label>
17
  <input id="subtitle" [formControl]="c.subtitle" />
18
 
19
+ @let isbnInvalid = isInvalid(c.isbn);
20
  <label for="isbn">ISBN</label>
21
+ <input
22
+ id="isbn"
23
+ [formControl]="c.isbn"
24
+ [attr.aria-describedby]="isbnInvalid ? 'isbn-error' : null"
25
+ [attr.aria-invalid]="isbnInvalid"
26
+ />
27
+ @if (isbnInvalid) {
28
+ <small id="isbn-error">The ISBN is invalid.</small>
29
+ }
30
 
31
  <fieldset>
32
  <legend>Authors</legend>
 
47
  <label for="imageUrl">Thumbnail URL</label>
48
  <input type="url" id="imageUrl" [formControl]="c.imageUrl" />
49
 
50
+ <button type="submit" [disabled]="bookForm.invalid">Save</button>
51
  </form>
src/app/books-admin/book-form/book-form.ts CHANGED
@@ -1,5 +1,5 @@
1
  import { Component, output } from '@angular/core';
2
- import { FormArray, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
3
 
4
  import { Book } from '../../shared/book';
5
 
@@ -13,9 +13,21 @@ export class BookForm {
13
  readonly submitBook = output<Book>();
14
 
15
  bookForm = new FormGroup({
16
- isbn: new FormControl('', { nonNullable: true }),
17
- title: new FormControl('', { nonNullable: true }),
18
- subtitle: new FormControl('', { nonNullable: true }),
 
 
 
 
 
 
 
 
 
 
 
 
19
  description: new FormControl('', { nonNullable: true }),
20
  authors: new FormArray([
21
  new FormControl('', { nonNullable: true })
@@ -29,6 +41,13 @@ export class BookForm {
29
  );
30
  }
31
 
 
 
 
 
 
 
 
32
  submitForm() {
33
  const formValue = this.bookForm.getRawValue();
34
  const authors = formValue.authors.filter(author => !!author);
 
1
  import { Component, output } from '@angular/core';
2
+ import { FormArray, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
3
 
4
  import { Book } from '../../shared/book';
5
 
 
13
  readonly submitBook = output<Book>();
14
 
15
  bookForm = new FormGroup({
16
+ isbn: new FormControl('', {
17
+ nonNullable: true,
18
+ validators: [
19
+ Validators.required,
20
+ Validators.minLength(13),
21
+ Validators.maxLength(13),
22
+ ]
23
+ }),
24
+ title: new FormControl('', {
25
+ nonNullable: true,
26
+ validators: Validators.required,
27
+ }),
28
+ subtitle: new FormControl('', {
29
+ nonNullable: true
30
+ }),
31
  description: new FormControl('', { nonNullable: true }),
32
  authors: new FormArray([
33
  new FormControl('', { nonNullable: true })
 
41
  );
42
  }
43
 
44
+ isInvalid(control: FormControl) {
45
+ if (!control.touched) {
46
+ return null;
47
+ }
48
+ return control.invalid && control.touched;
49
+ }
50
+
51
  submitForm() {
52
  const formValue = this.bookForm.getRawValue();
53
  const authors = formValue.authors.filter(author => !!author);