Como sobrescribir el script de auto completado en Drupal 7

Author Top
kenneth

La funcionalidad de auto completar de Drupal es muy útil y suple la mayoría de nuestras necesidades, sin embargo si quisiéramos agregar una característica adicional al comportamiento normal que esta definido por Drupal no existe algo parecido a los hooks para poder realizar esta tarea.  

Por lo tanto debemos tomar una de las siguientes iniciativas:

  • Crear nuestro propio sistema de auto completado.
  • Sobrescribir el funcionamiento normal de sistema de auto completado que tiene Drupal.

En esta ocasión implementaremos la segunda opción. Se agregara una condición para borrar el cache del autocomplete basado en el estado de un elemento de la página actual.

Antes de continuar necesitamos saber cual es el archivo que ejecuta Drupal cuando se utiliza el script de auto completado, este archivo se encuentra en la siguiente ruta: "misc/autcomplete.js", el cual define el comportamiento que se ejecutará al lado del cliente por medio de javascript.

Dicho archivo define la clase Drupal.ACDB y en esta clase esta definido el comportamiento para el sistema de auto completado y cuenta con la propiedad llamada cache la cual es usada para almacenar los resultados de las búsquedas y usarlo en las siguientes peticiones que coincidan con el criterio de busqueda dando una sensación de inmediates al usurio final.

En nuestra implementación verificaremos un elemento de la página que nos indicara si los resultados de la base de datos han cambiado y el cache debe ser refrescado.uesto que se almacena en la cache.

1. Crear archivo javascript.

Se debe hacer una copia de la función de la clase Drupal.ACDB llamada Drupal.ACDB.prototype.search presente en el archivo "misc/autocomplete.js" en algun módulo custom, en este nuevo archivo al que llamaremos cache_clear.js y donde cambiaremos el comportamiento de la función search. dentro del código de nuestro módulo debemos incluir nuestro archivo de javascript como se muestra a continuación.

drupal_add_js(drupal_get_path('module', 'modulo_personalizado') . '/cache_clear.js');

2. Sobrescribir la funcion Search.

Ahora podemos modificar la función y estar seguros que no crearemos conflicto con el comportamiento normal como se muestra a continuacion:

(function($) {

 $(document).ready(function(){

 $('#ID-ELEMENT-DOM').live('change', function(){
 $(this).data('clear', true);
 });
 
 Drupal.ACDB.prototype.search = function (searchString) {
 var db = this;
 this.searchString = searchString;

 // See if this string needs to be searched for anyway.
 searchString = searchString.replace(/^\s+|\s+$/, '');
 if (searchString.length <= 0 ||
 searchString.charAt(searchString.length - 1) == ',') {
 return;
 }

 // See if this key has been searched for before.
 if($('#ID-ELEMENT-DOM').data('clear')){
 this.cache = {};
 $('#ID-ELEMENT-DOM').data('clear', false);
 }

 if (this.cache[searchString]) {
 return this.owner.found(this.cache[searchString]);
 }

 // Initiate delayed search.
 if (this.timer) {
 clearTimeout(this.timer);
 }
 this.timer = setTimeout(function () {
 db.owner.setStatus('begin');

 // Ajax GET request for autocompletion. We use Drupal.encodePath instead of
 // encodeURIComponent to allow autocomplete search terms to contain slashes.
 $.ajax({
 type: 'GET',
 url: db.uri + '/' + Drupal.encodePath(searchString),
 dataType: 'json',
 success: function (matches) {
 if (typeof matches.status == 'undefined' || matches.status != 0) {
 db.cache[searchString] = matches;
 // Verify if these are still the matches the user wants to see.
 if (db.searchString == searchString) {
 db.owner.found(matches);
 }
 db.owner.setStatus('found');
 }
 },
 error: function (xmlhttp) {
 alert(Drupal.ajaxError(xmlhttp, db.uri));
 }
 });
 }, this.delay);
 };

 });

})(jQuery);

El primer cambio es detectar cuando el elemento del html identificado con el #ID ID-ELEMENT-DOM cambie, configurar el atributo clear del element en TRUE.

 $('#ID-ELEMENT-DOM').live('change', function(){
 $(this).data('clear', true);
 });

Adicionalmente se agregar un proceso extra a la busqueda, para verificar valor del atributo clear del elemento con ID ID-ELEMENT-DOM y si este esta en TRUE se procede a borrar el cache de las búsquedas.

 // See if this key has been searched for before.
 if($('#ID-ELEMENT-DOM').data('clear')){
 this.cache = {};
 $('#ID-ELEMENT-DOM').data('clear', false);
 }

Espero que esto les haya sido de mucha ayuda y lo puedan implementar,

Saludos.