Differenzansicht 12-validation
im Vergleich zu 11-forms

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