Hero

¿Cómo trabajar en Drupal 8 con formularios con Ajax?

Diciembre 04, 2014

enzo
Drupal
Desarrollo de Modulos

Hoy en día Drupal 8 ya tiene 3 versiones beta por lo que el lanzamiento oficial está a la vuelta de la esquina (eso espero). Por eso empece a probar las características típicas y necesarias en un sitio Drupal.

Hoy voy a compartir con ustedes mis experiencias con un Formulario con efectos Ajax.

  1. Crear un Formulario.

Voy a omitir la explicación acerca de cómo crear un formulario en Drupal 8 porque se podría generar con el proyecto Drupal Console ejecutando el siguiente comando.

$ php console.phar generate:form:config
  1. Drupal 8 FAPI + Ajax

La documentación actual de FAPI para Drupal 8 sobre #ajax no esta actualizada, por que aun esta en progreso esta implementación.

Sin embargo, la propiedad se llama todavía #ajax como se puede comprobar en la siguiente aplicación.

$form['source']['version'] = array(
  '#type' => 'radios',
  '#title' => $this->t('Drupal Version'),
  '#default_value'=>"d6",
  '#options' => $options,
  '#description' => t('Choise what version of Drupal you want migrate'),
  '#required' => TRUE,
  '#ajax' => array(
    'callback' => '::updateDestinationIds',
    'wrapper' => 'edit-destinations',
    'progress' => array(
      'type' => 'throbber',
      'message' => "searching",
    ),
  ),
);

Si usted es un desarrollador con experiencia en Drupal reconocerá las propiedades wrapper y progress*. Estas propiedades funcionan igual en Drupal 7.

El principal cambio está en propiedad de callback en mi ejemplo el valor ’:: updateDestinationIds’ significa que debe existir un método llamado updateDestinationIds en la clase que implementa el Form. No he probado pero parece que podemos asignar un método estático como ‘Drupal :: StaticMethod’.

  1. Medotodo Callback

Similar a Drupal 7 el método tiene que devolver la parte del formulario que debe ser sobrescrita a través de ajax, permítame mostrarle un ejemplo.

/**
 * Gets migration configurations.
 *
 * @return array
 *   An array of migration names.
 */
function updateDestinationIds($form, FormStateInterface $form_state) {
    $form ['source']['migration_ids']['#options'] = $this->getDestinationIds($form_state->getValue('version'));
    return $form ['source']['migration_ids'];
}
  1. Errores conocidos.

Después de implementar la función Ajax detecte un problema cuando trato de seleccionar valores generados a través de Ajax al hacer submit del formulario se genera el siguiente mensaje de error “An illegal choice has been detected. Please contact the site administrator.”

Luego de depurar puede determinar que el método buildForm se ejecuta en diferentes momentos que se enumeran a continuación:

  • Form load: Construcción del Formulario.
  • Ajax request: Re-build del formulario para determinar elementos a sobre escribir.
  • Form submit: Procesar el formulario

El error es generado cuando se le da Enviar al formulario porque se que se ejecuta la implementación de clase FormValidator.

El FormValidator ignora el proceso de Ajax y validar los valores FormState con la lista de valores permitidos y porque tomó estos valores de buildForm son siempre los valores iniciales ignorando la interacción del usuario.

Para resolver este problema use el objeto FormState para determinar si buildForm fue ejecutado para hacer que la forma en la primera vez, o si tiene interacción Humana (ajax o enviar) . Para definir la lista de permitidos de valores basados en la interacción del usuario, implemente el siguiente código.

$form_state_complete_form=$form_state->getCompleteForm();
if(empty($form_state_complete_version)){
    $form ['source']['migration_ids']['#options'] = $this->getDestinationIds("d6");
 }
  else  {
   $form ['source']['migration_ids']['#options'] = $this->getDestinationIds($form_state_complete_version);
 }

No se preocupe acerca de este comportamiento como se puede ver es fácil de solucionar y estoy seguro que no será necesario cuando Drupal 8 tenga el primer release oficial.

  1. Advertencias

Actualmente Drupal 8 sólo soporta la actualización de ajax en elementos de tipo Select, he intentado con Tableselect y Checkboxes pero no funciona.

Ademas recomiendo trabajar con alguna beta como la Beta 3 o la version Beta que este disponible al momento de leer esta entrada de blog por que la version desarrollo Git no funciona.

Hay una error reportado por este problema Ajax doesn’t work with Tableselect with checkboxes.

Espero que haya sido de su agrado

Recibe consejos y oportunidades de trabajo 100% remotas y en dólares de weKnow Inc.