5

Drupal有一个架构非常好的、基于jQuery的autocomplete.js。通常,您不必费心,因为它的配置和执行由 Drupal 表单 API 处理。

现在,我需要一种在运行时重新配置它的方法(即使用 JavaScript)。我有一个标准的下拉选择框,旁边有一个文本字段,根据选择框中选择的选项,我需要调用不同的 URL 来自动完成,对于其中一个选项,应该完全禁用自动完成。是否可以重新配置现有的自动完成实例,或者我必须以某种方式销毁并重新创建?

4

4 回答 4

4

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

输入的 value 属性用于创建 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-processed”类重新附加该行为,然后调用 Drupal.attachBehaviors(thatInputElement)。

这可能行不通。如果你一遍又一遍地将相同的行为附加到同一个元素上,事情可能会变得非常糟糕。创建不同的自动完成字段并根据选择的值简单地隐藏和显示它们可能更明智。当您隐藏和显示小部件时,这仍然需要调用 Drupal.attachBehaviors,但如果切换发生多次,相同的行为将保持附加,并且您不会冒险将相同的行为多次附加到元素。

于 2009-06-20T00:30:43.803 回答
3

好吧,作为参考,我整理了一个可行的技巧,但如果有人能想到更好的解决方案,我会很高兴听到它。

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。

于 2009-06-21T15:19:51.490 回答
1

它应该像动态更改自动完成表单字段旁边的“隐藏”自动完成输入元素的“值”一样简单。IE。

$('select#myelement').bind('change', function(e) { 
  if (/* something */) {
    $('input#myelement-autocomplete').attr('value', '/mycustom/path');
  }
}); 
于 2009-06-19T22:05:28.683 回答
1

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);
于 2009-09-04T14:08:43.257 回答