3.0 / 5

Formulario dinámico en Angular

9.97K
3

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.

THIS IS AN OPTIONAL

Related Post

Veremos como funciona Angular Shell usando Angular 7 y el rendimiento adicional que obtenemos en nue

Hola buenas a todos, hoy les comparto un pequeño tutorial para poder comunicar dos componentes herm

Hola buenas a todos! Hoy veremos un poco de lo nuevo en Angular 12...¡Esta nueva versión contiene

6 COMMENTS
  • By David Gonzales

    Se ve excepcionalmente bien, tienes codigo en github?

    / Responder
    • By jlopezjujuy

      Hola David, si, pero es un repo privado. solo pude compartir algunas cosas. No puedo compartir otras cosas mas.

      / Responder
      • By marco

        LLevo semanas con un problema similar podrias apoyarme con el codigo?

        / Responder
        • By jlopezjujuy

          Hola Marco, perdon la demora, estaba con mucho trabajo. podrias comentar mas o menos cual es el problema que estas teniendo?

          / Responder
  • By David Gonzales

    entiendo, gracias.

    / Responder
  • By emmanuel

    Estimado que tal , podrias por favor compartirnos el codigo en archivos de este ejemplo

    / Responder

LEAVE YOUR COMMENTS