Primary tabs
Añadir AJAX a un Webform en Drupal 7
El siguiente artículo es una traducción de http://envisioninteractive.com/drupal/add-ajax-to-a-webform-in-drupal-7/
___________________________________________________
El módulo Webform es espectacular , nos proporciona una forma fácil y rápida de agregar formularios a nuestro sitio encargándose del manejo del formulario. Todo lo anterior a través de una interfaz fácil de usar. Con el lanzamiento de Drupal 7el API de formularios (Form API) tuvo algunas mejoras, más específicamente, el manejo de AJAX por parte de los formularios es un poco mas directo. Recientemente tuve que construir un sitio donde necesitaba un formulario de contacto y que fuese enviado usando AJAX, luego del envío un mensaje de confirmación reemplazaría al formulario.
Desafortunadamente aún no hay una versión del módulo Webform Ajax para la versión 7 de Drupal por lo tanto solo tenía dos opciones.
- Usar el API de formularios (FAPI), escribir mi propia validación de formularios, enviar la información a la base de datos y correos de notificación.
- Usar el módulo webfom y alterarlo para usar AJAX
Para este caso tomé la opción 2.
Crear el formulario con Webform
Una vez descargado y habilitado el módulo Webform, se crea un formulario de contacto básico.

Añadir el mensaje de confirmación.
Ahora necesitamos ingresar el mensaje de confirmación en la página de configuración del formulario (node/[el id de su nodo]/webform/configure) , Una vez llenado el campo "Confirmation message", seleccione la opción "COnfirmation page" dentro de la configuración de "Redirection location".

Alterar el formulario.
Usamos el hook_form_alter para añadir el manejador de AJAX en el formulario.
1 2 3 4 5 6 7 8 9 10 11 | function sandbox_form_alter(&$form, &$form_state, $form_id) { if(strstr($form_id, 'webform_client_form_')) { $nid = $form['#node']->nid; $form['actions']['submit']['#ajax'] = array( 'callback' => 'sandbox_webform_js_submit', 'wrapper' => 'webform-client-form-' . $nid, 'method' => 'replace', 'effect' => 'fade', ); }} |
Analizando linea por línea
1 | if(strstr($form_id, 'webform_client_form_')) { |
Aquí estamos usando la función strstr de PHP para ver si la cadena "webform_client_form_" se encuentra en la variable $form_id, de esta forma podemos alterar todos los formualrios generados por el módulo Webform.
1 | $nid = $form['#node']->nid; |
Almacenamos el identificador del nodo para poder usarlo en el AJAX Wrapper mas adelante
1 | $form['actions']['submit']['#ajax'] = array( |
Usando un print_r (o un dsm) del arreglo $form encontré los valores de los botones de envío, Necesitamos agregar el arreglo #ajax para que drupal use AJAX en el envío si nos encontramos en un navegador con Javascript habilitado.
1 | 'callback' => 'sandbox_webform_js_submit', |
El parámetro callback define la función que será invocada cuando se use el envío por AJAX, escribiremos esta función mas adelante.
1 | 'wrapper' => 'webform-client-form-' . $nid, |
El parámetro wrapper define el id (en html) del elemento que se verá afectado por lo que retornará la función callback , en nuestro caso vamos a reemplazar totalmente el formulario con el mensaje de confirmación, por lo tanto nuestro wrapper es el id de nuestro Webform.
1 | 'method' => 'replace', |
El parámetro method define que haremos en el wrapper, en nuestro caso estamos usando "replace", pero también podriamos usar "after", "append", "before"o "prepend" , revise la documentación del Form API para mas información de como puede usar estos métodos.
1 | 'effect' => 'fade', |
El parámetro effect define que efecto tendrá el método sobre el wrapper, en nuestro caso estamos usando fade, pero también podríamos usar "none" o "slide".
Escribir la función AJAX handler callback.
ahora necesitamos crear la función sanbox_webform_js_submit que definimos arriba en el array #ajax.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function sandbox_webform_js_submit($form, $form_state) { $sid = $form_state['values']['details']['sid']; if ($sid) { $node = node_load($form_state['values']['details']['nid']); $confirmation = array( '#type' => 'markup', '#markup' => check_markup($node->webform['confirmation'], $node->webform['confirmation_format'], '', TRUE), ); return $confirmation; } else { return $form; }} |
Y linea por línea
1 2 | $sid = $form_state['values']['details']['sid']; if ($sid) { |
Primero definimos la variable $sid, luego verificamos si el formulario fue enviado correctamente, si tenemos un envío satisfactorio , reemplazamos el formulario con el mensaje de confirmación. De lo contrario retornamos el array del formulario que incluye los mensajes de error.
1 | $node = node_load($form_state['values']['details']['nid']); |
Neceistamos cargar el nodo del webform para obtener el mensaje de confirmación que anteriormente ingresamos a través de la interfaz gráfica.
1 2 3 4 5 6 | $confirmation = array( '#type' => 'markup', '#markup' => check_markup($node->webform['confirmation'], $node->webform['confirmation_format'], '', TRUE), ); return $confirmation;} |
Necesitamos crear un arreglo para renderizar con etiquetado, usamos el tipo "markup" y obtenemos la información directamente desde el objeto $node.
1 2 3 | else { return $form;} |
Este es e l caso en que no hay un envío del formulario, simplemente retornamos el arreglo $form.
Todo junto
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | function sandbox_form_alter(&$form, &$form_state, $form_id) { // see if webform_client_form_ is in the form_id if(strstr($form_id, 'webform_client_form_')) { // get the nid so we can use it in the wrapper value $nid = $form['#node']->nid; // add the ajax properties to the submit button $form['actions']['submit']['#ajax'] = array( 'callback' => 'sandbox_webform_js_submit', 'wrapper' => 'webform-client-form-' . $nid, 'method' => 'replace', 'effect' => 'fade', ); }}function sandbox_webform_js_submit($form, $form_state) { // define the $sid variable (submission id from webform) $sid = $form_state['values']['details']['sid']; // if we have a sid then we know the form was properly submitted, otherwise, we'll just return the existing $form array if ($sid) { // first we have to load up the webform node object $node = node_load($form_state['values']['details']['nid']); // create an array up with the confirmation message, retreived from the webform node $confirmation = array( '#type' => 'markup', '#markup' => check_markup($node->webform['confirmation'], $node->webform['confirmation_format'], '', TRUE), ); // return the confirmation message return $confirmation; } else { // return the form return $form; }} |
¡Hecho!
Ahora después de enviar el formulario, obtengo la confirmación sin refrescar la página.

Nota: Cabe resaltar que lo anterior debería realizarse en un módulo nuevo que debemos crear para que funcione, en este caso se llamó sandbox.
Documentación adicional: http://drupal.org/node/752056


Enviar un comentario nuevo