From 6e5eadd3a2ef0a84fcafd76df70e1d3b8dcd6f64 Mon Sep 17 00:00:00 2001 From: Jan-Marlon Leibl Date: Tue, 3 Dec 2024 09:20:59 +0100 Subject: [PATCH] add better validation to forms --- src/app/app.routes.ts | 4 +++ src/app/form.guard.spec.ts | 17 ++++++++++++ src/app/form.guard.ts | 15 +++++++++++ .../hotel-details.component.html | 4 +-- .../hotel-details/hotel-details.component.ts | 15 ++++++----- src/app/hotel-form/hotel-form.component.html | 17 +++++++++--- src/app/hotel-form/hotel-form.component.ts | 6 +++-- src/app/hotel-list/hotel-list.component.html | 26 ++++++++++++++++--- 8 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 src/app/form.guard.spec.ts create mode 100644 src/app/form.guard.ts diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 9d06d6e..46c3c18 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -2,6 +2,8 @@ import { Routes } from '@angular/router'; import { HotelDetailsComponent } from './hotel-details/hotel-details.component'; import { HotelListComponent } from './hotel-list/hotel-list.component'; import { HotelFormComponent } from './hotel-form/hotel-form.component'; +import { inject } from '@angular/core'; +import { formGuard } from './form.guard'; export const routes: Routes = [ { @@ -11,9 +13,11 @@ export const routes: Routes = [ { path: "hotels/:id", component: HotelDetailsComponent, + canDeactivate: [formGuard], }, { path: "create-hotel", component: HotelFormComponent, + canDeactivate: [formGuard], }, ]; diff --git a/src/app/form.guard.spec.ts b/src/app/form.guard.spec.ts new file mode 100644 index 0000000..1c3d01f --- /dev/null +++ b/src/app/form.guard.spec.ts @@ -0,0 +1,17 @@ +import { TestBed } from '@angular/core/testing'; +import { CanDeactivateFn } from '@angular/router'; + +import { formGuard } from './form.guard'; + +describe('formGuard', () => { + const executeGuard: CanDeactivateFn = (...guardParameters) => + TestBed.runInInjectionContext(() => formGuard(...guardParameters)); + + beforeEach(() => { + TestBed.configureTestingModule({}); + }); + + it('should be created', () => { + expect(executeGuard).toBeTruthy(); + }); +}); diff --git a/src/app/form.guard.ts b/src/app/form.guard.ts new file mode 100644 index 0000000..bec14c4 --- /dev/null +++ b/src/app/form.guard.ts @@ -0,0 +1,15 @@ +import { CanDeactivateFn } from '@angular/router'; +import { HotelFormComponent } from './hotel-form/hotel-form.component'; +import { HotelDetailsComponent } from './hotel-details/hotel-details.component'; + +export const formGuard: CanDeactivateFn = (component: HotelFormComponent | HotelDetailsComponent, currentRoute, currentState, nextState) => { + console.log(component) + if (component instanceof HotelFormComponent && component.form?.dirty) { + return confirm('You have unsaved changes. Do you really want to leave?'); + } + else if (component instanceof HotelDetailsComponent && component.hotelForm?.form?.dirty) { + return confirm('You have unsaved changes. Do you really want to leave?'); + } + + return true; +}; diff --git a/src/app/hotel-details/hotel-details.component.html b/src/app/hotel-details/hotel-details.component.html index 2ba9075..9f26099 100644 --- a/src/app/hotel-details/hotel-details.component.html +++ b/src/app/hotel-details/hotel-details.component.html @@ -1,5 +1,5 @@
-
- +
+
diff --git a/src/app/hotel-details/hotel-details.component.ts b/src/app/hotel-details/hotel-details.component.ts index aac11b2..750c869 100644 --- a/src/app/hotel-details/hotel-details.component.ts +++ b/src/app/hotel-details/hotel-details.component.ts @@ -1,23 +1,24 @@ import { HttpClient } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import {ActivatedRoute, Router, RouterLink} from '@angular/router'; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; import { Hotel } from '../HotelItem/hotel'; -import {CurrencyPipe, NgIf} from '@angular/common'; -import { StarRatingComponent } from '../star-rating/star-rating.component'; -import { HotelItem } from '../HotelItem/HotelItem.component'; +import { NgIf } from '@angular/common'; import { catchError, EMPTY } from 'rxjs'; -import {HotelFormComponent} from "../hotel-form/hotel-form.component"; +import { HotelFormComponent } from "../hotel-form/hotel-form.component"; @Component({ selector: 'app-hotel-details', standalone: true, - imports: [CurrencyPipe, StarRatingComponent, HotelItem, HotelFormComponent, NgIf, RouterLink], + imports: [HotelFormComponent, NgIf], templateUrl: './hotel-details.component.html', styleUrl: './hotel-details.component.css' }) export class HotelDetailsComponent implements OnInit { public hotel: any; + @ViewChild('hotelForm', { static: false }) + public hotelForm!: HotelFormComponent; + constructor(private route: ActivatedRoute, private http: HttpClient, private router: Router) { } ngOnInit(): void { diff --git a/src/app/hotel-form/hotel-form.component.html b/src/app/hotel-form/hotel-form.component.html index 93aa829..36b5ad9 100644 --- a/src/app/hotel-form/hotel-form.component.html +++ b/src/app/hotel-form/hotel-form.component.html @@ -57,7 +57,7 @@ delete
- +
@@ -65,8 +65,19 @@
- + +
+
+

Confirm Deletion

+

Are you sure you want to delete this hotel?

+
+ + +
+
+
\ No newline at end of file diff --git a/src/app/hotel-form/hotel-form.component.ts b/src/app/hotel-form/hotel-form.component.ts index c23ec43..0323c9a 100644 --- a/src/app/hotel-form/hotel-form.component.ts +++ b/src/app/hotel-form/hotel-form.component.ts @@ -1,4 +1,4 @@ -import { Component, inject, Inject, Input } from '@angular/core'; +import { Component, HostListener, inject, Inject, Input } from '@angular/core'; import { FormArray, FormControl, FormGroup, ReactiveFormsModule, Validators } from "@angular/forms"; import { Hotel } from "../HotelItem/hotel"; import { HttpClient } from '@angular/common/http'; @@ -32,6 +32,8 @@ export class HotelFormComponent { public router: Router = inject(Router); + public showDeleteConfirmation = false; + constructor(private http: HttpClient) {} ngOnInit() { @@ -66,7 +68,7 @@ export class HotelFormComponent { } public submit() { - if (this.form.valid) { + if (this.form.valid && !this.form.dirty) { const hotelData: Hotel = { id: this.hotel?.id || 0, hotelName: this.form.value.name, diff --git a/src/app/hotel-list/hotel-list.component.html b/src/app/hotel-list/hotel-list.component.html index 6f2d94c..be67e98 100644 --- a/src/app/hotel-list/hotel-list.component.html +++ b/src/app/hotel-list/hotel-list.component.html @@ -1,10 +1,28 @@
-

{{'hello' | uppercase | text}}

- - -
+
+
+

{{'hello' | uppercase | text}}

+ + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+