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 (field().type === 'text') {
<!-- Text Input -->
<div class="form-group">
<label [for]="field().key">{{ field().label }}</label>
<input
[id]="field().key"
[placeholder]="field().placeholder || ''"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[class.is-invalid]="isValid"
class="form-control">
<!-- @if (isFieldInvalid()) {
<div class="invalid-feedback">
{{ getErrorMessage() }}
</div>
}-->
</div>
} @else if (field().type === 'select') {
<!-- Select Dropdown -->
<div class="form-group">
<label [for]="field().key">{{ field().label }}</label>
<select
[id]="field().key"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[class.is-invalid]="isValid"
class="form-control">
<option value="">Please select...</option>
@for (option of field().options; track option.key) {
<option
[value]="option.key">
{{ option.value }}
</option>
}
</select>
<!-- @if (isFieldInvalid()) {
<div class="invalid-feedback">
{{ getErrorMessage() }}
</div>
}-->
</div>
} @else if (field().type === 'checkbox') {
<!-- Checkbox -->
<div class="form-group form-check">
<input
type="checkbox"
[id]="field().key"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[class.is-invalid]="isValid"
class="form-check-input">
<label class="form-check-label" [for]="field().key">
{{ field().label }}
</label>
<!-- @if (isFieldInvalid()) {
<div class="invalid-feedback">
{{ getErrorMessage() }}
</div>
}-->
</div>
} @else if (field().type === 'email') {
<!-- Email Input -->
<div class="form-group">
<label [for]="field().key">{{ field().label }}</label>
<input
type="email"
[id]="field().key"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[placeholder]="field().placeholder || ''"
[class.is-invalid]="isValid"
class="form-control">
<!-- @if (isFieldInvalid()) {
<div class="invalid-feedback">
{{ getErrorMessage() }}
</div>
}-->
</div>
} @else if (field().type === 'textarea') {
<!-- Textarea -->
<div class="form-group">
<label [for]="field().key">{{ field().label }}</label>
<textarea
[id]="field().key"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[placeholder]="field().placeholder || ''"
[class.is-invalid]="isValid"
rows="4"
class="form-control">
@if (field().type === 'text') {
<!-- Text Input -->
<div class="form-group">
<label [for]="field().key">{{ field().label }}</label>
<input
[id]="field().key"
[placeholder]="field().placeholder || ''"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[class.is-invalid]="isInvalid"
class="form-control">
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</div>
} @else if (field().type === 'select') {
<!-- Select Dropdown -->
<div class="form-group">
<label [for]="field().key">{{ field().label }}</label>
<select
[id]="field().key"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[class.is-invalid]="isInvalid"
class="form-control">
<option value="">Please select...</option>
@for (option of field().options; track option.key) {
<option
[value]="option.key">
{{ option.value }}
</option>
}
</select>
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</div>
} @else if (field().type === 'checkbox') {
<!-- Checkbox -->
<div class="form-group form-check">
<input
type="checkbox"
[id]="field().key"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[class.is-invalid]="isInvalid"
class="form-check-input">
<label class="form-check-label" [for]="field().key">
{{ field().label }}
</label>
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</div>
} @else if (field().type === 'email') {
<!-- Email Input -->
<div class="form-group">
<label [for]="field().key">{{ field().label }}</label>
<input
type="email"
[id]="field().key"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[placeholder]="field().placeholder || ''"
[class.is-invalid]="isInvalid"
class="form-control">
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</div>
} @else if (field().type === 'textarea') {
<!-- Textarea -->
<div class="form-group">
<label [for]="field().key">{{ field().label }}</label>
<textarea
[id]="field().key"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
[placeholder]="field().placeholder || ''"
[class.is-invalid]="isInvalid"
rows="4"
class="form-control">
</textarea>
<!-- @if (isFieldInvalid()) {
<div class="invalid-feedback">
{{ getErrorMessage() }}
</div>
}-->
</div>
}
@if (isInvalid) {
<ng-container [ngTemplateOutlet]="errorTemplate"/>
}
</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,
OnInit,
} from '@angular/core';
import { NgTemplateOutlet } from '@angular/common';
import { FormFieldConfig } from '../dynamic-form.models';
import {
AbstractControl,
ControlValueAccessor,
FormControl,
FormControlName,
FormGroupDirective,
FormsModule,
NG_VALIDATORS,
NG_VALUE_ACCESSOR,
NgControl,
ValidationErrors,
Validators,
NgControl
} from '@angular/forms';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { NgTemplateOutlet } from '@angular/common';
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' },
exportAs: 'abpDynamicFormField',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [FormsModule],
imports: [FormsModule, NgTemplateOutlet],
})
export class DynamicFormFieldComponent implements OnInit, ControlValueAccessor {
field = input.required<FormFieldConfig>();
visible = input<boolean>(true);
disabled = false;
value: any;
isFieldInvalid: boolean = false;
control!: FormControl;
readonly changeDetectorRef = inject(ChangeDetectorRef);
readonly destroyRef = inject(DestroyRef);
@ -88,11 +83,30 @@ export class DynamicFormFieldComponent implements OnInit, ControlValueAccessor {
this.changeDetectorRef.markForCheck();
}
get isValid(): boolean {
get isInvalid(): boolean {
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 = () => {};

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

Loading…
Cancel
Save