Javascript 选择2-按查询对结果排序
我正在使用Select2 4.0.0版 如果我的结果包含多个单词,并且用户输入其中一个单词,则我 要显示按输入单词在结果中的位置排序的结果 例如,用户输入“apple”,我的结果是:Javascript 选择2-按查询对结果排序,javascript,jquery,jquery-select2,jquery-select2-4,Javascript,Jquery,Jquery Select2,Jquery Select2 4,我正在使用Select2 4.0.0版 如果我的结果包含多个单词,并且用户输入其中一个单词,则我 要显示按输入单词在结果中的位置排序的结果 例如,用户输入“apple”,我的结果是: “香蕉橙苹果” “香蕉苹果橙” “苹果香蕉橙” 然后,“苹果香蕉橙”应该首先出现在select2结果列表中,因为这是“苹果”在结果中最早出现的结果。我不太在乎过去的订单 我应该覆盖或配置什么以获得类似的结果?看来,matcher没有 处理排序,sorter不包含查询数据。您可以通过使用Select2-search\
matcher
没有
处理排序,
sorter
不包含查询数据。您可以通过使用Select2-search\u字段
类识别Select2生成的输入框的值来获取搜索查询。这可能会跨越多个版本,但由于它们不提供钩子来获取查询,因此需要进行某种黑客攻击。您可以让他们添加对排序期间访问查询的支持,特别是因为在Select2 3.5.2中似乎可以这样做
$(“#水果”)。选择2({
宽度:“200px”,
分拣机:功能(结果){
var query=$('.select2-search__字段').val().toLowerCase();
返回结果。排序(函数(a,b){
返回a.text.toLowerCase().indexOf(查询)-
b、 text.toLowerCase().indexOf(查询);
});
}
});代码>
香蕉橙苹果
香蕉苹果橙
苹果香蕉橙
阿乔查苹果杏
榴莲芒果木瓜
番木瓜
番茄木瓜
榴莲番茄木瓜
这里的问题是,在4.0.0版本中,Select2将查询结果与显示结果分开。因此,通常用于对结果进行排序的sorter
选项不会传入所做的查询(包括搜索词)
因此,您需要找到一种缓存查询的方法,以便在排序时使用它。在关于的回答中,我通过加载
模板方法缓存查询,每当进行搜索时都会触发该方法。这里也可以使用同样的方法
var query = {};
$element.select2({
language: {
searching: function (params) {
// Intercept the query as it is happening
query = params;
// Change this to be appropriate for your application
return 'Searching…';
}
}
});
因此,现在您可以构建一个自定义的sorter
方法,该方法使用保存的query
(并使用query.term
作为搜索项)。对于我的示例排序方法,我使用文本中搜索结果排序结果的位置。这可能与您正在寻找的类似,但这是一种非常野蛮的方法
function sortBySearchTerm (results) {
// Don't alter the results being passed in, make a copy
var sorted = results.slice(0);
// Array.sort is an in-place sort
sorted.sort(function (first, second) {
query.term = query.term || "";
var firstPosition = first.text.toUpperCase().indexOf(
query.term.toUpperCase()
);
var secondPosition = second.text.toUpperCase().indexOf(
query.term.toUpperCase()
);
return firstPosition - secondPosition;
});
return sorted;
};
这将按照您希望的方式进行排序。您可以在下面找到一个完整的示例,其中所有部分都连接在一起。它使用了您在问题中提到的三个示例选项
var query={};
变量$element=$('select');
函数sortBySearchTerm(结果){
//不要改变传递的结果,复制一份
var排序=results.slice(0);
//Array.sort是就地排序
sorted.sort(函数(第一,第二){
query.term=query.term | |“”;
var firstPosition=first.text.toUpperCase().indexOf(
query.term.toUpperCase()的
);
var secondPosition=second.text.toUpperCase().indexOf(
query.term.toUpperCase()的
);
返回第一个位置-第二个位置;
});
返回排序;
};
$element.select2({
分拣机:SortBySearch术语,
语言:{
搜索:函数(参数){
//在查询发生时拦截查询
query=params;
//更改此选项以适合您的应用程序
返回“搜索…”;
}
}
});代码>
香蕉橙苹果
香蕉苹果橙
苹果香蕉橙
无需遵守条款:
$element.select2({
sorter: function (data) {
if(data && data.length>1 && data[0].rank){
data.sort(function(a,b) {return (a.rank > b.rank) ? -1 : ((b.rank > a.rank) ? 1 : 0);} );
}
return data;
}
,
matcher:function(params, data) {
// If there are no search terms, return all of the data
if ($.trim(params.term) === '') {
return data;
}
// Do not display the item if there is no 'text' property
if (typeof data.text === 'undefined') {
return null;
}
// `params.term` should be the term that is used for searching
// `data.text` is the text that is displayed for the data object
var idx = data.text.toLowerCase().indexOf(params.term.toLowerCase());
if (idx > -1) {
var modifiedData = $.extend({
// `rank` is higher when match is more similar. If equal rank = 1
'rank':(params.term.length / data.text.length)+ (data.text.length-params.term.length-idx)/(3*data.text.length)
}, data, true);
// You can return modified objects from here
// This includes matching the `children` how you want in nested data sets
return modifiedData;
}
// Return `null` if the term should not be displayed
return null;
}
})在原始列表中排列元素可能更容易。大概它们会在筛选过程中显示为已排序。我不理解你的评论。在用户开始搜索之前,我怎么知道如何排列列表呢。如果您最初按字母顺序排列列表,则在搜索过程中会收到哪个排序列表?搜索过程中的排序默认按字母顺序排列。这就是我想要改变的。我不认为这是完全清楚的,如果搜索词以你搜索的内容开始,你希望结果首先出现吗?只是提醒一下,你几乎可以保证文本
将包含搜索词。唯一的例外是,如果您使用的是自定义的匹配器
,此时您很可能知道异常是什么。感谢@KevinBrown的评论。我相信你的话,text
将包含搜索词,因此我相应地简化了代码。谢谢,这几乎可以实现,但它似乎无法对整个列表进行排序。比如,如果我有多个结果,其中“apple”是第一个单词,它会将一个放在顶部,然后将其他结果不排序,放在不相关的结果下面。我正在尝试@KevinBrown的方法。@nnyby-Huh。你只想匹配整个单词吗?例如,如果您正在搜索苹果
,并且有两个结果:香蕉橙苹果
和苹果红番茄
,是否希望香蕉橙苹果
首先显示?@heeneee它现在工作正常,谢谢!我实际上在尝试Kevin Brown的方法,这给了我同样的结果,即使我在其中添加了不区分大小写的hack,所以我想假设你的方法也会有同样的行为。谢谢。。。我一直在搞这个很长时间了。