Browse Source

dynamic form field validator func updated

pull/24547/head
erdemcaygor 11 months ago
parent
commit
b094d5a7f3
  1. 192
      npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.html
  2. 36
      npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.ts
  3. 22
      npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.component.html

192
npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.html

@ -1,100 +1,98 @@
@if (visible()) { @if (visible()) {
@if (field().type === 'text') { @if (field().type === 'text') {
<!-- Text Input --> <!-- Text Input -->
<div class="form-group"> <div class="form-group">
<label [for]="field().key">{{ field().label }}</label> <label [for]="field().key">{{ field().label }}</label>
<input <input
[id]="field().key" [id]="field().key"
[placeholder]="field().placeholder || ''" [placeholder]="field().placeholder || ''"
[ngModel]="value" [ngModel]="value"
(ngModelChange)="onValueChange($event)" (ngModelChange)="onValueChange($event)"
[class.is-invalid]="isValid" [class.is-invalid]="isInvalid"
class="form-control"> class="form-control">
<!-- @if (isFieldInvalid()) { @if (isInvalid) {
<div class="invalid-feedback"> <ng-container [ngTemplateOutlet]="errorTemplate"/>
{{ getErrorMessage() }} }
</div> </div>
}--> } @else if (field().type === 'select') {
</div> <!-- Select Dropdown -->
} @else if (field().type === 'select') { <div class="form-group">
<!-- Select Dropdown --> <label [for]="field().key">{{ field().label }}</label>
<div class="form-group"> <select
<label [for]="field().key">{{ field().label }}</label> [id]="field().key"
<select [ngModel]="value"
[id]="field().key" (ngModelChange)="onValueChange($event)"
[ngModel]="value" [class.is-invalid]="isInvalid"
(ngModelChange)="onValueChange($event)" class="form-control">
[class.is-invalid]="isValid" <option value="">Please select...</option>
class="form-control"> @for (option of field().options; track option.key) {
<option value="">Please select...</option> <option
@for (option of field().options; track option.key) { [value]="option.key">
<option {{ option.value }}
[value]="option.key"> </option>
{{ option.value }} }
</option> </select>
} @if (isInvalid) {
</select> <ng-container [ngTemplateOutlet]="errorTemplate"/>
<!-- @if (isFieldInvalid()) { }
<div class="invalid-feedback"> </div>
{{ getErrorMessage() }} } @else if (field().type === 'checkbox') {
</div> <!-- Checkbox -->
}--> <div class="form-group form-check">
</div> <input
} @else if (field().type === 'checkbox') { type="checkbox"
<!-- Checkbox --> [id]="field().key"
<div class="form-group form-check"> [ngModel]="value"
<input (ngModelChange)="onValueChange($event)"
type="checkbox" [class.is-invalid]="isInvalid"
[id]="field().key" class="form-check-input">
[ngModel]="value" <label class="form-check-label" [for]="field().key">
(ngModelChange)="onValueChange($event)" {{ field().label }}
[class.is-invalid]="isValid" </label>
class="form-check-input"> @if (isInvalid) {
<label class="form-check-label" [for]="field().key"> <ng-container [ngTemplateOutlet]="errorTemplate"/>
{{ field().label }} }
</label> </div>
<!-- @if (isFieldInvalid()) { } @else if (field().type === 'email') {
<div class="invalid-feedback"> <!-- Email Input -->
{{ getErrorMessage() }} <div class="form-group">
</div> <label [for]="field().key">{{ field().label }}</label>
}--> <input
</div> type="email"
} @else if (field().type === 'email') { [id]="field().key"
<!-- Email Input --> [ngModel]="value"
<div class="form-group"> (ngModelChange)="onValueChange($event)"
<label [for]="field().key">{{ field().label }}</label> [placeholder]="field().placeholder || ''"
<input [class.is-invalid]="isInvalid"
type="email" class="form-control">
[id]="field().key" @if (isInvalid) {
[ngModel]="value" <ng-container [ngTemplateOutlet]="errorTemplate"/>
(ngModelChange)="onValueChange($event)" }
[placeholder]="field().placeholder || ''" </div>
[class.is-invalid]="isValid" } @else if (field().type === 'textarea') {
class="form-control"> <!-- Textarea -->
<!-- @if (isFieldInvalid()) { <div class="form-group">
<div class="invalid-feedback"> <label [for]="field().key">{{ field().label }}</label>
{{ getErrorMessage() }} <textarea
</div> [id]="field().key"
}--> [ngModel]="value"
</div> (ngModelChange)="onValueChange($event)"
} @else if (field().type === 'textarea') { [placeholder]="field().placeholder || ''"
<!-- Textarea --> [class.is-invalid]="isInvalid"
<div class="form-group"> rows="4"
<label [for]="field().key">{{ field().label }}</label> class="form-control">
<textarea
[id]="field().key"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[placeholder]="field().placeholder || ''"
[class.is-invalid]="isValid"
rows="4"
class="form-control">
</textarea> </textarea>
<!-- @if (isFieldInvalid()) { @if (isInvalid) {
<div class="invalid-feedback"> <ng-container [ngTemplateOutlet]="errorTemplate"/>
{{ getErrorMessage() }} }
</div> </div>
}--> }
</div>
}
} }
<ng-template #errorTemplate>
<div class="invalid-feedback">
@for (error of errors; track error) {
<div>{{ error }}</div>
}
</div>
</ng-template>

