Monday, January 27, 2014

Sorting Autocomplete Responses For Relevancy

The autocomplete widget will search a given data source for the term the user has typed into the text box. This happens as the user types, so with each keystroke, there's potential for a new data response to be rendered. This response, however, doesn't do any sorting. For example, the user could type "games", which could yield hundreds of results. The autocomplete widget isn't going to display hundreds of items, because the user would have to use their eyes to sift throught the results, line-by-line, which kind of defeats the purpose of the widget. Rather than displaying the autocomplete items in the same order as the source data, we could first sort them by some criteria.

Here's a simple way to do that. It uses the timestamp field to sort the autocomplete response for relevancy. We could use any other ordering criteria, but "most recent" is a fairly universal thing to do. Here's what the results look like before the sorting criteria is applied.

And here's the same autocomplete query with sorting applied.

"Hazelnut" comes out on top — it equally matches the other items in terms of string matches, but has the most recent timestamp. While there are only four items to display here, this really comes in handy when autocomplete is truncating the results — you're not missing out on the most relevant items. Here's what the code to create the autocomplete widget looks like.

$( "#tags" ).autocomplete({
    source: function( request, response ) {
        
        var filtered = $.ui.autocomplete.filter(
            nuts,
            request.term
        );
        
        filtered.sort(function( a, b ) {
            return b.timestamp - a.timestamp;
        });
        
        response( filtered );
        
    }
});

We're supplying the autocomplete source option a function. This function takes a request argument, when holds the current search term, as well as a response argument, a function to call with the data once we've filtered it. The first thing we do is filter the data source using $.ui.autocomplete.filter(). So far, we're doing everything that the autocomplete widget would do by default. The difference is that once we've filtered the data, we sort it. We do this based on the timestamp property of the each data item, and we do so in descending order. This is where you put any relevancy criteria you like.