:::: MENU ::::

AJAX avanzado en Drupal: Procesado de la respuesta AJAX

4.17 avg. rating (80% score) - 6 votes

En tutoriales anteriores vimos la forma de realizar una llamada básica en AJAX en Drupal y cómo pre-procesarla una llamada AJAX antes de la ejecución Drupal. En este nuevo tutorial veremos cómo podemos añadir nuestro propio procesamiento de la respuesta AJAX, una vez que el framework de Drupal ha hecho su trabajo.

Recordatorio del ejemplo básico de AJAX con Drupal

Extraído del primer tutorial, recordamos el aspecto básico de una función básica de callback para la generación de la respuesta AJAX en nuestro módulo personalizado.

function mi_funcion_callback() {
  // Generamos el nuevo contenido que queremos enviar
  $output = "<p>Aquí el nuevo contenido</p>";
  // Creamos un array de comandos para el dispatcher
  $commands = array();
  // Comando html indica a Drupal que sustituya el contenido del 
  // selector '#resultado' por el contenido de $output
  $commands[] = ajax_command_html('#resultado', $output);
  // Indicamos que el resultado es AJAX y la lista de comandos
  return array('#type' => 'ajax',
               '#commands' => $commands);
}

Nota: No vuelvo a explicar la forma en la que esta función es llamada al acceder a una URL. Consultar el primer tutorial para tener la visión completa, que incluye el uso de hook_menu, y en enlace HTML para ejecutar el procesado AJAX.

El punto importante de la función anterior, es la llamada a ajax_command_html(), que será procesado por el framework AJAX de Drupal, en este caso para sustituir el contenido del selector «#resultado» dentro del DOM, por el contenido de la variable $output.

De forma similar a ajax_command_html, existen otra serie de funciones para los casos más comunes. Puede consultarse la lista completa para Drupal 7 en Ajax Framework Commands.

Método 1: Sobreescribir la función success de jQuery

Una vez el procesamiento AJAX se ha completado, existe un handler «success» que es llamado automáticamente (no olvidar que todo el framework AJAX de Drupal está basado en jQuery).
Una forma fácil de procesar el resultado de la llamada AJAX es sustituir la función success asociada a nuestro evento.

Drupal.behaviors.mibehaviorid = {
  attach: function (context, settings) {
    jQuery('.custom-use-ajax:not(.ajax-processed)').addClass('ajax-processed').each(function () {
      var element_settings = {};

      // For anchor tags, these will go to the target of the anchor rather
      // than the usual location.
      if (jQuery(this).attr('href')) {
        element_settings.url = jQuery(this).attr('href');
        element_settings.event = 'click';
      }

      var base = jQuery(this).attr('id');
      var ajax = new Drupal.ajax(base, this, element_settings);

      // Nos guardamos la función success anterior, para llamarla al final
      ajax.success_old = ajax.success;

      // Creamos una nueva función success que sustituye a la anterior
      ajax.success = function (response, status) {
        /*
         * Incluimos aquí el código necesario
         */

        // Llamamos a la función success original
        ajax.success_old(response, status);
      }

      // Guardamos el evento AJAX en el array global
      Drupal.ajax[base] = ajax;
    });
  }
};

La mayor parte de este código está comentado en el post anterior: cómo pre-procesarla una llamada AJAX antes de la ejecución Drupal.

Método 2: Sobreescribir funciones del Framework AJAX de Drupal

Drupal nos proporciona la capacidad de sobreescribir funciones del framework, como la anterior ajax_command_html si su funcionamiento no cubre nuestras necesidades.

Por ejemplo, si queremos sustituir el comportamiento de la función anterior, podemos incluir el siguiente fragmento en alguno de los ficheros javascript de nuestro módulo:

Drupal.behaviors.minamespace = {
  attach: function (context, settings) {
    Drupal.ajax['enlaceid'].commands.insert = function (ajax, response, status) {
      alert('El comando html ahora muestra este mensaje');
    }
  } 
};

Nota: Observar que aunque la función que queremos modificar es ajax_command_html, estamos sobreescribiendo la función command.insert. Para obtener la equivalencia de los comandos y sus funciones, consultar el Ajax Framework Commands.

En el código de la función, llama la atención el índice de acceso al array Drupal.ajax[‘mienlace’].

En el array Drupal.ajax existe una entrada para cada acción AJAX de la página actual, y el índice corresponde al atributo id del enlace que pulsamos para disparar el evento AJAX. Recordando del tutorial básico:

echo l(t('Mi enlace'), 'nojs/destino', array('attributes' => array('id' => 'enlaceid', 'class' => array('use-ajax'))));

Método 3: Añadir un comando nuevo al framework AJAX de Drupal

Además de sobrreescribir comandos ya existentes como en el caso anterior, podemos crear nuestros nuevos comandos y añadirlos al framework AJAX fácilmente.

Para ello necesitamos:

  • Crear una función en PHP, similar a las existentes ajax_command_html.
  • Crear la función javascript que se llamará cuando se procese el comando
  • Hacer consciente a Drupal de la existencia del nuevo comando.

Si queremos un comando llamado «minuevocomando», para utilizarlo de forma similar al ajax_command_html que tenemos arriba , en primer lugar tendremos que crear una función PHP en nuestro módulo, similar a la siguiente:

function ajax_command_minuevocomando($selector, $html, $settings = NULL) {
  return array(
    'command' => 'minuevocomando',
    'selector' => $selector,
    'data' => $html,
    'settings' => $settings,
  );
}

Con esto, podremos añadir a nuestra función de callback AJAX, comandos de la siguiente forma:

function mi_funcion_callback() {
  // Generamos el nuevo contenido que queremos enviar
  $output = "<p>Aquí el nuevo contenido</p>";
  // Creamos un array de comandos para el dispatcher
  $commands = array();
  // Comando html indica a Drupal que sustituya el contenido del 
  // selector '#resultado' por el contenido de $output
  $commands[] = ajax_command_minuevocomando('#resultado', $output);
  // Indicamos que el resultado es AJAX y la lista de comandos
  return array('#type' => 'ajax',
               '#commands' => $commands);
}

El framework buscará automáticamente el nombre de la función javascript «minuevocomando», ya que es el nombre indicado en el parámetro command (línea 3 marcada en el bloque anterior).

Buscará dicha función en el objeto Drupal.ajax.prototype.commands, definido en /misc/ajax.js.

Podemos añadirlo en cualquier fichero js de nuestro módulo, mediante el siguiente fragmento:

Drupal.behaviors.minamespace = {
  attach: function (context, settings) {
    Drupal.ajax.prototype.commands.minuevocomando = function(ajax, response, status) {
      alert('has ejecutado el comando custom');
    }
  } 
};

Con esto hemos cubierto en diferentes tutoriales desde los aspectos básicos del framework, hasta las cuestiones avanzadas para modificar el comportamiento estándar de Drupal.




3 Comments

    • Responder Daniel Navarro Murillo |

      Se puede utilizar igualmente. La diferencia es que utilizando behaviors, las funciones se ejecutan en cada ciclo de carga, independientemente de que sea una recarga de la página completa o una llamada AJAX.

      Si actualizas un área de la página mediante AJAX y la zona actualizada contiene otro enlace AJAX, usando ready el enlace no se procesaría, mientras que usando behavior sí.

  • Responder ВалокКраснознаменск |

    RE:AJAX avanzado en Drupal: Procesado de la respuesta AJAX | Programador Drupal | Programador Freelance Web y Movil Валок Morris Олёкминск

Hey! Qué opinas sobre el artículo?