Compare commits

..

2 Commits

Author SHA1 Message Date
Igor Hrenowitsch Propisnov 95aa8d6b11 Implement edit icon to dropdown 2024-07-30 16:44:04 +02:00
Igor Hrenowitsch Propisnov 52d4245338 Added validation 2024-07-30 16:43:52 +02:00
4 changed files with 76 additions and 30 deletions

View File

@ -7,23 +7,12 @@
<span class="label-text">Location Name</span> <span class="label-text">Location Name</span>
<span class="label-text-alt">Name of the location</span> <span class="label-text-alt">Name of the location</span>
</div> </div>
<div class="input input-bordered flex items-center gap-2"> <input
<input [ngClass]="getInputClass('name')"
formControlName="name" formControlName="name"
type="text" type="text"
class="grow" class="input input-bordered w-full"
placeholder="" /> placeholder="" />
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="h-4 w-4 opacity-70">
<path
fill-rule="evenodd"
d="M9.965 11.026a5 5 0 1 1 1.06-1.06l2.755 2.754a.75.75 0 1 1-1.06 1.06l-2.755-2.754ZM10.5 7a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Z"
clip-rule="evenodd" />
</svg>
</div>
<div class="label"> <div class="label">
<span class="label-text-alt"></span> <span class="label-text-alt"></span>
<span class="label-text-alt"></span> <span class="label-text-alt"></span>
@ -37,6 +26,7 @@
<span class="label-text-alt"></span> <span class="label-text-alt"></span>
</div> </div>
<input <input
[ngClass]="getInputClass('postalCode')"
type="text" type="text"
formControlName="postalCode" formControlName="postalCode"
class="input input-bordered w-full" /> class="input input-bordered w-full" />
@ -52,6 +42,7 @@
<span class="label-text-alt">Name of the city</span> <span class="label-text-alt">Name of the city</span>
</div> </div>
<input <input
[ngClass]="getInputClass('city')"
type="text" type="text"
formControlName="city" formControlName="city"
class="input input-bordered w-full" /> class="input input-bordered w-full" />
@ -69,6 +60,7 @@
<span class="label-text-alt">Name of the street</span> <span class="label-text-alt">Name of the street</span>
</div> </div>
<input <input
[ngClass]="getInputClass('street')"
type="text" type="text"
formControlName="street" formControlName="street"
class="input input-bordered w-full" /> class="input input-bordered w-full" />
@ -84,6 +76,7 @@
<span class="label-text-alt"></span> <span class="label-text-alt"></span>
</div> </div>
<input <input
[ngClass]="getInputClass('houseNumber')"
type="text" type="text"
formControlName="houseNumber" formControlName="houseNumber"
class="input input-bordered w-full" /> class="input input-bordered w-full" />

View File

