Как динамически перенастроить JQuery на основе автозаполнения Drupal во время выполнения? - PullRequest
5 голосов
/ 19 июня 2009

Drupal имеет очень хорошо спроектированную структуру jQuery autocomplete.js . Обычно вам не нужно беспокоиться об этом, так как его конфигурация и выполнение обрабатываются API-формой Drupal.

Теперь мне нужен способ перенастроить его во время выполнения (то есть с помощью JavaScript). У меня есть стандартный выпадающий список выбора с текстовым полем рядом с ним, и в зависимости от того, какой параметр выбран в поле выбора, мне нужно вызывать разные URL-адреса для автозаполнения, а для одного из вариантов автозаполнение должно быть полностью отключено. Можно ли перенастроить существующий экземпляр автозаполнения, или мне придется каким-то образом уничтожить и воссоздать?

Ответы [ 4 ]

4 голосов
/ 20 июня 2009

Посмотрите на 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');
  });
};

Атрибут значения ввода используется для создания ACDB, который представляет собой кэш значений для этого пути автозаполнения (uri). Это используется в функции Drupal.jsAC, чтобы связать события keydown, keyup и blur элемента с триггерами ajax-операции автозаполнения (которая кэширует свои значения в объекте ACDB для этого элемента), открывает всплывающие окна и т. Д.

/**
 * 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(); });

};

Что вам нужно сделать, это изменить значение ввода, а также заново подключить поведение. Повторите это поведение, удалив класс .autocomplete-processing в элемент ввода текстового поля автозаполнения, а затем вызовите Drupal.attachBehaviors (thatInputElement).

Это может не сработать. Все может пойти очень плохо, если вы снова и снова присоединяете одно и то же поведение к одному и тому же элементу. Может быть более разумно создавать различные поля автозаполнения и просто скрывать и показывать их в зависимости от значения выбора. Это по-прежнему требует вызова Drupal.attachBehaviors, когда вы скрываете и отображаете виджет, но такое же поведение останется подключенным, если переключение произошло более одного раза, и вы не рискуете присоединить одно и то же поведение к элементу несколько раз.

3 голосов
/ 21 июня 2009

Ну, для справки, я собрал хак, который работает, но если кто-нибудь сможет придумать лучшее решение, я буду рад его услышать.

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);
          }
      });
};

Этот код взят из модуля ding_campaign . Не стесняйтесь проверить код, если вам нужно сделать что-то подобное. Это все GPL2.

1 голос
/ 04 сентября 2009

Рабочий раствор для 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);
1 голос
/ 20 июня 2009

это должно быть так же просто, как динамически изменить «значение» «скрытого» автозаполнения элемент ввода, который отходит от автозаполнения полей формы. то есть.

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