gpt4 book ai didi

javascript - 无法在 Select2 下拉菜单中选择项目

转载 作者:技术小花猫 更新时间:2023-10-29 11:45:18 24 4
gpt4 key购买 nike

我正在开发一个使用 Select2(版本 3.5.1)的应用程序。设置此下拉/自动完成字段的 HTML 如下所示:

<input id="mySelect" class="form-control" type="hidden">

此代码段中的 form-control 类来自 Bootstrap。我正在使用以下代码从 JavaScript 初始化此字段:

function getItemFormat(item) {
var format = '<div>' + item.ItemName + '</div>';
return format;
}

$(function() {
$('#mySelect').select2({
minimumInputLength: 5,
placeholder: 'Search for an item',
allowClear: true,
ajax: {
url: '/api/getItems',
dataType: 'json',
quietMillis: 250,
data: function (term, page) {
return {
query: term
};
},
results: function (data, page) {
return { results: data, id: 'ItemId', text: 'ItemText' };
}
},
formatResult: getItemFormat,
dropdownCssClass: "bigdrop",
escapeMarkup: function (m) { return m; }
});
});

当我的选择字段加载时,它会成功呈现。一旦我至少输入第五个字符,它就会成功地从服务器中提取项目并将它们列为选项。但是,如果我尝试选择其中之一,则什么也不会发生。下拉弹出窗口保持打开状态。没有任何东西被放入实际领域。 JavaScript 控制台中没有错误。就像我没有点击任何东西一样。

此外,我注意到当我将鼠标放在某个项目上或尝试使用箭头键浏览选项列表时,没有突出显示任何内容。

我做错了什么?

最佳答案

发生了什么:

默认情况下,您在 ajax.results 中返回的对象的 results 应该是此结构中的数组 [{id:1,text:"a"},{id:2,text:"b"}, ...].

  results: function (data, page) {
var array = data.results; //depends on your JSON
return { results: array };
}


Select2.js它实际上指出:

* @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2.
* The expected format is an object containing the following keys:
* results array of objects that will be used as choices
* more (optional) boolean indicating whether there are more results available
* Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}


阅读源码,我们可以看到AJAX成功时调用了ajax.results:

   success: function (data) {
// TODO - replace query.page with query so users have access to term, page, etc.
// added query as third paramter to keep backwards compatibility
var results = options.results(data, query.page, query);
query.callback(results);
}


所以 ajax.results 实际上只是一个函数,可让您将数据格式化为适当的结构(例如 [{id:a,text:"a"},{id: b,text:"b"}, ...]) 在数据传递给query.callback之前:

 callback: this.bind(function (data) {

// ignore a response if the select2 has been closed before it was received
if (!self.opened()) return;


self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
self.postprocessResults(data, false, false);

if (data.more===true) {
more.detach().appendTo(results).html(self.opts.escapeMarkup(evaluate(self.opts.formatLoadMore, self.opts.element, page+1)));
window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
} else {
more.remove();
}
self.positionDropdown();
self.resultsPage = page;
self.context = data.context;
this.opts.element.trigger({ type: "select2-loaded", items: data });
})});


query.callback 最终所做的是正确设置逻辑,以便在您选择其中一项并触发 .selectChoice 时一切正常。

selectChoice: function (choice) {

var selected = this.container.find(".select2-search-choice-focus");
if (selected.length && choice && choice[0] == selected[0]) {

} else {
if (selected.length) {
this.opts.element.trigger("choice-deselected", selected);
}
selected.removeClass("select2-search-choice-focus");
if (choice && choice.length) {
this.close();
choice.addClass("select2-search-choice-focus");
this.opts.element.trigger("choice-selected", choice);
}
}
}


因此,如果存在一些错误配置(例如,results 的结构不正确)导致类 .select2-search-choice-focus 不被添加到.selectChoice 被调用之前的 DOM 元素,这是发生了什么:

The drop-down popup stays open. Nothing gets put in the actual field. There are no errors in the JavaScript console. Its like I didn't click anything.


解决方案

对此有很多解决方案。当然,其中之一是在 ajax.results 中进行一些数组键操作。

  results: function (data, page) {
//data = { results:[{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}] };
var array = data.results;
var i = 0;
while(i < array.length){
array[i]["id"] = array[i]['ItemId'];
array[i]["text"] = array[i]['ItemText'];
delete array[i]["ItemId"];
delete array[i]["ItemText"];
i++;
}
return { results: array };
}

但是你可能会问:为什么数组中id一定要是“id”,文本一定要是“text”?

[{id:1,text:"a"},{id:2,text:"b"}] 

数组可以改用这种结构吗?

[{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}]

答案是肯定的。您只需要用您自己的函数覆盖 idtext 函数即可。


以下是 Select2.js.selecte2 的原始函数:

    id: function (e) { return e == undefined ? null : e.id; },
text: function (e) {
if (e && this.data && this.data.text) {
if ($.isFunction(this.data.text)) {
return this.data.text(e);
} else {
return e[this.data.text];
}
} else {
return e.text;
}
},


要覆盖它们,只需在传递给 .selecte2 的对象中添加您自己的函数:

$('#mySelect').select2({
id: function (item) { return item.ItemId },
text: function (item) { return item.ItemText }
......
});

更新

还发生了什么:

However, the text of the selected item does not appear in the field after the list closes.

这意味着 .selectChoice 已成功执行。现在问题出在.updateSelection。在源代码中:

   updateSelection: function (data) {

var container=this.selection.find(".select2-chosen"), formatted, cssClass;

this.selection.data("select2-data", data);

container.empty();
if (data !== null) {
formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);
}
if (formatted !== undefined) {
container.append(formatted);
}
cssClass=this.opts.formatSelectionCssClass(data, container);
if (cssClass !== undefined) {
container.addClass(cssClass);
}

this.selection.removeClass("select2-default");

if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
this.container.addClass("select2-allowclear");
}
}


从这里我们可以看出,在将相应的文本字符串放入输入之前,它会调用formatSelection

formatSelection: function (data, container, escapeMarkup) {
return data ? escapeMarkup(this.text(data)) : undefined;
},

更新:解决方案

以前我认为 this.text(data) 可以通过在参数中包含 text: funcion(item){ ... } 来覆盖,但遗憾的是它没有'那样工作。

因此要在字段中正确呈现文本,您应该通过执行以下操作来覆盖 formatSelection

$('#mySelect').select2({
id: function (item) { return item.ItemId },
formatSelection: function (item) { return item.ItemText }
//......
});

而不是尝试覆盖 text(应该具有相同的效果,但库中尚不支持/实现这种覆盖方式)

$('#mySelect').select2({
id: function (item) { return item.ItemId },
text: function (item) { return item.ItemText } //this will not work.
//......
});

关于javascript - 无法在 Select2 下拉菜单中选择项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26074414/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com