3.0 / 5
Hola buenas a todos! espero que estén bien, hoy vamos a ver un tema que estuve trabajando estas semanas, como investigación para un proyecto personal, y es el uso de Formulario Dinámico con Angular.
En este caso el problema era que el usuario necesita crear productos, pero no todos los productos tenÃan los mismos atributos, algunos tenÃan mas otros menos. En este caso el usuario querÃa configurar sus propios campos, y decidir si son requeridos o no, o si es dropbox o no, etc.
Siguiendo un ejemplo básico de la pagina de Angular, logramos algo asi:
Para cargar elementos al formulario dinamo seguimos lo siguiente:
Y al guardarlo queda de la siguiente manera.
Si agregamos mas campos quedarÃa de la siguiente manera:
Ahora en otra pantalla, donde vamos a hacer uso del formulario dinamico, podemos ver algo como lo siguiente:
y luego al elegir el formulario podremos ver como se crean los campos dinamicamente.
Como pueden ver, visualmente queda muy bien y ordenado ahora veremos un poco el código usado:
Aquà las interfaces que vamos a usar:
export interface IDynamicForm { form_id?: number; form_description?: string; country?: string; value?: string; key?: string; label?: string; labelEs?: string; labelEn?: string; labelBr?: string; info?: string; infoEs?: string; infoEn?: string; infoBr?: string; required?: any; order?: number; type?: string; options?: Option[]; environment?: string; domain?: string; customer_domain?: string; session_id?: string; api_id?: string; control_type?: string; comparable?: boolean; graphic?: boolean; icon?: string; }
Ahora vemos el formgroup que vamos a usar
editForm = this.fb.group({
form_id: [null, [Validators.required]],
value: [null, [Validators.required]],
keyForm: [null, [Validators.required]],
labelForm: [null, [Validators.required]],
requiredForm: [null, [Validators.required]],
order: [null, [Validators.required]],
control_type: [null, [Validators.required]],
type: [],
options: [],
keyOption: [],
valueOtion: [],
});
Aqui el metodo que corresponde al boton de Guardar:
Â
private createFromForm(): IDynamicForm {
return {
...new DynamicForm(),
form_id: this.editForm.get([ 'form_id' ])!.value,
value: this.editForm.get(['value'])!.value,
key: this.editForm.get(['keyForm'])!.value,
label: this.editForm.get(['labelForm'])!.value,
required: this.editForm.get(['requiredForm'])!.value,
order: this.editForm.get(['order'])!.value,
control_type: this.editForm.get(['control_type'])!.value,
type: this.editForm.get(['type'])!.value,
options: this.editForm.get(['options'])!.value,
};
}
Ya teniendo el “DynamicForm” procedemos a enviarlo a nuestro BackEnd y listo la primera parte.
Mostrar campos del Formulario.
Ahora veremos un poco como seria el código para mostrar los campos del formulario dinámico en la pantalla que la necesitemos:
Nuestro HTML quedaria de la siguiente forma:
Â
<div [formGroup]="form">
<mat-form-field appearance="outline" style="width: 100%;">
<mat-label [attr.for]="solicitud.key">{{ solicitud.label }}</mat-label>
<div [ngSwitch]="solicitud.control_type">
<input matInput *ngSwitchCase="'textbox'" [formControlName]="solicitud.key" [id]="solicitud.key" [type]="solicitud.type" />
<mat-select [id]="solicitud.key" *ngSwitchCase="'dropdown'" [formControlName]="solicitud.key">
<mat-option *ngFor="let opt of solicitud.options" [value]="opt.key">{{ opt.value }}</mat-option>
</mat-select>
</div>
<mat-error class="errorMessage" *ngIf="!isValid"><span jhiTranslate="entity.validation.required"> is required</span></mat-error>
</mat-form-field>
</div>
Nuestro Componente quedaria de la siguiente manera:
Â
@Component({
selector: 'app-formulario',
templateUrl: './solicitud-formulario.component.html',
styleUrls: ['./solicitud-formulario.component.scss'],
})
export class FormularioComponent implements OnInit {
@Input() solicitud: IDynamicForm;
@Input() form: FormGroup;
@Input() disabled: boolean;
constructor() {}
ngOnInit(): void {}
get isValid(): boolean {
if (this.form.controls[this.solicitud.key]) {
return this.form.controls[this.solicitud.key].valid;
} else {
return false;
}
}
}
Ahora lo que nos queda hacer es obtener el formulario, recorrerlo y mostrarlo en el HTML, puede ser algo como lo siguiente:
Â
<form [formGroup]="formList">
<mat-tab-group>
<mat-tab *ngFor="let item of itemsFormDyn" label="{{ item.formId }}">
<div class="tab-content p-24" fusePerfectScrollbar>
<mat-grid-list [cols]="breakpoint3" rowHeight="9rem" (window:resize)="onResize($event)">
<!-- <div *ngFor="let solicitud of solicitudes" class="form-row" >-->
<mat-grid-tile *ngFor="let solicitud of item.itemSol">
<app-formu
[solicitud]="solicitud"
[form]="formList"
class="input-full-width"
></app-formu>
</mat-grid-tile>
</mat-grid-list>
</div>
</mat-tab>
</mat-tab-group>
</form>
Â
Todo eso nos dara el resultado que vimos anteriormente:
Bueno espero les sea de utilidad, desde ya muchas gracias por visitar mi blog. Saludos a todos.
By David Gonzales
Se ve excepcionalmente bien, tienes codigo en github?
By jlopezjujuy
Hola David, si, pero es un repo privado. solo pude compartir algunas cosas. No puedo compartir otras cosas mas.
By marco
LLevo semanas con un problema similar podrias apoyarme con el codigo?
By jlopezjujuy
Hola Marco, perdon la demora, estaba con mucho trabajo. podrias comentar mas o menos cual es el problema que estas teniendo?
By David Gonzales
entiendo, gracias.
By emmanuel
Estimado que tal , podrias por favor compartirnos el codigo en archivos de este ejemplo