@ -1,5 +1,11 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { Component, output, OutputEmitterRef } from '@angular/core'; import {
Component,
output,
OutputEmitterRef,
signal,
WritableSignal,
} from '@angular/core';
import { import {
FormBuilder, FormBuilder,
FormGroup, FormGroup,
@ -24,18 +30,33 @@ export class LocationDialogComponent {
public locationCreated: OutputEmitterRef<EventLocation> = public locationCreated: OutputEmitterRef<EventLocation> =
output<EventLocation>(); output<EventLocation>();
public locationForm: FormGroup = new FormGroup({}); public locationForm: FormGroup = new FormGroup({});
public formSubmitted: WritableSignal<boolean> = signal<boolean>(false);
public constructor(private readonly formBuilder: FormBuilder) { public constructor(private readonly formBuilder: FormBuilder) {
this.locationForm = this.formBuilder.group({ this.locationForm = this.formBuilder.group({
name: ['', [Validators.required, Validators.minLength(3)]],
postalCode: ['', [Validators.required, Validators.pattern(/^\d{5}$/)]], postalCode: ['', [Validators.required, Validators.pattern(/^\d{5}$/)]],
city: ['', Validators.required], city: ['', [Validators.required, Validators.minLength(2)]],
street: ['', Validators.required], street: ['', [Validators.required, Validators.minLength(3)]],
houseNumber: ['', Validators.required], houseNumber: [
name: ['', Validators.required], '',
[Validators.required, Validators.pattern(/^[0-9]+[a-zA-Z]?$/)],
],
}); });
} }
public getInputClass(controlName: string): string {
const control = this.locationForm.get(controlName);
if ((control?.dirty || this.formSubmitted()) && control?.touched) {
return control.valid ? 'input-success' : 'input-error';
}
return '';
}
public createLocation(): void { public createLocation(): void {
this.formSubmitted.set(true);
this.locationForm.markAllAsTouched();
if (this.locationForm.valid) { if (this.locationForm.valid) {
this.locationCreated.emit(this.locationForm.value); this.locationCreated.emit(this.locationForm.value);
this.closeModal(); this.closeModal();
@ -47,6 +68,10 @@ export class LocationDialogComponent {
'location_modal' 'location_modal'
) as HTMLDialogElement; ) as HTMLDialogElement;
this.locationForm.reset();
this.locationForm.markAsUntouched();
this.locationForm.markAsPristine();
this.formSubmitted.set(false);
modal.showModal(); modal.showModal();
} }

View File

@ -35,12 +35,14 @@
@if (filteredItems().length > 0) { @if (filteredItems().length > 0) {
@for (item of filteredItems(); track item) { @for (item of filteredItems(); track item) {
<li> <li>
<a <div class="flex justify-between items-center w-full">
(mousedown)="selectItem(item)" <span
class="flex justify-between items-center" (mousedown)="selectItem(item)"
[class.font-bold]="item === selectedItem()" class="flex-grow cursor-pointer"
[class.text-primary]="item === selectedItem()"> [class.font-bold]="item === selectedItem()"
<span>{{ item }}</span> [class.text-primary]="item === selectedItem()">
{{ item }}
</span>
@if (item === selectedItem()) { @if (item === selectedItem()) {
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -48,14 +50,32 @@
viewBox="0 0 24 24" viewBox="0 0 24 24"
stroke-width="1.5" stroke-width="1.5"
stroke="currentColor" stroke="currentColor"
class="size-6"> class="size-6 text-primary">
<path <path
stroke-linecap="round" stroke-linecap="round"
stroke-linejoin="round" stroke-linejoin="round"
d="m4.5 12.75 6 6 9-13.5" /> d="m4.5 12.75 6 6 9-13.5" />
</svg> </svg>
} @else {
<div
class="tooltip tooltip-info"
data-tip="Edit this location's details. You can modify the name, address, or any other relevant information associated with this place.">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-6 cursor-pointer"
(mousedown)="editItem(item, $event)">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
</svg>
</div>
} }
</a> </div>
</li> </li>
} }
<div class="divider">{{ dividerText() }}</div> <div class="divider">{{ dividerText() }}</div>

View File

@ -35,6 +35,7 @@ export class DropdownComponent {
); );
public itemSelected: OutputEmitterRef<string> = output<string>(); public itemSelected: OutputEmitterRef<string> = output<string>();
public submitNewItems: OutputEmitterRef<boolean> = output<boolean>(); public submitNewItems: OutputEmitterRef<boolean> = output<boolean>();
public itemEdit: OutputEmitterRef<string> = output<string>();
public onInput(event: Event): void { public onInput(event: Event): void {
const value = (event.target as HTMLInputElement).value; const value = (event.target as HTMLInputElement).value;
@ -62,6 +63,13 @@ export class DropdownComponent {
this.showDropdown.set(true); this.showDropdown.set(true);
} }
public editItem(item: string, event: MouseEvent): void {
event.preventDefault();
event.stopPropagation();
// TODO: Implement edit item functionality
this.itemEdit.emit(item);
}
public selectItem(item: string): void { public selectItem(item: string): void {
this.searchTerm.set(item); this.searchTerm.set(item);
this.selectedItem.set(item); this.selectedItem.set(item);