Select2 - 按查询排序结果

nny*_*yby 13 javascript jquery jquery-select2 jquery-select2-4

我正在使用Select2版本4.0.0.

如果我的结果包含多个单词,并且用户输入其中一个单词,我想显示按输入单词在结果中的位置排序的结果.

例如,用户输入"apple",我的结果是:

  1. "香蕉橙苹果"
  2. "香蕉苹果橙"
  3. "苹果香蕉橙"

然后"apple banana orange"应首先出现在select2结果列表中,因为这是"apple"最早出现在结果中的结果.我不太关心过去的顺序.

我可以覆盖或配置什么来获得这样的东西?它似乎matcher不处理排序,并且sorter不包含查询数据.

hee*_*nee 13

您可以通过使用select2-search__field类识别它来从Select2生成的输入框的值中获取搜索查询.这可能会打破各个版本,但由于他们没有提供钩子来获取查询,因此需要某种黑客攻击.您可以提交一个问题,让他们在排序期间添加对访问查询的支持,特别是因为它似乎可以在Select2 3.5.2中使用.

$('#fruit').select2({
  width: '200px',
  sorter: function(results) {
    var query = $('.select2-search__field').val().toLowerCase();
    return results.sort(function(a, b) {
      return a.text.toLowerCase().indexOf(query) -
        b.text.toLowerCase().indexOf(query);
    });
  }
});
Run Code Online (Sandbox Code Playgroud)
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" />

<select id="fruit">
  <option>Banana Orange Apple</option>
  <option>Banana Apple Orange</option>
  <option>Apple Banana Orange</option>
  <option>Achocha Apple Apricot</option>
  <option>Durian Mango Papaya</option>
  <option>Papaya</option>
  <option>Tomato Papaya</option>
  <option>Durian Tomato Papaya</option>
</select>
Run Code Online (Sandbox Code Playgroud)


Kev*_*own 8

这里的问题是4.0.0版本中的Select2将结果查询与结果显示分开.因此sorter,您通常用于对结果进行排序的选项不会传递所做的查询(包括搜索项).

因此,您需要找到一种方法来缓存所做的查询,以便在排序时使用它.在我关于在结果中加下搜索词的下划线的答案,我通过loading模板方法缓存查询,模板方法总是在进行搜索时触发.这里也可以使用相同的方法.

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…';
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

所以现在你可以构建一个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;
};
Run Code Online (Sandbox Code Playgroud)

这将按照您希望的方式对事物进行排序.您可以在下面找到所有连接在一起的部件的完整示例.它使用您在问题中提到的三个示例选项.

var query = {};
var $element = $('select');

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;
};

$element.select2({
  sorter: sortBySearchTerm,
  language: {
    searching: function (params) {
      // Intercept the query as it is happening
      query = params;

      // Change this to be appropriate for your application
      return 'Searching…';
    }
  }
});
Run Code Online (Sandbox Code Playgroud)
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script>

<select style="width: 50%">
  <option>banana orange apple</option>
  <option>banana apple orange</option>
  <option>apple banana orange</option>
</select>
Run Code Online (Sandbox Code Playgroud)