¿Cómo reconfigurar dinámicamente el autocompletado basado en jQuery de Drupal en tiempo de ejecución?

StackOverflow https://stackoverflow.com/questions/1018981

Pregunta

Drupal tiene un rel muy bien diseñado, jQuery -based autocomplete.js . Por lo general, no tiene que molestarse con él, ya que su configuración y ejecución se maneja mediante la API de formulario de Drupal.

Ahora, necesito una forma de reconfigurarlo en tiempo de ejecución (con JavaScript, eso es). Tengo un cuadro de selección desplegable estándar con un campo de texto al lado, y dependiendo de qué opción esté seleccionada en el cuadro de selección, necesito llamar a diferentes URL para completar automáticamente, y para una de las opciones, la finalización automática debería estar completamente desactivada. ¿Es posible reconfigurar la instancia de autocompletar existente, o tendré que destruir y recrear de alguna manera?

¿Fue útil?

Solución 2

Bueno, como referencia, he creado un truco que funciona, pero si alguien puede pensar en una solución mejor, me encantaría escucharlo.

Drupal.behaviors.dingCampaignRules = function () {
  $('#campaign-rules')
    .find('.campaign-rule-wrap')
      .each(function (i) {
          var type = $(this).find('select').val();

          $(this).find('.form-text')
            // Remove the current autocomplete bindings.
            .unbind()
            // And remove the autocomplete class
            .removeClass('form-autocomplete')
          .end()
          .find('select:not(.dingcampaignrules-processed)')
            .addClass('dingcampaignrules-processed')
            .change(Drupal.behaviors.dingCampaignRules)
          .end();

          if (type == 'page' || type == 'library' || type == 'taxonomy') {
            $(this).find('input.autocomplete')
              .removeClass('autocomplete-processed')
              .val(Drupal.settings.dingCampaignRules.autocompleteUrl + type)
            .end()
            .find('.form-text')
              .addClass('form-autocomplete');
            Drupal.behaviors.autocomplete(this);
          }
      });
};

Este código proviene del módulo ding_campaign . No dude en consultar el código si necesita hacer algo similar. Todo es GPL2.

Otros consejos

Eche un vistazo a misc / autocomplete.js.

/**
 * Attaches the autocomplete behavior to all required fields
 */
Drupal.behaviors.autocomplete = function (context) {
  var acdb = [];
  $('input.autocomplete:not(.autocomplete-processed)', context).each(function () {
    var uri = this.value;
    if (!acdb[uri]) {
      acdb[uri] = new Drupal.ACDB(uri);
    }
    var input = $('#' + this.id.substr(0, this.id.length - 13))
      .attr('autocomplete', 'OFF')[0];
    $(input.form).submit(Drupal.autocompleteSubmit);
    new Drupal.jsAC(input, acdb[uri]);
    $(this).addClass('autocomplete-processed');
  });
};

El atributo de valor de la entrada se usa para crear ACDB, que es un caché de valores para esa ruta de autocompletar (uri). Eso se usa en la función Drupal.jsAC para vincular los eventos de keydown, keyup y blur del elemento con desencadena la operación de autocompletar ajax (que almacena en caché sus valores en el objeto ACDB para ese elemento), abre ventanas emergentes, etc.

/**
 * An AutoComplete object
 */
Drupal.jsAC = function (input, db) {
  var ac = this;
  this.input = input;
  this.db = db;

  $(this.input)
    .keydown(function (event) { return ac.onkeydown(this, event); })
    .keyup(function (event) { ac.onkeyup(this, event); })
    .blur(function () { ac.hidePopup(); ac.db.cancel(); });

};

Lo que tendrá que hacer es cambiar el valor de la entrada y también volver a conectar el comportamiento. Volverá a unir el comportamiento eliminando la clase '.autocomplete-procesado' en el elemento de entrada del campo de texto de autocompletar y luego llamará a Drupal.attachBehaviors (thatInputElement).

Esto puede no funcionar. Las cosas pueden salir muy mal si adjuntas el mismo comportamiento al mismo elemento una y otra vez. Puede ser más sensato crear diferentes campos de autocompletar y simplemente ocultarlos y mostrarlos en función del valor de la selección. Esto aún requeriría llamar a Drupal.attachBehaviors cuando oculta y muestra el widget, pero el mismo comportamiento permanecería asociado si el cambio ocurriera más de una vez, y no correría el riesgo de asociar el mismo comportamiento al elemento varias veces.

debería ser tan simple como cambiar dinámicamente el " valor " del " oculto " autocompletar elemento de entrada que viene a un lado de los campos de formulario de autocompletar. es decir.

$('select#myelement').bind('change', function(e) { 
  if (/* something */) {
    $('input#myelement-autocomplete').attr('value', '/mycustom/path');
  }
}); 

Solución de trabajo para Drupal 5

/*
 *  Błażej Owczarczyk
 *  blazej.owczarczyk@gmail.com 
 * 
 *  Name: Autocomplete City Taxonomy 
 *  Description: Hierarchical city selecting (province select and city autocomplete)
 */

var Act = Act || {};

Act.init = function () {
    $('select.act-province').change(Act.provinceChange);        // select with top taxonomy terms    
}

/*
 *  Change event of select element
 */
Act.provinceChange = function () { 
    var context = $(this).parent().parent();              
    var currentTid = $(this).val();
    Act.rewriteURI(context, currentTid);
    Act.unbind();
    Drupal.autocompleteAutoAttach();
};

/*
 *  Changes the value of hidden autocomplete input
 */
Act.rewriteURI = function (context, newTid) {
    var tempArray;
    tempArray = $('.autocomplete', context).val().split('/');
    tempArray.pop();
    tempArray.push(newTid);
    $('.autocomplete', context).val(tempArray.join('/'));    
};

/*
 *  Prevents muliple binding of the same events
 */
Act.unbind = function () {
    $('.form-autocomplete').unbind().parents('form').unbind('submit');
};

$(document).ready(Act.init);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top