select2 search - match only words that start with search term
Asked Answered
B

3

21

I migrated from chosen to select2 plugin because it works better for me, but its documentation is very poor when compared to chosen. Could anyone tell me what option(s) should be used to make select2 search function to filter words that just begin with search term (and don't contain it in the middle).

Let's say select2 field has those options: banana, apple, pineapple.

When user enters "app" (or apple), only apple should be returned (because it's the only word that starts with apple). Now, it returns both apple and pineapple.

After lots of search I figured out that some custom matcher needs to be used, but that's all so far.

Blowhard answered 22/7, 2015 at 19:4 Comment(0)
O
22

Select2 provides an example in the documentation on how to use a custom matcher function for matching search terms to search results. The example given is this exact use case.

function matchStart (term, text) {
  if (text.toUpperCase().indexOf(term.toUpperCase()) == 0) {
    return true;
  }
 
  return false;
}
 
$.fn.select2.amd.require(['select2/compat/matcher'], function (oldMatcher) {
  $("select").select2({
    matcher: oldMatcher(matchStart)
  })
});
<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.full.js"></script>

<select style="width: 200px">
  <option value="AL">Alabama</option>
  <option value="AK">Alaska</option>
  <option value="AZ">Arizona</option>
</select>
Oarsman answered 22/7, 2015 at 23:28 Comment(1)
Thanks - this was helpful - what is confusing to me is - how would you / could you pass in additional configurations? I simply set up an object for the configs, and inside the function(oldMatcher) {...} set the config.matcher property: config.matcher = oldMatcher(matchStart);.... does that make sense?Crestfallen
M
35

Select2 4.0.0

function matchStart(params, data) {
    params.term = params.term || '';
    if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) == 0) {
        return data;
    }
    return false;
}

$("select").select2({
    matcher: function(params, data) {
        return matchStart(params, data);
    },
});
Mathis answered 29/6, 2016 at 1:40 Comment(1)
I would also recommend to remove white space or trim() on data.text, it didn't work for me until I did that.Slackjawed
O
22

Select2 provides an example in the documentation on how to use a custom matcher function for matching search terms to search results. The example given is this exact use case.

function matchStart (term, text) {
  if (text.toUpperCase().indexOf(term.toUpperCase()) == 0) {
    return true;
  }
 
  return false;
}
 
$.fn.select2.amd.require(['select2/compat/matcher'], function (oldMatcher) {
  $("select").select2({
    matcher: oldMatcher(matchStart)
  })
});
<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.full.js"></script>

<select style="width: 200px">
  <option value="AL">Alabama</option>
  <option value="AK">Alaska</option>
  <option value="AZ">Arizona</option>
</select>
Oarsman answered 22/7, 2015 at 23:28 Comment(1)
Thanks - this was helpful - what is confusing to me is - how would you / could you pass in additional configurations? I simply set up an object for the configs, and inside the function(oldMatcher) {...} set the config.matcher property: config.matcher = oldMatcher(matchStart);.... does that make sense?Crestfallen
A
1

This is optinized matcher function for large data sets. Others works slow

function matchStart(params, data) {
    if ($.trim(params.term) === '') {
        return data;
    }
    if (typeof data.text === 'undefined') {
        return null;
    }
    if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) == 0) {
        return data;
    }
    return null;
}  

$("select").select2({
    matcher: function(params, data) {
        return matchStart(params, data);
    }
});
Appreciate answered 19/4, 2023 at 22:38 Comment(2)
Why is this optimized? What makes it faster than the other solutions? Please explain your code.Adamo
Have no explanation, sorry) This is original function with little change in "indexOf" row. Just tried other and this solutionAppreciate

© 2022 - 2024 — McMap. All rights reserved.