Javascript 如何在运行时动态重新配置Drupal基于jQuery的自动完成?
有一个非常好的架构,基于。通常,您不必为它操心,因为它的配置和执行由Drupal表单API处理Javascript 如何在运行时动态重新配置Drupal基于jQuery的自动完成?,javascript,jquery,drupal,autocomplete,drupal-6,Javascript,Jquery,Drupal,Autocomplete,Drupal 6,有一个非常好的架构,基于。通常,您不必为它操心,因为它的配置和执行由Drupal表单API处理 现在,我需要一种在运行时用JavaScript重新配置它的方法,也就是说。我有一个标准的下拉选择框,旁边有一个文本字段,根据选择框中选择的选项,我需要调用不同的URL进行自动完成,对于其中一个选项,应该完全禁用自动完成。是否可以重新配置现有的autocomplete实例,或者我必须以某种方式销毁并重新创建?它应该非常简单,只需手动更改隐藏的autocomplete实例的值即可 自动完成表单字段旁边的输
现在,我需要一种在运行时用JavaScript重新配置它的方法,也就是说。我有一个标准的下拉选择框,旁边有一个文本字段,根据选择框中选择的选项,我需要调用不同的URL进行自动完成,对于其中一个选项,应该完全禁用自动完成。是否可以重新配置现有的autocomplete实例,或者我必须以某种方式销毁并重新创建?它应该非常简单,只需手动更改隐藏的autocomplete实例的值即可 自动完成表单字段旁边的输入元素。即
$('select#myelement').bind('change', function(e) {
if (/* something */) {
$('input#myelement-autocomplete').attr('value', '/mycustom/path');
}
});
看看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,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文本字段输入元素上的“.autocomplete processed”类,然后调用Drupal.attachBehaviorsthatInputElement,可以重新附加该行为
这可能行不通。如果你一次又一次地将相同的行为附加到同一个元素上,事情会变得非常糟糕。创建不同的自动完成字段并根据select的值简单地隐藏和显示它们可能更明智。这仍然需要在隐藏和显示小部件时调用Drupal.attachBehaviors,但如果切换多次发生,相同的行为将保持连接状态,并且您不会冒险多次将相同的行为附加到元素。好吧,作为参考,我已经想出了一个可行的方法,但如果有人能想出更好的解决办法,我很乐意听到
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);
}
});
};
此代码来自。如果您需要执行类似的操作,请随时查看代码。这都是GPL2。Drupal5的工作解决方案
这似乎不起作用。显然,URL存储在JavaScript中的某个位置,不会从输入字段中重新读取。此外,您需要从隐藏字段中删除autocomplete processed类,然后通过调用Drupal.behaviors.AutoCompletedDocument;重新附加autocomplete行为;。它可以工作,但每次更改时都会注册一个新的url,如果重新附加2次,总共会向serverWell发出3次调用,我绝不是JavaScript专家,但是否可以更改JavaScript中的值,而不是每次销毁并重新创建自动完成的核心选项?因为url缓存在abcd[]数组,则必须重新附加该行为以更新它,如果这样做,则应在之前解除绑定到autocomplete元素的所有先前事件。我已设法解除绑定并重新应用该行为,但这是否会导致旧的autocomplete对象被垃圾收集?否则,这将泄漏内存。这可能没什么大不了的,但绝对不是什么新鲜事:请注意,这几乎就是location模块所做的——请查看location_autocomplete.js以了解有趣的细节。
/*
* 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);