UNPKG

material-dynamic-forms

Version:

¡Crea formularios dinámicos, potentes y configurables en Angular usando Material Design! 🚀

255 lines 95 kB
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[