Select2 - Сортировка результатов по запросу
Я использую Select2 version 4.0.0.
Если мои результаты содержат несколько слов, и пользователь вводит одно из этих слов, я
хотите отобразить результаты, отсортированные по тому, где введенное слово находится в результате.
Например, пользователь вводит "яблоко", и мои результаты:
- "банановое апельсиновое яблоко"
- "банановый яблочный апельсин"
- "яблочный банановый апельсин"
Затем "яблочный банановый апельсин" должен появиться сначала в списке результатов select2, потому что это результат, в котором "яблоко" появляется в самом начале в результате. Мне все равно, о том, как это сделать.
Что я могу переопределить или настроить, чтобы получить что-то вроде этого? Кажется, что matcher
не
упорядочивание порядка, а sorter
не содержит данных запроса.
Ответы
Ответ 1
Вы можете захватить поисковый запрос из значения поля ввода, сгенерированного Select2, путем идентификации его с классом select2-search__field
. Вероятно, это приведет к разрыву версий, но поскольку они не обеспечивают крючок для получения запроса, потребуется какой-то хак. Вы можете отправить вопрос, чтобы они добавили поддержку для доступа к запросу во время сортировки, тем более, что это похоже на возможность выбора в 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);
});
}
});
<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>
Ответ 2
Проблема в том, что Select2 в версии 4.0.0 отделил запрос результатов от отображения результатов. Из-за этого параметр 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…';
}
}
});
Итак, теперь вы можете создать собственный 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 = {};
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…';
}
}
});
<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>