Validierung Part II, neue Komponenten
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { ControlValueAccessor } from '@angular/forms';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { ValidationMessagesService } from '../validation-messages.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-base-input',
|
||||
template: ``,
|
||||
standalone: true,
|
||||
imports: [],
|
||||
})
|
||||
export abstract class BaseInputComponent implements ControlValueAccessor {
|
||||
@Input() value: any = '';
|
||||
validationMessage: string = '';
|
||||
onChange: any = () => {};
|
||||
onTouched: any = () => {};
|
||||
subscription: Subscription | null = null;
|
||||
@Input() label: string = '';
|
||||
// @Input() id: string = '';
|
||||
@Input() name: string = '';
|
||||
constructor(protected validationMessagesService: ValidationMessagesService) {}
|
||||
ngOnInit() {
|
||||
this.subscription = this.validationMessagesService.messages$.subscribe(() => {
|
||||
this.updateValidationMessage();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.subscription) {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
writeValue(value: any): void {
|
||||
if (value !== undefined) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
registerOnChange(fn: any): void {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: any): void {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
updateValidationMessage(): void {
|
||||
this.validationMessage = this.validationMessagesService.getMessage(this.name);
|
||||
}
|
||||
setDisabledState?(isDisabled: boolean): void {}
|
||||
}
|
||||
@@ -1,22 +1,24 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core';
|
||||
import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { Component, EventEmitter, forwardRef, Output } from '@angular/core';
|
||||
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { BaseInputComponent } from '../base-input/base-input.component';
|
||||
import { ValidationMessagesService } from '../validation-messages.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-validated-input',
|
||||
template: `
|
||||
<div>
|
||||
<label [for]="id" class="block text-sm font-medium text-gray-700">
|
||||
<label [for]="name" class="block text-sm font-medium text-gray-700">
|
||||
{{ label }}
|
||||
<span class="text-red-500 ml-1">{{ validationMessage }}</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
[id]="name"
|
||||
[ngModel]="value"
|
||||
(input)="onInputChange($event)"
|
||||
(blur)="onTouched()"
|
||||
[attr.name]="name"
|
||||
[required]="required"
|
||||
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
@@ -31,32 +33,11 @@ import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/f
|
||||
},
|
||||
],
|
||||
})
|
||||
export class ValidatedInputComponent implements ControlValueAccessor {
|
||||
@Input() label: string = '';
|
||||
@Input() id: string = '';
|
||||
@Input() name: string = '';
|
||||
@Input() type: string = 'text';
|
||||
@Input() required: boolean = false;
|
||||
@Input() validationMessage: string = '';
|
||||
|
||||
@Input() value: any = '';
|
||||
export class ValidatedInputComponent extends BaseInputComponent {
|
||||
@Output() valueChange = new EventEmitter<any>();
|
||||
|
||||
onChange: any = () => {};
|
||||
onTouched: any = () => {};
|
||||
|
||||
writeValue(value: any): void {
|
||||
if (value !== undefined) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
registerOnChange(fn: any): void {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: any): void {
|
||||
this.onTouched = fn;
|
||||
constructor(validationMessagesService: ValidationMessagesService) {
|
||||
super(validationMessagesService);
|
||||
}
|
||||
|
||||
onInputChange(event: Event): void {
|
||||
@@ -65,8 +46,4 @@ export class ValidatedInputComponent implements ControlValueAccessor {
|
||||
this.onChange(value);
|
||||
this.valueChange.emit(value);
|
||||
}
|
||||
|
||||
setDisabledState?(isDisabled: boolean): void {
|
||||
// Implementieren Sie dies, wenn Sie die Deaktivierung des Inputs unterstützen möchten
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, forwardRef } from '@angular/core';
|
||||
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { QuillModule } from 'ngx-quill';
|
||||
import { BaseInputComponent } from '../base-input/base-input.component';
|
||||
import { ValidationMessagesService } from '../validation-messages.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-validated-quill',
|
||||
template: `
|
||||
<div>
|
||||
<label [for]="name" class="block text-sm font-medium text-gray-700">
|
||||
{{ label }}
|
||||
<span class="text-red-500 ml-1">{{ validationMessage }}</span>
|
||||
</label>
|
||||
<quill-editor [(ngModel)]="value" (ngModelChange)="onInputChange($event)" (onBlur)="onTouched()" [id]="name" [attr.name]="name" [modules]="quillModules"></quill-editor>
|
||||
</div>
|
||||
`,
|
||||
standalone: true,
|
||||
imports: [CommonModule, FormsModule, QuillModule],
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => ValidatedQuillComponent),
|
||||
multi: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class ValidatedQuillComponent extends BaseInputComponent {
|
||||
quillModules = {
|
||||
toolbar: [['bold', 'italic', 'underline', 'strike'], [{ list: 'ordered' }, { list: 'bullet' }], [{ header: [1, 2, 3, 4, 5, 6, false] }], [{ color: [] }, { background: [] }], ['clean']],
|
||||
};
|
||||
constructor(validationMessagesService: ValidationMessagesService) {
|
||||
super(validationMessagesService);
|
||||
}
|
||||
|
||||
onInputChange(event: Event): void {
|
||||
this.value = event;
|
||||
this.onChange(this.value);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,23 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core';
|
||||
import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { BaseInputComponent } from '../base-input/base-input.component';
|
||||
import { ValidationMessagesService } from '../validation-messages.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-validated-select',
|
||||
template: `
|
||||
<div>
|
||||
<label [for]="id" class="block text-sm font-medium text-gray-700">
|
||||
<label [for]="name" class="block text-sm font-medium text-gray-700">
|
||||
{{ label }}
|
||||
<span class="text-red-500 ml-1">{{ validationMessage }}</span>
|
||||
</label>
|
||||
<select
|
||||
[id]="id"
|
||||
[id]="name"
|
||||
[name]="name"
|
||||
[ngModel]="value"
|
||||
(change)="onSelectChange($event)"
|
||||
(blur)="onTouched()"
|
||||
[required]="required"
|
||||
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
|
||||
>
|
||||
<option value="" disabled selected>Select an option</option>
|
||||
@@ -36,32 +37,14 @@ import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/f
|
||||
},
|
||||
],
|
||||
})
|
||||
export class ValidatedSelectComponent implements ControlValueAccessor {
|
||||
@Input() label: string = '';
|
||||
@Input() id: string = '';
|
||||
@Input() name: string = '';
|
||||
@Input() required: boolean = false;
|
||||
@Input() validationMessage: string = '';
|
||||
export class ValidatedSelectComponent extends BaseInputComponent {
|
||||
// @Input() required: boolean = false;
|
||||
// @Input() validationMessage: string = '';
|
||||
@Input() options: Array<{ value: any; label: string }> = [];
|
||||
|
||||
@Input() value: any = '';
|
||||
@Output() valueChange = new EventEmitter<any>();
|
||||
|
||||
onChange: any = () => {};
|
||||
onTouched: any = () => {};
|
||||
|
||||
writeValue(value: any): void {
|
||||
if (value !== undefined) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
registerOnChange(fn: any): void {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: any): void {
|
||||
this.onTouched = fn;
|
||||
constructor(validationMessagesService: ValidationMessagesService) {
|
||||
super(validationMessagesService);
|
||||
}
|
||||
|
||||
onSelectChange(event: Event): void {
|
||||
@@ -70,8 +53,4 @@ export class ValidatedSelectComponent implements ControlValueAccessor {
|
||||
this.onChange(value);
|
||||
this.valueChange.emit(value);
|
||||
}
|
||||
|
||||
setDisabledState?(isDisabled: boolean): void {
|
||||
// Implementieren Sie dies, wenn Sie die Deaktivierung des Selects unterstützen möchten
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, EventEmitter, forwardRef, Output } from '@angular/core';
|
||||
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { BaseInputComponent } from '../base-input/base-input.component';
|
||||
import { ValidationMessagesService } from '../validation-messages.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-validated-textarea',
|
||||
template: `
|
||||
<div>
|
||||
<label [for]="name" class="block text-sm font-medium text-gray-700">
|
||||
{{ label }}
|
||||
<span class="text-red-500 ml-1">{{ validationMessage }}</span>
|
||||
</label>
|
||||
<textarea [id]="name" [ngModel]="value" (ngModelChange)="onInputChange($event)" [attr.name]="name" class="w-full p-2 border border-gray-300 rounded-md" rows="3"></textarea>
|
||||
</div>
|
||||
`,
|
||||
standalone: true,
|
||||
imports: [CommonModule, FormsModule],
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => ValidatedTextareaComponent),
|
||||
multi: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class ValidatedTextareaComponent extends BaseInputComponent {
|
||||
@Output() valueChange = new EventEmitter<any>();
|
||||
|
||||
constructor(validationMessagesService: ValidationMessagesService) {
|
||||
super(validationMessagesService);
|
||||
}
|
||||
|
||||
onInputChange(event: Event): void {
|
||||
this.value = event;
|
||||
this.onChange(this.value);
|
||||
}
|
||||
}
|
||||
31
bizmatch/src/app/components/validation-messages.service.ts
Normal file
31
bizmatch/src/app/components/validation-messages.service.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { Injectable, InjectionToken } from '@angular/core';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
|
||||
export interface ValidationMessage {
|
||||
field: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export const VALIDATION_MESSAGES = new InjectionToken<ValidationMessagesService>('VALIDATION_MESSAGES');
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ValidationMessagesService {
|
||||
private messagesSubject = new BehaviorSubject<ValidationMessage[]>([]);
|
||||
messages$: Observable<ValidationMessage[]> = this.messagesSubject.asObservable();
|
||||
|
||||
updateMessages(messages: ValidationMessage[]): void {
|
||||
this.messagesSubject.next(messages);
|
||||
}
|
||||
|
||||
clearMessages(): void {
|
||||
this.messagesSubject.next([]);
|
||||
}
|
||||
|
||||
getMessage(field: string): string | null {
|
||||
const messages = this.messagesSubject.value;
|
||||
const message = messages.find(m => m.field === field);
|
||||
return message ? message.message : null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user