5

Drupalには、非常によく設計されたjQueryベースのautocomplete.jsがあります。設定と実行は Drupal フォーム API によって処理されるため、通常は気にする必要はありません。

ここで、実行時に (つまり、JavaScript を使用して) 再構成する方法が必要です。横にテキスト フィールドがある標準のドロップダウン選択ボックスがあり、選択ボックスで選択されているオプションに応じて、オートコンプリート用に別の URL を呼び出す必要があり、オプションの 1 つでオートコンプリートを完全に無効にする必要があります。既存のオートコンプリート インスタンスを再構成することは可能ですか、それとも何らかの方法で破棄して再作成する必要がありますか?

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 属性は、そのオートコンプリート パス (uri) の値のキャッシュである ACDB を作成するために使用されます。これは 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) を呼び出します。

これはうまくいかないかもしれません。同じ動作を同じ要素に何度も適用すると、事態は非常に悪化する可能性があります。さまざまなオートコンプリート フィールドを作成し、select の値に基づいて単純に表示または非表示にする方が賢明な場合があります。これには、ウィジェットを非表示および表示するときに 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

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 に答える