material-dynamic-forms
Version:
¡Crea formularios dinámicos, potentes y configurables en Angular usando Material Design! 🚀
255 lines • 95 kB
JavaScript
import { Component, EventEmitter, Inject, Input, Output } from '@angular/core';
import { eDataType, } from './interfaces/fieldDynamicForm.interface';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, } from '@angular/material/core';
import { DynamicFormService } from './dynamic-form.service';
import { APP_DATE_FORMATS, AppDateAdapter } from './utils/date.adapter';
import * as i0 from "@angular/core";
import * as i1 from "@angular/material/dialog";
import * as i2 from "./dynamic-form.service";
import * as i3 from "@angular/common";
import * as i4 from "@angular/forms";
import * as i5 from "@angular/material/checkbox";
import * as i6 from "@angular/material/icon";
import * as i7 from "@angular/material/button";
import * as i8 from "@angular/material/form-field";
import * as i9 from "@angular/material/select";
import * as i10 from "@angular/material/core";
import * as i11 from "@angular/material/button-toggle";
import * as i12 from "@angular/material/input";
import * as i13 from "@angular/material/divider";
import * as i14 from "@angular/material/datepicker";
import * as i15 from "primeng/multiselect";
import * as i16 from "primeng/dropdown";
import * as i17 from "primeng/autocomplete";
export class DynamicFormComponent {
constructor(data, modal, dynamicFormService) {
this.data = data;
this.modal = modal;
this.dynamicFormService = dynamicFormService;
this.isModal = false;
this.isEdit = false;
this.isReadonlyForm = false;
this.changeValueSelected = new EventEmitter();
this.formValidityChange = new EventEmitter();
this.externalDependenciesValuesChanged = new EventEmitter();
this.eDataType = eDataType;
this.title = '';
this.titleButton = 'Guardar';
this.selectedOption = null;
}
ngOnInit() {
this.inizializarForm();
}
ngOnDestroy() {
this.form.reset();
}
ngOnChanges(changes) {
// Detecta si el valor de resetFormTrigger cambia
if (changes['resetFormTrigger'] &&
changes['resetFormTrigger'].currentValue) {
this.form.reset(); // Resetea el formulario
}
// Detecta si el valor de baseUrl cambia
if (changes['baseUrl'] &&
changes['baseUrl'].currentValue) {
this.dynamicFormService.setBaseUrl(this.baseUrl);
}
// Detecta si el valor de isEdit cambia
if (changes['isEdit'] &&
changes['isEdit'].currentValue) {
this.dynamicFormService.setEditMode(this.isEdit);
}
}
inizializarForm() {
if (this.isReadonlyForm) {
this.dynamicFormService.setReadonly(true);
}
// En el caso que se esta utilizando un formulario desde una modal MatDialog
if (this.data?.dataForm) {
this.fieldGroups = this.data.dataForm.fieldGroups;
this.isModal = true;
this.title = this.data.title;
this.titleButton = this.data.dataForm.titleButtonAcceptForm;
if (this.data.dataForm.baseUrl) {
this.dynamicFormService.setBaseUrl(this.data.dataForm.baseUrl);
this.baseUrl = this.data.dataForm.baseUrl;
}
if (this.data.dataForm.form) {
this.form = this.data.dataForm.form;
}
if (this.data.dataForm.edit) {
this.isEdit = this.data.dataForm.edit;
this.dynamicFormService.setEditMode(this.data.dataForm.edit);
}
}
// Inicializa el formulario
if (this.fieldGroups) {
this.form = this.dynamicFormService.functionInitComponent(this.fieldGroups, this.form);
// Manejar campos con dependencias externas
this.fieldGroups.forEach((group) => {
group.fields.forEach((field) => {
if (field.externalDependencies) {
this.handleExternalDependencies(field);
}
});
});
}
// Emito la validacion actual del form
this.formValidityChange.emit(this.form.valid);
// Escucha los cambios de estado del formulario y emite el resultado
this.form.statusChanges.subscribe(() => {
this.formValidityChange.emit(this.form.valid);
});
}
/**
* Método para manejar dependencias externas.
*/
handleExternalDependencies(field) {
const control = this.form.get(field.name);
// Llamamos al servicio
const checkDependencies = this.dynamicFormService.handleExternalDependenciesService(field, control);
// Suscribimos el EventEmitter para volver a verificar las dependencias
// cuando cambien los valores externos
this.externalDependenciesValuesChanged.subscribe(() => {
checkDependencies?.();
});
}
// Método para actualizar las dependencias externas
updateExternalDependencies(values) {
// Actualizas la variable en el servicio
this.dynamicFormService.setExternalDependenciesValues(values);
// Emite el evento si deseas que otros sitios en el componente reaccionen
this.externalDependenciesValuesChanged.emit();
}
// Método para actualizar el valor de un campo del formulario
updateFormField(fieldName, value) {
if (this.form && this.form.controls[fieldName]) {
this.form.controls[fieldName].setValue(value);
}
}
/**
* Función pública para deshabilitar un campo específico
* @param fieldName Nombre del campo a deshabilitar
*/
disableField(fieldName) {
const control = this.form.get(fieldName);
if (control) {
control.disable();
}
else {
console.warn(`El campo con nombre "${fieldName}" no existe en el formulario.`);
}
}
/**
* Función pública para habilitar un campo específico
* @param fieldName Nombre del campo a habilitar
*/
enableField(fieldName) {
const control = this.form.get(fieldName);
if (control) {
control.enable();
}
else {
console.warn(`El campo con nombre "${fieldName}" no existe en el formulario.`);
}
}
removeExternalDependency(key) {
this.dynamicFormService.removeExternalDependency(key);
this.externalDependenciesValuesChanged.emit();
}
refreshDependentFields() {
// Emit the event to refresh dependencies
this.externalDependenciesValuesChanged.emit();
}
simulateFieldChange(fieldName) {
const control = this.form.get(fieldName);
if (control) {
const currentValue = control.value;
control.setValue(currentValue);
}
}
getFormFieldValue(fieldName) {
return this.form.get(fieldName)?.value;
}
onSubmit() {
let listadoFormGet = this.dynamicFormService.functionGetFormValue(this.form, this.fieldGroups);
this.modal.close(listadoFormGet);
}
emitEvent(nameForm, event) {
let value;
value = this.form.get(nameForm.name)?.value;
if (event) {
value = event.value;
}
this.changeValueSelected.emit({ form: nameForm, value: value });
}
getForm() {
return this.form;
}
getErrorMessage(fieldName) {
const control = this.form.get(fieldName);
if (control?.hasError('required')) {
return 'Este campo es obligatorio';
}
if (control?.hasError('min')) {
return `El valor debe ser mayor o igual a ${control.getError('min').min}`;
}
if (control?.hasError('max')) {
return `El valor debe ser menor o igual a ${control.getError('max').max}`;
}
if (control?.hasError('email')) {
return 'Debe ser un correo electrónico válido';
}
if (control?.hasError('pattern')) {
return 'El formato no es válido';
}
if (control?.hasError('minlength')) {
return `Debe tener al menos ${control.getError('minlength').requiredLength} caracteres`;
}
if (control?.hasError('maxlength')) {
return `Debe tener como máximo ${control.getError('maxlength').requiredLength} caracteres`;
}
// Agrega más validaciones según sea necesario
return null;
}
getGridColumns(columnCount) {
return `repeat(${columnCount || 1}, 1fr)`;
}
getColSpanClass(colspan) {
return colspan ? `col-span-${colspan}` : 'col-span-1';
}
}
DynamicFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DynamicFormComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }, { token: i2.DynamicFormService }], target: i0.ɵɵFactoryTarget.Component });
DynamicFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DynamicFormComponent, selector: "lib-dynamic-form", inputs: { fieldGroups: "fieldGroups", isModal: "isModal", baseUrl: "baseUrl", resetFormTrigger: "resetFormTrigger", isEdit: "isEdit", isReadonlyForm: "isReadonlyForm" }, outputs: { changeValueSelected: "changeValueSelected", formValidityChange: "formValidityChange", externalDependenciesValuesChanged: "externalDependenciesValuesChanged" }, providers: [
DynamicFormService,
{
provide: DateAdapter,
useClass: AppDateAdapter,
},
{
provide: MAT_DATE_FORMATS,
useValue: APP_DATE_FORMATS,
},
{
provide: MAT_DATE_LOCALE,
useValue: 'es-ES',
},
], usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"form\" class=\"my-2\" (ngSubmit)=\"onSubmit()\">\r\n <div class=\"flex items-center\" mat-dialog-title *ngIf=\"isModal\">\r\n <h2 class=\"headline m-0 flex-auto\">{{ title }}</h2>\r\n </div>\r\n <mat-divider *ngIf=\"isModal\" class=\"-mx-6 text-border\"></mat-divider>\r\n\r\n <mat-dialog-content class=\"flex flex-col\">\r\n <div *ngFor=\"let groups of fieldGroups\">\r\n <div mat-dialog-title *ngIf=\"groups.title\">\r\n <h6 class=\"title-group m-0 flex-auto\">{{ groups.title }}</h6>\r\n </div>\r\n <div\r\n class=\"grid-container\"\r\n [style.gridTemplateColumns]=\"getGridColumns(groups.countColumns || 1)\"\r\n >\r\n <div\r\n *ngFor=\"let field of groups.fields\"\r\n [class]=\"getColSpanClass(field.colspan)\"\r\n >\r\n <div [ngSwitch]=\"field.type\" *ngIf=\"field.visible\">\r\n <!-- INPUT -->\r\n <mat-form-field\r\n *ngSwitchCase=\"eDataType.input\"\r\n appearance=\"outline\"\r\n class=\"w-full\"\r\n [attr.style]=\"\r\n field.background\r\n ? '--dynamic-background-color: ' + field.background\r\n : 'transparent'\r\n \"\r\n >\r\n <mat-label>{{ field.label }}</mat-label>\r\n <input\r\n [type]=\"field.controlType!\"\r\n matInput\r\n [placeholder]=\"field.placeholder!\"\r\n [formControlName]=\"field.name!\"\r\n [value]=\"field.value ? field.value : ''\"\r\n (blur)=\"emitEvent(field)\"\r\n />\r\n <mat-icon\r\n [svgIcon]=\"field.icon!\"\r\n class=\"icon-sm\"\r\n matSuffix\r\n ></mat-icon>\r\n\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </mat-form-field>\r\n\r\n <!-- SELECT -->\r\n <mat-form-field\r\n *ngSwitchCase=\"eDataType.select\"\r\n appearance=\"outline\"\r\n class=\"w-full\"\r\n [attr.style]=\"\r\n field.background\r\n ? '--dynamic-background-color: ' + field.background\r\n : 'transparent'\r\n \"\r\n >\r\n <mat-label>{{ field.label }}</mat-label>\r\n <mat-select\r\n [formControlName]=\"field.name!\"\r\n (selectionChange)=\"emitEvent(field, $event)\"\r\n >\r\n <mat-option *ngIf=\"field.allOption\" [value]=\"-1\"\r\n >TODOS</mat-option\r\n >\r\n <mat-option\r\n *ngFor=\"let option of field.options\"\r\n [value]=\"option.key\"\r\n >\r\n {{ option.value }}\r\n </mat-option>\r\n </mat-select>\r\n\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </mat-form-field>\r\n\r\n <!-- SELECT WITH AUTOCOMPLETE -->\r\n <div\r\n *ngSwitchCase=\"eDataType.select_autocomplete\"\r\n style=\"margin-bottom: 15px\"\r\n >\r\n <h2 *ngIf=\"field.label\" class=\"label-custom\">\r\n {{ field.label }}\r\n </h2>\r\n <p-dropdown\r\n [options]=\"field.options!\"\r\n [formControlName]=\"field.name\"\r\n [filter]=\"true\"\r\n [showClear]=\"true\"\r\n [placeholder]=\"field.placeholder || 'Seleccione'\"\r\n (onChange)=\"emitEvent(field, $event)\"\r\n optionLabel=\"value\"\r\n optionValue=\"key\"\r\n appendTo=\"body\"\r\n filterBy=\"value\"\r\n >\r\n </p-dropdown>\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </div>\r\n\r\n <!-- INPUT AUTOCOMPLETE -->\r\n <div\r\n *ngSwitchCase=\"eDataType.input_autocomplete\"\r\n style=\"margin-bottom: 15px\"\r\n >\r\n <h2 *ngIf=\"field.label\" class=\"label-custom\">\r\n {{ field.label }}\r\n </h2>\r\n <span class=\"p-input-icon-right w-full mr-2\">\r\n <i class=\"pi pi-search\"></i>\r\n <p-autoComplete\r\n [formControlName]=\"field.name\"\r\n [placeholder]=\"field.placeholder || ''\"\r\n [suggestions]=\"field.inputAutoComplete?.suggestions || []\"\r\n [showClear]=\"field.inputAutoComplete?.showClear || true\"\r\n (completeMethod)=\"\r\n field.inputAutoComplete?.onCompleteMethod($event)\r\n \"\r\n (onClear)=\"field.inputAutoComplete?.onClear($event)\"\r\n (onSelect)=\"field.inputAutoComplete?.onSelect($event)\"\r\n field=\"value\"\r\n optionValue=\"key\"\r\n styleClass=\"w-full\"\r\n inputStyleClass=\"w-full p-inputtext\"\r\n appendTo=\"body\"\r\n >\r\n </p-autoComplete>\r\n </span>\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </div>\r\n\r\n <!-- SELECT-CHIPS -->\r\n <div *ngSwitchCase=\"eDataType.select_chips\">\r\n <h2 class=\"label-custom\">{{ field.label }}</h2>\r\n <p-multiSelect\r\n [options]=\"field.options!\"\r\n [formControlName]=\"field.name\"\r\n [defaultLabel]=\"field.placeholder || ''\"\r\n (onChange)=\"emitEvent(field, $event)\"\r\n optionLabel=\"value\"\r\n optionValue=\"key\"\r\n display=\"chip\"\r\n appendTo=\"body\"\r\n ></p-multiSelect>\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </div>\r\n\r\n <!-- DATE -->\r\n <ng-container *ngSwitchCase=\"eDataType.date\">\r\n <ng-container\r\n *ngIf=\"!field.multiple; then singleDate; else rangeDate\"\r\n >\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- DATE-SINGLE -->\r\n <ng-template #singleDate>\r\n <mat-form-field\r\n appearance=\"outline\"\r\n class=\"w-full\"\r\n [attr.style]=\"\r\n field.background\r\n ? '--dynamic-background-color: ' + field.background\r\n : 'transparent'\r\n \"\r\n >\r\n <mat-label style=\"font-size: 12px\">{{ field.label }}</mat-label>\r\n <input\r\n [matDatepicker]=\"datepickerRef\"\r\n [formControlName]=\"field.name!\"\r\n matInput\r\n (dateChange)=\"emitEvent(field, $event)\"\r\n [min]=\"field.minDate || null\"\r\n [max]=\"field.maxDate || null\"\r\n [matDatepickerFilter]=\"field.dateFilterFn!\"\r\n />\r\n <mat-datepicker-toggle\r\n [for]=\"datepickerRef\"\r\n class=\"block\"\r\n matSuffix\r\n ></mat-datepicker-toggle>\r\n <mat-datepicker\r\n #datepickerRef\r\n class=\"end-position\"\r\n ></mat-datepicker>\r\n\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </mat-form-field>\r\n </ng-template>\r\n\r\n <!-- DATE-RANGE -->\r\n <ng-template #rangeDate>\r\n <mat-form-field\r\n appearance=\"outline\"\r\n class=\"w-full\"\r\n [attr.style]=\"\r\n field.background\r\n ? '--dynamic-background-color: ' + field.background\r\n : 'transparent'\r\n \"\r\n >\r\n <mat-label>{{ field.label }}</mat-label>\r\n <mat-date-range-input [rangePicker]=\"picker\">\r\n <input\r\n matStartDate\r\n placeholder=\"Fecha Inicial\"\r\n [formControlName]=\"field.name + 'start'\"\r\n (dateChange)=\"emitEvent(field, $event)\"\r\n />\r\n <input\r\n matEndDate\r\n placeholder=\"Fecha Final\"\r\n [formControlName]=\"field.name + 'end'\"\r\n />\r\n </mat-date-range-input>\r\n\r\n <mat-datepicker-toggle\r\n matIconSuffix\r\n [for]=\"picker\"\r\n ></mat-datepicker-toggle>\r\n <mat-date-range-picker #picker></mat-date-range-picker>\r\n\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </mat-form-field>\r\n </ng-template>\r\n\r\n <!-- TEXT-AREA -->\r\n <mat-form-field\r\n [attr.style]=\"\r\n field.background\r\n ? '--dynamic-background-color: ' + field.background\r\n : 'transparent'\r\n \"\r\n *ngSwitchCase=\"eDataType.tex_area\"\r\n appearance=\"outline\"\r\n class=\"w-full h-full\"\r\n >\r\n <mat-label>{{ field.label }}</mat-label>\r\n <textarea\r\n matInput\r\n #observaciones\r\n [name]=\"field.name!\"\r\n [placeholder]=\"field.placeholder!\"\r\n maxlength=\"250\"\r\n onkeypress=\"if (this.value.length > 250) { return false; }\"\r\n [formControlName]=\"field.name!\"\r\n rows=\"3\"\r\n (blur)=\"emitEvent(field)\"\r\n >\r\n </textarea>\r\n\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </mat-form-field>\r\n\r\n <!-- Tipo checkbox-->\r\n <mat-checkbox\r\n *ngSwitchCase=\"eDataType.checkbox\"\r\n [formControlName]=\"field.name!\"\r\n (change)=\"emitEvent(field)\"\r\n color=\"primary\"\r\n >\r\n {{ field.label }}\r\n </mat-checkbox>\r\n\r\n <!-- Button-Toggle -->\r\n <div *ngSwitchCase=\"eDataType.button_toggle\">\r\n <span class=\"label-chip\">{{ field.label }}</span>\r\n <mat-button-toggle-group\r\n [attr.style]=\"\r\n field.background\r\n ? '--dynamic-background-color: ' + field.background\r\n : 'transparent'\r\n \"\r\n (change)=\"emitEvent(field, $event)\"\r\n [(value)]=\"field.value\"\r\n >\r\n <mat-button-toggle\r\n *ngFor=\"let option of field.options\"\r\n [value]=\"option.key\"\r\n >{{ option.value }}</mat-button-toggle\r\n >\r\n </mat-button-toggle-group>\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </mat-dialog-content>\r\n\r\n <mat-dialog-actions style=\"justify-content: space-between\" *ngIf=\"isModal\">\r\n <button\r\n style=\"margin-right: 1rem\"\r\n mat-button\r\n mat-dialog-close\r\n type=\"button\"\r\n >\r\n Cancelar\r\n </button>\r\n <button color=\"primary\" mat-flat-button [disabled]=\"form.invalid\">\r\n {{ titleButton }}\r\n </button>\r\n </mat-dialog-actions>\r\n</form>\r\n", styles: [".scroll-off{overflow:hidden!important;padding:.9375rem}.mat-form-field-flex{height:100%}.title-group{font-weight:700;margin-bottom:15px}::ng-deep .mat-form-field-appearance-outline .mat-form-field-outline{background-color:var(--dynamic-background-color)}.grid-container{display:grid;gap:10px}.col-span-1{grid-column:span 1}.col-span-2{grid-column:span 2}.col-span-3{grid-column:span 3}.label-custom{margin-top:-10px;font:400 11px/18px var(--font)}:host ::ng-deep .p-multiselect{width:100%;max-width:100%;font-size:small;margin-bottom:15px}:host ::ng-deep .p-multiselect-label{display:flex;flex-wrap:wrap;min-height:40px;padding:4px}:host ::ng-deep .p-multiselect-token{margin:2px}.p-dropdown{width:100%}:host ::ng-deep .p-dropdown{height:48px;margin-top:3px}:host ::ng-deep .p-dropdown .p-dropdown-label{font-size:12px;margin-top:6px;font-weight:500;color:#000;font-family:var(--font)}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i7.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i8.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8.MatSuffix, selector: "[matSuffix]" }, { kind: "component", type: i9.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i10.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "directive", type: i11.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i11.MatButtonToggle, selector: "mat-button-toggle", inputs: ["disableRipple", "aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "appearance", "checked", "disabled"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i12.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i13.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i14.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i14.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i14.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i14.MatDateRangeInput, selector: "mat-date-range-input", inputs: ["rangePicker", "required", "dateFilter", "min", "max", "disabled", "separator", "comparisonStart", "comparisonEnd"], exportAs: ["matDateRangeInput"] }, { kind: "directive", type: i14.MatStartDate, selector: "input[matStartDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { kind: "directive", type: i14.MatEndDate, selector: "input[matEndDate]", inputs: ["errorStateMatcher"], outputs: ["dateChange", "dateInput"] }, { kind: "component", type: i14.MatDateRangePicker, selector: "mat-date-range-picker", exportAs: ["matDateRangePicker"] }, { kind: "component", type: i15.MultiSelect, selector: "p-multiSelect", inputs: ["style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "appendTo", "dataKey", "name", "label", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "autoZIndex", "baseZIndex", "filterBy", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "showTransitionOptions", "hideTransitionOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "defaultLabel", "placeholder", "options", "filterValue", "itemSize"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad"] }, { kind: "component", type: i16.Dropdown, selector: "p-dropdown", inputs: ["scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "filterPlaceholder", "filterLocale", "inputId", "selectId", "dataKey", "filterBy", "autofocus", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "disabled", "itemSize", "options", "filterValue"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i17.AutoComplete, selector: "p-autoComplete", inputs: ["minLength", "delay", "style", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "disabled", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "maxlength", "name", "required", "size", "appendTo", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "field", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "itemSize", "suggestions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onFocus", "onBlur", "onDropdownClick", "onClear", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DynamicFormComponent, decorators: [{
type: Component,
args: [{ selector: 'lib-dynamic-form', providers: [
DynamicFormService,
{
provide: DateAdapter,
useClass: AppDateAdapter,
},
{
provide: MAT_DATE_FORMATS,
useValue: APP_DATE_FORMATS,
},
{
provide: MAT_DATE_LOCALE,
useValue: 'es-ES',
},
], template: "<form [formGroup]=\"form\" class=\"my-2\" (ngSubmit)=\"onSubmit()\">\r\n <div class=\"flex items-center\" mat-dialog-title *ngIf=\"isModal\">\r\n <h2 class=\"headline m-0 flex-auto\">{{ title }}</h2>\r\n </div>\r\n <mat-divider *ngIf=\"isModal\" class=\"-mx-6 text-border\"></mat-divider>\r\n\r\n <mat-dialog-content class=\"flex flex-col\">\r\n <div *ngFor=\"let groups of fieldGroups\">\r\n <div mat-dialog-title *ngIf=\"groups.title\">\r\n <h6 class=\"title-group m-0 flex-auto\">{{ groups.title }}</h6>\r\n </div>\r\n <div\r\n class=\"grid-container\"\r\n [style.gridTemplateColumns]=\"getGridColumns(groups.countColumns || 1)\"\r\n >\r\n <div\r\n *ngFor=\"let field of groups.fields\"\r\n [class]=\"getColSpanClass(field.colspan)\"\r\n >\r\n <div [ngSwitch]=\"field.type\" *ngIf=\"field.visible\">\r\n <!-- INPUT -->\r\n <mat-form-field\r\n *ngSwitchCase=\"eDataType.input\"\r\n appearance=\"outline\"\r\n class=\"w-full\"\r\n [attr.style]=\"\r\n field.background\r\n ? '--dynamic-background-color: ' + field.background\r\n : 'transparent'\r\n \"\r\n >\r\n <mat-label>{{ field.label }}</mat-label>\r\n <input\r\n [type]=\"field.controlType!\"\r\n matInput\r\n [placeholder]=\"field.placeholder!\"\r\n [formControlName]=\"field.name!\"\r\n [value]=\"field.value ? field.value : ''\"\r\n (blur)=\"emitEvent(field)\"\r\n />\r\n <mat-icon\r\n [svgIcon]=\"field.icon!\"\r\n class=\"icon-sm\"\r\n matSuffix\r\n ></mat-icon>\r\n\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </mat-form-field>\r\n\r\n <!-- SELECT -->\r\n <mat-form-field\r\n *ngSwitchCase=\"eDataType.select\"\r\n appearance=\"outline\"\r\n class=\"w-full\"\r\n [attr.style]=\"\r\n field.background\r\n ? '--dynamic-background-color: ' + field.background\r\n : 'transparent'\r\n \"\r\n >\r\n <mat-label>{{ field.label }}</mat-label>\r\n <mat-select\r\n [formControlName]=\"field.name!\"\r\n (selectionChange)=\"emitEvent(field, $event)\"\r\n >\r\n <mat-option *ngIf=\"field.allOption\" [value]=\"-1\"\r\n >TODOS</mat-option\r\n >\r\n <mat-option\r\n *ngFor=\"let option of field.options\"\r\n [value]=\"option.key\"\r\n >\r\n {{ option.value }}\r\n </mat-option>\r\n </mat-select>\r\n\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </mat-form-field>\r\n\r\n <!-- SELECT WITH AUTOCOMPLETE -->\r\n <div\r\n *ngSwitchCase=\"eDataType.select_autocomplete\"\r\n style=\"margin-bottom: 15px\"\r\n >\r\n <h2 *ngIf=\"field.label\" class=\"label-custom\">\r\n {{ field.label }}\r\n </h2>\r\n <p-dropdown\r\n [options]=\"field.options!\"\r\n [formControlName]=\"field.name\"\r\n [filter]=\"true\"\r\n [showClear]=\"true\"\r\n [placeholder]=\"field.placeholder || 'Seleccione'\"\r\n (onChange)=\"emitEvent(field, $event)\"\r\n optionLabel=\"value\"\r\n optionValue=\"key\"\r\n appendTo=\"body\"\r\n filterBy=\"value\"\r\n >\r\n </p-dropdown>\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </div>\r\n\r\n <!-- INPUT AUTOCOMPLETE -->\r\n <div\r\n *ngSwitchCase=\"eDataType.input_autocomplete\"\r\n style=\"margin-bottom: 15px\"\r\n >\r\n <h2 *ngIf=\"field.label\" class=\"label-custom\">\r\n {{ field.label }}\r\n </h2>\r\n <span class=\"p-input-icon-right w-full mr-2\">\r\n <i class=\"pi pi-search\"></i>\r\n <p-autoComplete\r\n [formControlName]=\"field.name\"\r\n [placeholder]=\"field.placeholder || ''\"\r\n [suggestions]=\"field.inputAutoComplete?.suggestions || []\"\r\n [showClear]=\"field.inputAutoComplete?.showClear || true\"\r\n (completeMethod)=\"\r\n field.inputAutoComplete?.onCompleteMethod($event)\r\n \"\r\n (onClear)=\"field.inputAutoComplete?.onClear($event)\"\r\n (onSelect)=\"field.inputAutoComplete?.onSelect($event)\"\r\n field=\"value\"\r\n optionValue=\"key\"\r\n styleClass=\"w-full\"\r\n inputStyleClass=\"w-full p-inputtext\"\r\n appendTo=\"body\"\r\n >\r\n </p-autoComplete>\r\n </span>\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </div>\r\n\r\n <!-- SELECT-CHIPS -->\r\n <div *ngSwitchCase=\"eDataType.select_chips\">\r\n <h2 class=\"label-custom\">{{ field.label }}</h2>\r\n <p-multiSelect\r\n [options]=\"field.options!\"\r\n [formControlName]=\"field.name\"\r\n [defaultLabel]=\"field.placeholder || ''\"\r\n (onChange)=\"emitEvent(field, $event)\"\r\n optionLabel=\"value\"\r\n optionValue=\"key\"\r\n display=\"chip\"\r\n appendTo=\"body\"\r\n ></p-multiSelect>\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </div>\r\n\r\n <!-- DATE -->\r\n <ng-container *ngSwitchCase=\"eDataType.date\">\r\n <ng-container\r\n *ngIf=\"!field.multiple; then singleDate; else rangeDate\"\r\n >\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- DATE-SINGLE -->\r\n <ng-template #singleDate>\r\n <mat-form-field\r\n appearance=\"outline\"\r\n class=\"w-full\"\r\n [attr.style]=\"\r\n field.background\r\n ? '--dynamic-background-color: ' + field.background\r\n : 'transparent'\r\n \"\r\n >\r\n <mat-label style=\"font-size: 12px\">{{ field.label }}</mat-label>\r\n <input\r\n [matDatepicker]=\"datepickerRef\"\r\n [formControlName]=\"field.name!\"\r\n matInput\r\n (dateChange)=\"emitEvent(field, $event)\"\r\n [min]=\"field.minDate || null\"\r\n [max]=\"field.maxDate || null\"\r\n [matDatepickerFilter]=\"field.dateFilterFn!\"\r\n />\r\n <mat-datepicker-toggle\r\n [for]=\"datepickerRef\"\r\n class=\"block\"\r\n matSuffix\r\n ></mat-datepicker-toggle>\r\n <mat-datepicker\r\n #datepickerRef\r\n class=\"end-position\"\r\n ></mat-datepicker>\r\n\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </mat-form-field>\r\n </ng-template>\r\n\r\n <!-- DATE-RANGE -->\r\n <ng-template #rangeDate>\r\n <mat-form-field\r\n appearance=\"outline\"\r\n class=\"w-full\"\r\n [attr.style]=\"\r\n field.background\r\n ? '--dynamic-background-color: ' + field.background\r\n : 'transparent'\r\n \"\r\n >\r\n <mat-label>{{ field.label }}</mat-label>\r\n <mat-date-range-input [rangePicker]=\"picker\">\r\n <input\r\n matStartDate\r\n placeholder=\"Fecha Inicial\"\r\n [formControlName]=\"field.name + 'start'\"\r\n (dateChange)=\"emitEvent(field, $event)\"\r\n />\r\n <input\r\n matEndDate\r\n placeholder=\"Fecha Final\"\r\n [formControlName]=\"field.name + 'end'\"\r\n />\r\n </mat-date-range-input>\r\n\r\n <mat-datepicker-toggle\r\n matIconSuffix\r\n [for]=\"picker\"\r\n ></mat-datepicker-toggle>\r\n <mat-date-range-picker #picker></mat-date-range-picker>\r\n\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </mat-form-field>\r\n </ng-template>\r\n\r\n <!-- TEXT-AREA -->\r\n <mat-form-field\r\n [attr.style]=\"\r\n field.background\r\n ? '--dynamic-background-color: ' + field.background\r\n : 'transparent'\r\n \"\r\n *ngSwitchCase=\"eDataType.tex_area\"\r\n appearance=\"outline\"\r\n class=\"w-full h-full\"\r\n >\r\n <mat-label>{{ field.label }}</mat-label>\r\n <textarea\r\n matInput\r\n #observaciones\r\n [name]=\"field.name!\"\r\n [placeholder]=\"field.placeholder!\"\r\n maxlength=\"250\"\r\n onkeypress=\"if (this.value.length > 250) { return false; }\"\r\n [formControlName]=\"field.name!\"\r\n rows=\"3\"\r\n (blur)=\"emitEvent(field)\"\r\n >\r\n </textarea>\r\n\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[field.name]?.invalid &&\r\n (form.controls[field.name]?.touched ||\r\n form.controls[field.name]?.dirty)\r\n \"\r\n >\r\n {{ getErrorMessage(field.name) }}\r\n </mat-error>\r\n </mat-form-field>\r\n\r\n <!-- Tipo checkbox-->\r\n <mat-checkbox\r\n *ngSwitchCase=\"eDataType.checkbox\"\r\n [formControlName]=\"field.name!\"\r\n (change)=\"emitEvent(field)\"\r\n color=\"primary\"\r\n >\r\n {{ field.label }}\r\n </mat-checkbox>\r\n\r\n <!-- Button-Toggle -->\r\n <div *ngSwitchCase=\"eDataType.button_toggle\">\r\n <span class=\"label-chip\">{{ field.label }}</span>\r\n <mat-button-toggle-group\r\n [attr.style]=\"\r\n field.background\r\n ? '--dynamic-background-color: ' + field.background\r\n : 'transparent'\r\n \"\r\n (change)=\"emitEvent(field, $event)\"\r\n [(value)]=\"field.value\"\r\n >\r\n <mat-button-toggle\r\n *ngFor=\"let option of field.options\"\r\n [value]=\"option.key\"\r\n >{{ option.value }}</mat-button-toggle\r\n >\r\n </mat-button-toggle-group>\r\n <!-- MENSAJES DE ERROR -->\r\n <mat-error\r\n *ngIf=\"\r\n form.controls[