Select2 - Sorting results by query

nnyby picture nnyby · Aug 13, 2015 · Viewed 8.7k times · Source

I'm using Select2 version 4.0.0.

If my results contain multiple words, and the user enters one of those words, I want to display the results sorted by where the entered word is within the result.

For example, a user enters "apple", and my results are:

  1. "banana orange apple"
  2. "banana apple orange"
  3. "apple banana orange"

Then "apple banana orange" should appear first in the list of select2 results, because that is the result in which "apple" appears earliest within the result. I don't care so much about the ordering past that.

What do I override or configure to get something like this? It seems that matcher doesn't handle ordering, and sorter doesn't contain query data.

Answer

heenenee picture heenenee · Aug 19, 2015

You could grab the search query from the value of the input box generated by Select2 by identifying it with the select2-search__field class. That's probably going to break across versions, but since they don't provide a hook to get the query some sort of hack will be needed. You could submit an issue to have them add support for accessing the query during sort, especially since it looks like it was possible in 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>