I'd like to sort my jQuery Autocomplete UI results based on where in the string the match occurs. The results where the match is the first letter should be prioritized above results in which the match is in the middle of the string.
A search for "M" should return:
Matt, Michael, Sam, Tim, Adam, Benjamin
Instead, since it's just returning the items in alphabetical order right now, I'm getting this:
Adam, Benjamin, Matt, Michael, Sam, Tim
Unfortunately, it looks like Autocomplete UI doesn't have any options for doing something like this, instead it just presents the results in the order it received them. Having MySql do the sorting isn't an option since all the possible matches are preloaded so that I'm not making calls to the database with every keystroke. Has anybody done anything like this?
You can provide any local filtering logic you'd like by providing the source
option a function instead of a simple array. Here's a quick example that will do the basics of what you want:
var source = ['Adam', 'Benjamin', 'Matt', 'Michael', 'Sam', 'Tim'];
$("input").autocomplete({
source: function (request, response) {
var term = $.ui.autocomplete.escapeRegex(request.term)
, startsWithMatcher = new RegExp("^" + term, "i")
, startsWith = $.grep(source, function(value) {
return startsWithMatcher.test(value.label || value.value || value);
})
, containsMatcher = new RegExp(term, "i")
, contains = $.grep(source, function (value) {
return $.inArray(value, startsWith) < 0 &&
containsMatcher.test(value.label || value.value || value);
});
response(startsWith.concat(contains));
}
});
Example: http://jsfiddle.net/zkVrs/
Basically, the logic is to build up an array of matches that start with the term, and then concatenate that with matches that contain the term but don't start with it.
Performance could be a problem here, especially with the $.inArray
call. Might be a better way to accomplish that portion, but hopefully that will give you a good starting point.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With