以编程方式添加新的 jquery-select2-4 选项并重置搜索字段?
Programmatically add new jquery-select2-4 option and reset the search field?
我正在使用 jquery-select2-4 搜索外部数据库并向用户显示可供选择的搜索结果。
我在 this jsfiddle 上有一个工作版本 运行。
但是,例如,如果只返回 1 个搜索结果,我想跳过整个选择过程,而只是将返回的搜索结果添加到所选选项列表中。根据 select2 docs 我可以像这样添加一个新选项:
option = new Option("Sample text", "123", true, true);
select2_element.append(option);
select2_element.trigger('change');
这似乎在某种程度上起作用。但是也有一些问题。
- 添加选项后我无法清除搜索字段。
- 我无法添加
id
和 text
的任何其他内容。
- 添加的选项向用户显示为
undefined
。
我知道这个问题包含 3 个方面,但所有 3 个方面可能都指回这 1 个问题:
如何以编程方式添加新的 jquery-select2-4 选项并重置搜索字段?
供您参考,这是我询问的代码的上下文:
var formatRepo, formatRepoSelection, selectRepos;
formatRepoSelection = function(element) {
return element.name + ' ' + element.forks + ' ' + element.id;
};
formatRepo = function(element) {
var markup;
if (!element.loading) {
return markup = element.name + ' ' + element.id;
}
};
selectRepos = function() {
var option, select2_element;
select2_element = $('#select2_element');
select2_element.select2({
ajax: {
url: "https://api.github.com/search/repositories",
dataType: 'json',
data: function (params) {
return {
q: params.term,
page: params.page
};
},
processResults: function (data, params) {
if (data.items.length === 1) {
// START: The code I am asking about.
// Add the search result directly as an option.
option = new Option("Sample text", "123", true, true);
select2_element.append(option);
return select2_element.trigger('change');
// END: The code I am asking about.
} else {
params.page = params.page || 1;
return {
results: data.items,
pagination: {
more: (params.page * 30) < data.total_count
}
};
}
},
cache: true
},
escapeMarkup: function(markup) {
return markup;
},
templateResult: formatRepo,
templateSelection: formatRepoSelection
});
};
$(function() {
return selectRepos();
});
我对原代码做了两处修改:
1。模拟选择唯一剩下的item
如您所述,创建 option
元素有其局限性:您只能指定 id 和 text 属性,无法访问所选项目的其他属性。
此外,它还会生成 undefined 值。这是因为回调函数 formatRepoSelection 试图访问未定义的属性(name 和 forks)为 option
元素创建的对象。您可以尝试解决此问题并在这种情况下使用 text 属性,但您仍然无法解决上述限制。
我在这里建议的解决方案有不同的方法。您可以模拟用户对最后一项的选择,而不是直接创建标签,向该列表项发送 mouseup 事件。
这有一个直接的好处,即应用正常的选择行为,就像用户单击了该项目一样,因此它立即解决了您遇到的所有三个问题:
- 过滤文本自动清除;
- formatRepoSelection函数接收到的是通常的对象,tag的label因此符合预期;
- 您可以使用与任何项目相同的属性。
这是实现这个的代码:
if (data.items.length === 1) {
// Change 1:
// Allow the list to update
setTimeout(function() {
// ... and then send a click event to the first list item
// Note the used id has the SELECT id in the middle.
$("#select2-select2_element-results li:first-child").trigger('mouseup');
}, 0);
这个解决方案的缺点是你让自己依赖于一个实现方面; select2 的未来版本可能会根据 HTML 元素和属性以不同方式组织结果。
但是,只要您决定使用 select2.
的更新版本,更新代码应该没什么大不了的
2。 Return 一个正确的对象
您的代码在 select2 库中产生错误:
TypeError: b is undefined, at select2.min.js:2:9842
这是因为这条语句:
return select2_element.trigger('change');
这个 return 是 jQuery select2_element 对象,但是库期望 return 值有一个 结果 属性.
因为不再需要 trigger,可以通过将上面的替换为:
来解决这个问题
// Change 2:
// Return empty results array
return {
results: data.items
};
不要试图设置 results: []
,因为我们仍然需要该项目来模拟鼠标事件。
还有...就是这样。
这是可行的解决方案:JS fiddle。
我正在使用 jquery-select2-4 搜索外部数据库并向用户显示可供选择的搜索结果。
我在 this jsfiddle 上有一个工作版本 运行。
但是,例如,如果只返回 1 个搜索结果,我想跳过整个选择过程,而只是将返回的搜索结果添加到所选选项列表中。根据 select2 docs 我可以像这样添加一个新选项:
option = new Option("Sample text", "123", true, true);
select2_element.append(option);
select2_element.trigger('change');
这似乎在某种程度上起作用。但是也有一些问题。
- 添加选项后我无法清除搜索字段。
- 我无法添加
id
和text
的任何其他内容。 - 添加的选项向用户显示为
undefined
。
我知道这个问题包含 3 个方面,但所有 3 个方面可能都指回这 1 个问题:
如何以编程方式添加新的 jquery-select2-4 选项并重置搜索字段?
供您参考,这是我询问的代码的上下文:
var formatRepo, formatRepoSelection, selectRepos;
formatRepoSelection = function(element) {
return element.name + ' ' + element.forks + ' ' + element.id;
};
formatRepo = function(element) {
var markup;
if (!element.loading) {
return markup = element.name + ' ' + element.id;
}
};
selectRepos = function() {
var option, select2_element;
select2_element = $('#select2_element');
select2_element.select2({
ajax: {
url: "https://api.github.com/search/repositories",
dataType: 'json',
data: function (params) {
return {
q: params.term,
page: params.page
};
},
processResults: function (data, params) {
if (data.items.length === 1) {
// START: The code I am asking about.
// Add the search result directly as an option.
option = new Option("Sample text", "123", true, true);
select2_element.append(option);
return select2_element.trigger('change');
// END: The code I am asking about.
} else {
params.page = params.page || 1;
return {
results: data.items,
pagination: {
more: (params.page * 30) < data.total_count
}
};
}
},
cache: true
},
escapeMarkup: function(markup) {
return markup;
},
templateResult: formatRepo,
templateSelection: formatRepoSelection
});
};
$(function() {
return selectRepos();
});
我对原代码做了两处修改:
1。模拟选择唯一剩下的item
如您所述,创建 option
元素有其局限性:您只能指定 id 和 text 属性,无法访问所选项目的其他属性。
此外,它还会生成 undefined 值。这是因为回调函数 formatRepoSelection 试图访问未定义的属性(name 和 forks)为 option
元素创建的对象。您可以尝试解决此问题并在这种情况下使用 text 属性,但您仍然无法解决上述限制。
我在这里建议的解决方案有不同的方法。您可以模拟用户对最后一项的选择,而不是直接创建标签,向该列表项发送 mouseup 事件。
这有一个直接的好处,即应用正常的选择行为,就像用户单击了该项目一样,因此它立即解决了您遇到的所有三个问题:
- 过滤文本自动清除;
- formatRepoSelection函数接收到的是通常的对象,tag的label因此符合预期;
- 您可以使用与任何项目相同的属性。
这是实现这个的代码:
if (data.items.length === 1) {
// Change 1:
// Allow the list to update
setTimeout(function() {
// ... and then send a click event to the first list item
// Note the used id has the SELECT id in the middle.
$("#select2-select2_element-results li:first-child").trigger('mouseup');
}, 0);
这个解决方案的缺点是你让自己依赖于一个实现方面; select2 的未来版本可能会根据 HTML 元素和属性以不同方式组织结果。
但是,只要您决定使用 select2.
的更新版本,更新代码应该没什么大不了的2。 Return 一个正确的对象
您的代码在 select2 库中产生错误:
TypeError: b is undefined, at select2.min.js:2:9842
这是因为这条语句:
return select2_element.trigger('change');
这个 return 是 jQuery select2_element 对象,但是库期望 return 值有一个 结果 属性.
因为不再需要 trigger,可以通过将上面的替换为:
来解决这个问题 // Change 2:
// Return empty results array
return {
results: data.items
};
不要试图设置 results: []
,因为我们仍然需要该项目来模拟鼠标事件。
还有...就是这样。
这是可行的解决方案:JS fiddle。