error messages kinda

This commit is contained in:
Constantin Simonis 2024-12-17 08:53:49 +01:00
parent 71612b1a9c
commit 2503c33005
Signed by: csimonis
GPG Key ID: 758DD9C506603183
3 changed files with 62 additions and 6 deletions

View File

@ -11,6 +11,8 @@ import {
import {Hotel} from "../model/hotel";
import {RouterLink} from "@angular/router";
import {NgForOf} from "@angular/common";
import {debounceTime} from "rxjs";
import {ErrorMsgComponent} from "./error-msg.component";
@Component({
selector: 'app-edit-hotel',
@ -20,24 +22,29 @@ import {NgForOf} from "@angular/common";
ReactiveFormsModule,
RouterLink,
NgForOf,
ErrorMsgComponent,
],
template: `
<ng-form [formGroup]="form" (ngSubmit)="submit()">
<label for="name">Name</label>
<br>
<input id="name" type="text" formControlName="name">
<app-error-msg [msg]="errorMsgs['name']"></app-error-msg>
<br>
<label for="description">Description</label>
<br>
<input id="description" type="text" formControlName="description">
<app-error-msg [msg]="errorMsgs['description']"></app-error-msg>
<br>
<label for="price">Price</label>
<br>
<input id="price" type="number" formControlName="price">
<app-error-msg [msg]="errorMsgs['price']"></app-error-msg>
<br>
<label for="rating">Rating</label>
<br>
<input id="rating" type="number" formControlName="rating" min="0" max="5">
<app-error-msg [msg]="errorMsgs['rating']"></app-error-msg>
<br>
<br>
<button (click)="addTag()">+</button>
@ -46,6 +53,7 @@ import {NgForOf} from "@angular/common";
<input type="text" placeholder="tag" [formControlName]="i">
<button (click)="deleteTag(tag)">-</button>
</div>
<app-error-msg [msg]="errorMsgs['tags']"></app-error-msg>
</div>
<br>
<br>
@ -56,6 +64,8 @@ import {NgForOf} from "@angular/common";
`,
})
export class EditHotelComponent implements OnInit {
errorMsgs: Record<string, string> = {};
@Input()
hotel: Hotel | null = null;
@ -64,6 +74,12 @@ export class EditHotelComponent implements OnInit {
form!: FormGroup
validationErrors: Record<string, string> = {
required: 'This field is required',
min: 'Value must be greater than or equal to 0',
max: 'Value must be less than or equal to 5'
};
ngOnInit(): void {
const tags = [];
@ -78,15 +94,20 @@ export class EditHotelComponent implements OnInit {
rating: new FormControl(this.hotel?.rating, [Validators.required, Validators.min(0), Validators.max(5)]),
tags: new FormArray(tags),
})
Object.keys(this.form.controls).forEach(controlName => {
const control = this.form.get(controlName);
if (!control) {
return;
}
control?.valueChanges?.pipe(debounceTime(1000)).subscribe(() => {this.setErrorMessage(controlName, control)});
});
}
submit() {
if (!this.form.valid) {
console.error('Form invalid: ');
for (const key in this.form.controls) {
console.error(key, this.form.controls[key].errors);
}
return;
}
const hotel: Hotel = {
@ -115,4 +136,8 @@ export class EditHotelComponent implements OnInit {
deleteTag(tagElement: AbstractControl) {
this.getTags().removeAt(this.getTags().controls.indexOf(tagElement));
}
setErrorMessage(controlName: string, control: AbstractControl) {
this.errorMsgs[controlName] = Object.keys(control.errors ?? {}).map ((key) => this.validationErrors[key]).join(' ');
}
}

View File

@ -0,0 +1,32 @@
import {Component, Input} from "@angular/core";
import {NgIf} from "@angular/common";
@Component({
standalone: true,
selector: 'app-error-msg',
imports: [
NgIf
],
template: `
<div *ngIf="msg" class="alert alert-danger">
{{ msg }}
</div>
`,
styles: `
.alert {
color: white;
background-color: red;
border-radius: 4px;
padding: 4px;
}
.alert-danger {
background-color: red;
}
`
})
export class ErrorMsgComponent {
@Input()
msg: string | null = null;
}

View File

@ -8,7 +8,6 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js" integrity="sha512-ykZ1QQr0Jy/4ZkvKuqWn4iF3lqPZyij9iRv6sGqLRdTPkY69YX6+7wvVGmsdBbiIfN/8OdsI7HABjvEok6ZopQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/css/bootstrap-grid.min.css" integrity="sha512-i1b/nzkVo97VN5WbEtaPebBG8REvjWeqNclJ6AItj7msdVcaveKrlIIByDpvjk5nwHjXkIqGZscVxOrTb9tsMA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/material-design-icons/4.0.0/iconfont/material-icons.min.css" referrerpolicy="no-referrer" />
</head>
<body>
<app-root></app-root>