36
npm/ng-packs/packages/components/dynamic-form/src/dynamic-form-field/dynamic-form-field.component.ts

@ -9,22 +9,18 @@ import {
input, input,
OnInit, OnInit,
} from '@angular/core'; } from '@angular/core';
import { NgTemplateOutlet } from '@angular/common';
import { FormFieldConfig } from '../dynamic-form.models'; import { FormFieldConfig } from '../dynamic-form.models';
import { import {
AbstractControl,
ControlValueAccessor, ControlValueAccessor,
FormControl, FormControl,
FormControlName, FormControlName,
FormGroupDirective, FormGroupDirective,
FormsModule, FormsModule,
NG_VALIDATORS,
NG_VALUE_ACCESSOR, NG_VALUE_ACCESSOR,
NgControl, NgControl
ValidationErrors,
Validators,
} from '@angular/forms'; } from '@angular/forms';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { NgTemplateOutlet } from '@angular/common';
export const ABP_DYNAMIC_FORM_FIELD = new InjectionToken<DynamicFormFieldComponent>('AbpDynamicFormField'); export const ABP_DYNAMIC_FORM_FIELD = new InjectionToken<DynamicFormFieldComponent>('AbpDynamicFormField');
@ -45,14 +41,13 @@ const DYNAMIC_FORM_FIELD_CONTROL_VALUE_ACCESSOR = {
host: { class: 'abp-dynamic-form-field' }, host: { class: 'abp-dynamic-form-field' },
exportAs: 'abpDynamicFormField', exportAs: 'abpDynamicFormField',
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [FormsModule], imports: [FormsModule, NgTemplateOutlet],
}) })
export class DynamicFormFieldComponent implements OnInit, ControlValueAccessor { export class DynamicFormFieldComponent implements OnInit, ControlValueAccessor {
field = input.required<FormFieldConfig>(); field = input.required<FormFieldConfig>();
visible = input<boolean>(true); visible = input<boolean>(true);
disabled = false; disabled = false;
value: any; value: any;
isFieldInvalid: boolean = false;
control!: FormControl; control!: FormControl;
readonly changeDetectorRef = inject(ChangeDetectorRef); readonly changeDetectorRef = inject(ChangeDetectorRef);
readonly destroyRef = inject(DestroyRef); readonly destroyRef = inject(DestroyRef);
@ -88,11 +83,30 @@ export class DynamicFormFieldComponent implements OnInit, ControlValueAccessor {
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
} }
get isValid(): boolean { get isInvalid(): boolean {
if (this.control) { if (this.control) {
return this.control.invalid && (this.control.dirty || this.control.touched); return (this.control.invalid && (this.control.dirty || this.control.touched));
}
return false;
}
get errors(): string[] {
if (this.control && this.control.errors) {
const errorKeys = Object.keys(this.control.errors);
return errorKeys.map(key => {
const validator = this.field().validators.find(v => v.type.toLowerCase() === key.toLowerCase());
console.log(this.field().validators, key);
if (validator && validator.message) {
return validator.message;
}
// Fallback error messages
if (key === 'required') return `${this.field().label} is required`;
if (key === 'email') return 'Please enter a valid email address';
if (key === 'minlength') return `Minimum length is ${this.control.errors[key].requiredLength}`;
if (key === 'maxlength') return `Maximum length is ${this.control.errors[key].requiredLength}`;
return `${this.field().label} is invalid due to ${key} validation.`;
});
} }
return true;
} }
private onChange: (value: any) => void = () => {}; private onChange: (value: any) => void = () => {};

22
npm/ng-packs/packages/components/dynamic-form/src/dynamic-form.component.html

@ -1,15 +1,15 @@
<form [formGroup]="dynamicForm" (ngSubmit)="onSubmit()" class="dynamic-form"> <form [formGroup]="dynamicForm" (ngSubmit)="onSubmit()" class="dynamic-form">
@for (field of sortedFields; track field.key) { <div class="row">
<div class="row"> @for (field of sortedFields; track field.key) {
<div [ngClass]="'col-md-' + (field.gridSize || 12)"> <div [ngClass]="'col-md-' + (field.gridSize || 12)">
<abp-dynamic-form-field <abp-dynamic-form-field
[field]="field" [field]="field"
[formControlName]="field.key" [formControlName]="field.key"
[visible]="isFieldVisible(field)"> [visible]="isFieldVisible(field)">
</abp-dynamic-form-field> </abp-dynamic-form-field>
</div> </div>
</div> }
} </div>
<ng-content select="[actions]"> <ng-content select="[actions]">
<ng-container [ngTemplateOutlet]="defaultActions"></ng-container> <ng-container [ngTemplateOutlet]="defaultActions"></ng-container>
</ng-content> </ng-content>

Loading…
Cancel
Save