¿Cómo puedo implementar el envío de formularios AJAX?

14

Mi tarea es enviar el formulario de contacto a través de AJAX y luego mostrar "¡Gracias por enviarlo !" mensaje, cargado en el lugar donde estaba el formulario. Entonces necesito ajaxificar el formulario de contacto existente.

Encontré algunos ejemplos de cómo validar campos de formulario usando AJAX en D8, pero no puedo encontrar ningún ejemplo de cómo implementar el envío de formularios ajax y cargar algún contenido a través de AJAX.

¿Cómo puedo implementar mi tarea? ¿Cómo debo modificar el formulario de contacto para agregar la funcionalidad requerida?

Sergey Kravchenko
fuente
Para aquellos que llegan aquí con una pregunta de formulario genérico: el módulo de formulario web le permite crear un formulario tal como lo desea y dejar que los resultados se envíen a través de ajax.
Florian Müller

Respuestas:

26

Al trabajar con ajax en formularios, debe tener en cuenta lo siguiente:

  • sepa si está reconstruyendo todo el formulario o solo parte de él y envuelva el formulario en consecuencia con el elemento div que tenga el atributo ID que usará en la definición #ajax en el elemento desencadenante como 'contenedor'. Utilice los atributos #prefix y #suffix para this ( $form['#prefix'] = '<div id="myform-ajax-wrapper">'; $form['#suffix'] = '</div>';). También tenga en cuenta que si tiene una plantilla personalizada para que su formulario NO represente el prefijo y el sufijo en este caso ( {{ form|without('#prefix', '#suffix') }}) de lo contrario, se representarán dos veces: por su plantilla y también por el contenedor del tema del formulario. No puede evitar esto estableciendo #theme_wrappers para vaciar la matriz, ya que la plantilla de formulario contiene el elemento html de formulario real.

  • en su controlador de envío ajax, devuelva el formulario completo o una parte del mismo que ha envuelto y desea reconstruir ( return $formo return $form['myelement']). También puede usar comandos ajax en lugar de simplemente devolver la estructura del formulario, pero eso es algo más avanzado.

  • almacene cada valor en el almacenamiento del estado del formulario hasta que envíe el formulario. Haga esto en el controlador de envío ( $form_state->set('somevalue', $form_state->getValue('somevalue'))) y siempre llame $form_state->setRebuild()si no está haciendo el envío final del formulario. Prefiero tener controladores de envío personalizados, pero tener más lógica en el controlador de envío principal también está totalmente bien.

  • siempre use el #nameatributo en el botón que está haciendo el envío y si tiene un solo formulario, use el controlador de envío $for_state->getTriggeringElement()['#name']para detectar qué elemento ha enviado el formulario.

  • si está usando 'trigger_as' en la definición de #ajax, en caso de que desee enviar el formulario con el elemento select, por ejemplo, use siempre la misma definición de #ajax como lo hace en el botón. En mi experiencia es obligatorio, aunque no se menciona en la documentación.

  • a #limit_validation_errorsveces puede ser muy complicado usarlo y descubrir por qué el formulario no funciona puede llevar bastante tiempo, así que úselo con cuidado (esto es bueno para aislar errores de formulario solo en los elementos que realmente está reconstruyendo para que su código no influye en otras partes del formulario).

  • siempre use botones para enviar el formulario y si desea tener algo elegante, como seleccionar ser el elemento desencadenante, use la opción 'trigger_as' de la configuración #ajax y oculte el botón real con la clase 'js-hide' para una buena interfaz de usuario.

  • en la definición del formulario, obtenga los valores predeterminados del almacenamiento del estado del formulario si existen o asígnelos al almacenamiento si no existen. De lo contrario, el formulario no funcionará correctamente.

  • no use $ this ni ninguna otra cosa a la que no tenga acceso externo, de lo contrario se romperá el ajax. siempre use manejadores estáticos de ajax.

  • cuando finalmente envíe el formulario, dependiendo de que usted (no) tenga un controlador de envío de formulario personalizado para el ajax, desactive la reconstrucción del formulario llamando $form_state->setRebuild(FALSE).

  • puede usar las llamadas :: abreviadas en el elemento de envío ajax ( $element['#ajax']['callback'] = '::ajaxFormRebuild';y $element['#submit'] = [['::ajaxFormSubmitHandler'];).

  • la devolución de llamada ajax es puramente para devolver el formulario reconstruido o los comandos ajax. Nunca devuelva la forma alterada (es decir, no modifique la matriz de forma en esta devolución de llamada).


fuente
¡Excelente lista de verificación, si tiene problemas con ajax en drupal 8! (No entiendo el primer punto, ¿por qué NO renderizar el ajax wrap div?)
4k4
No recuerdo exactamente, pero creo que podría haber tenido algo que ver con #theme, #theme_wrappers y el manejo de los atributos #prefix y #suffix en el renderizador. Creo que terminarías con el contenedor dentro del elemento <form>. Por supuesto, esto solo se aplica si está reconstruyendo todo el formulario, no solo algún elemento.
Gracias, pero ¿dónde puedo encontrar algún ejemplo simple para el envío de AJAX?
Sergey Kravchenko
@IvanJaros, gracias por la respuesta. ¿Sabes cómo borrar los valores del formulario después de un envío ajax?
milkovsky
1

Para agregar a esta lista de verificación, si está mostrando un formulario en una ventana modal, existe la posibilidad de que no se muestren los mensajes de error. Como dijo Ivan Jaros, debe asegurarse de que el formulario tenga un contenedor:

$form['#prefix'] = '<div id="my-form-wrapper-id">';
$form['#suffix'] = '</div>';

También deberá agregar lo siguiente al elemento que envía el formulario. En la mayoría de los casos, sería su botón de envío:

$form['submit'] = [
    '#type' => 'submit',
    '#value' => $this->t('Save Changes'),
    '#attributes' => [
        'class' => [
            'btn',
            'btn-md',
            'btn-primary',
            'use-ajax-submit'
        ]
    ],
    '#ajax' => [
        'wrapper' => 'my-form-wrapper-id',
    ]
];
IslandDev
fuente
1

Yo uso el módulo de contacto ajax . Algunos detalles más al respecto (de su página de proyecto):

Contacto Ajax implementa el envío de ajax para el formulario de contacto en Drupal 8.

Cómo funciona

Después de habilitar el módulo, cada formulario de contacto mostrará una casilla de verificación "Usar ajax". Cuando esta casilla de verificación está habilitada, el formulario de contacto le mostrará otra opción "Tipo de confirmación" con estas opciones:

  • Cargue el formulario: enviará el formulario sin volver a cargar la página.
  • Cargar desde mensaje personalizado: carga un texto personalizado.
  • Cargar desde nodo: carga un nodo después del envío del formulario.

Este módulo podría ayudarlo si:

  • necesitas personalizar el mensaje de confirmación
  • debe enviar un formulario de contacto sin volver a cargar la página.
  • desea cargar un texto personalizado u otro nodo después del envío del formulario.
masdzen
fuente