-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
solve--add-a-book-new-form-and-route
- Loading branch information
1 parent
e11e3c9
commit 61a5da5
Showing
8 changed files
with
182 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<h2>New</h2> | ||
|
||
<form [formGroup]="form" (ngSubmit)="submit()"> | ||
<label class="form-field"> | ||
<span>ISBN</span> | ||
<input formControlName="isbn" /> | ||
@if (form.controls.isbn.dirty && form.controls.isbn.hasError('required')) { | ||
<small>Please insert an Author.</small> | ||
} | ||
</label> | ||
|
||
<label class="form-field"> | ||
<span>Title</span> | ||
<input formControlName="title" /> | ||
@if ( | ||
form.controls.title.dirty && form.controls.title.hasError('required') | ||
) { | ||
<small>Please insert a title.</small> | ||
} | ||
</label> | ||
|
||
<label class="form-field"> | ||
<span>Subtitle</span> | ||
<input formControlName="subtitle" /> | ||
</label> | ||
|
||
<ng-container formArrayName="authors"> | ||
@for (author of authors.controls; track index; let index = $index) { | ||
<label class="form-field"> | ||
<span>Author</span> | ||
<input [formControlName]="index" /> | ||
|
||
@if (author.dirty) { | ||
@if (author.hasError('required')) { | ||
<small>Please insert an Author.</small> | ||
} @else if (author.hasError('invalidAuthor')) { | ||
<small>Name must not contain digits</small> | ||
} | ||
} | ||
</label> | ||
<button (click)="deleteAuthor(index)">Remove Author</button> | ||
} | ||
</ng-container> | ||
<button type="button" (click)="addAuthor()">Author hinzufügen</button> | ||
|
||
<label class="form-field"> | ||
<span>Abstract</span> | ||
<input formControlName="abstract" /> | ||
</label> | ||
|
||
<div class="form-actions"> | ||
<button type="submit" [disabled]="form.invalid">Save</button> | ||
</div> | ||
</form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
:host { | ||
display: block; | ||
margin: 1rem; | ||
} | ||
|
||
.form-field { | ||
display: block; | ||
margin-top: 1rem; | ||
|
||
> span { | ||
display: block; | ||
margin-bottom: 0.5rem; | ||
} | ||
|
||
> input { | ||
padding: 12px 20px 12px 6px; | ||
border: 1px solid #ccc; | ||
border-radius: 4px; | ||
box-sizing: border-box; | ||
min-width: 250px; | ||
} | ||
} | ||
|
||
.form-field-hint { | ||
display: block; | ||
color: #3c3c3c; | ||
} | ||
|
||
.form-actions { | ||
margin-top: 1rem; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { Component, inject } from '@angular/core'; | ||
import { | ||
FormArray, | ||
FormControl, | ||
FormGroup, | ||
NonNullableFormBuilder, | ||
ReactiveFormsModule, | ||
Validators | ||
} from '@angular/forms'; | ||
import { BookApiService } from '../book-api.service'; | ||
import { validAuthorName } from '../validators/author.validator'; | ||
|
||
interface BookForm { | ||
isbn: FormControl<string>; | ||
title: FormControl<string>; | ||
subtitle: FormControl<string>; | ||
authors: FormArray<FormControl<string>>; | ||
abstract: FormControl<string>; | ||
} | ||
|
||
@Component({ | ||
selector: 'app-book-new', | ||
standalone: true, | ||
imports: [ReactiveFormsModule], | ||
templateUrl: './book-new.component.html', | ||
styleUrls: ['./book-new.component.scss'] | ||
}) | ||
export class BookNewComponent { | ||
private readonly formBuilder = inject(NonNullableFormBuilder); | ||
private readonly bookApiService = inject(BookApiService); | ||
|
||
form: FormGroup<BookForm> = this.formBuilder.group({ | ||
isbn: ['', [Validators.required]], | ||
title: ['', [Validators.required]], | ||
subtitle: [''], | ||
authors: this.formBuilder.array([ | ||
['', [Validators.required, validAuthorName()]] | ||
]), | ||
abstract: [''] | ||
}); | ||
|
||
submit() { | ||
this.bookApiService.create(this.form.getRawValue()).subscribe(); | ||
// We need to handle the formArray now for authors separately | ||
// Unfortunately the backend doesn't handle multiple authors yet | ||
const firstAuthor = this.form.getRawValue().authors[0] || 'n/a'; | ||
this.bookApiService | ||
.create({ ...this.form.getRawValue(), author: firstAuthor }) | ||
.subscribe(); | ||
} | ||
|
||
get authors(): FormArray { | ||
return this.form.controls.authors; | ||
} | ||
|
||
deleteAuthor(authorIndex: number) { | ||
this.authors.removeAt(authorIndex); | ||
} | ||
|
||
addAuthor() { | ||
this.authors.push( | ||
this.formBuilder.control('', [Validators.required, validAuthorName()]) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import {AbstractControl, ValidationErrors, ValidatorFn} from '@angular/forms'; | ||
|
||
export function validAuthorName(): ValidatorFn { | ||
return (control:AbstractControl) : ValidationErrors | null => { | ||
const value = control.value; | ||
if (!value) { | ||
return null; | ||
} | ||
|
||
const hasNumeric = /[0-9]+/.test(value); | ||
return hasNumeric ? { invalidAuthor : true }: null; | ||
} | ||
} |