TransWikia.com

Angular 8 Actualizar valor de input al cambiar un select en reactive form o DOM

Stack Overflow en español Asked by Salvation on November 24, 2021

Situación:

En un Dialog (con cierta información) hay un botón que muestra otro Dialog (común y dinámico para toda la plataforma) antes de realizar la acción correspondiente. En este segundo diálogo común, hay un mat-select y en función del valor seleccionado, hay que actualizar un input. Todo esto es un Reactive Form.

ModalPrevia.ts (antes de generar un diálogo común)

El diálogo común se genera de la siguiente manera:

items = {
    'item_1': {
      'info': 'Info completa del item 1',
      'instructions': 'pasos a seguir...'
      ...
    },
    'item_2': {
      'info': 'Info completa del item 2',
      'instructions': 'pasos a seguir...'
      ...
    },
}

options = [
  {
    'text':'Instrucciones del item 1',
    'value': 'item_1'
  },
  {
    'text':'Instrucciones del item 2',
    'value': 'item_2'
  },
]

this.dialogCommon.open(DialogComponent, {
  height: 'auto',
  width: '500px',
  data: {
      dialogObj: {
          title: `Título del Dialog`,
          bodyText: `Contenido del body antes de los inputs`,
          inputs: [
              {
                type: 'select',
                text: 'Texto',
                name: 'select_field_item,
                value: this.options,
                functions: {
                  change: (event) => {
                    // event.value = text_1, text_2,...
                    console.log(event.value)
                    // TODO:: Actualizar el value del textarea una vez generado el form dinámico del segundo Dialog
                    // Setear dentro del textarea (DOM): this.items(event.value).instructions
                  }
                }
              },
              {
                type: 'textarea',
                text: 'Instrucciones del item',
                name: 'textarea_field_instructions',
                value: '',
              }
          ]
      }
  }
}

DialogComponent.html

Esto lo que hará, es ir al componente del diálogo común y montar la template de forma dinámica:

...*ngFor del dialogObj...
<!-- SELECTOR -->
<mat-form-field>
    <mat-label>{{field.text}}</mat-label>
    <mat-select [(ngModel)]="selectedNull" [formControlName]="field.name" (selectionChange)="field.functions.change($event)">
        <mat-option [value]="null"></mat-option>
        <mat-option *ngFor="let option of field.value" [value]="option.value">
            {{ option.text }}
        </mat-option>
    </mat-select>
</mat-form-field>

<!-- TEXTAREA -->
<div *ngSwitchCase="'textarea'">
    <mat-form-field>
        <mat-label>{{field.text}}</mat-label>
        <textarea matInput [formControlName]="field.name" [name]="field.name" #textarea>
            {{ field.value }}
        </textarea>
    </mat-form-field>
</div>

Con el evento selectionChange me muestra los textos de los items (options) por consola, pero no soy capaz de capturar el form del segundo Dialog para setearle el valor en el textarea.

DialogComponent.ts:

[...]
constructor(
        [...]
        @Inject(MAT_DIALOG_DATA) public data: any
    ) {
    }

ngOnInit() {
    this.generateDialog(this.data.dialogObj);
}

generateDialog(dialogObj) {
  // Inputs
  const inputs = dialogObj.inputs;
  _.forEach(inputs, (value, key) => {
      this.dialogForm.addControl(value.name, this.fb.control(''));
  });
}
[...]

introducir la descripción de la imagen aquí

Cuando añado como provider en ModalPrevia el DialogComponent, puedo acceder al dialogForm generado, sin embargo está vacío.

Por lo que no puedo hacer un patchValue en el textarea.

¿Cómo podría obtener de forma dinámica del DOM el textarea y cambiarle su valor?

One Answer

Al final hubo una forma de hacerlo:

En el functions: change, añadí el siguiente código:

[...]
functions: {
    change: (event) => {
        // Guarda el valor  en una variable global
        this.instructions = this.items[event.value].instructions;
        // Muestra el valor en el campo (DOM)
        document.getElementsByName('textarea_field_instructions')[0]['value'] = this.instructions;
    }
},
[...]

Además de esto, cuando se acepta el Dialog, en el evento afterClosed() cuando recibe los datos, hay que comprobar si están rellenados o no.

Aunque se muestre texto en el DOM, angular no reconoce el texto si no has escrito en ellos manualmente (desde teclado) o has hecho un patchValue de se campo en el formulario, por lo tanto una forma de comprobarlo es la siguiente:

[...]
.afterClosed()
.subscribe((dialogInfo) => {
  if (dialogInfo) {
      // Comprobamos si hay datos escritos a mano
      if (dialogInfo.value.instructions === null) {
          // Si no están, los recogemos de la variable global, ya esté vacía o no, podremos obtener el texto igualmente y trabajar con él
          dialogInfo.value.instructions = this.instructions;
      }

      [...]
  }
}
[...]

Y con esto queda resuelto para poder trabajar con diálogos comunes/dinámicos.

Answered by Salvation on November 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP