I upgraded to the awesome new 1.4 version of jQuery recently in preparation for deploying another beta version of my site. Unfortunately the jquery-autocomplete plugin by Jörn Zaefferer doesn’t work with this new version. However, the equally awesome jQuery user interface library, jQuery UI, now has a new autocomplete widget that is based upon Jörn’s design. The API isn’t quite the same, but after some reading you’ll find that most of the functionality is still there. However the new UI widget does not support caching requests, leaving that to the user to implement. This kind of surprised me, as I would think that would be a commonly requested feature. But perhaps the UI folks felt that everyone would have different caching requirements. There is one example on the UI site of how to cache, but curiously it only caches the last request, which doesn’t seem all that useful to me.
In any event, after reading the documentation, it wasn’t hard to implement caching for my purposes. The following code simply caches the last 16 requests. Once the cache is full, it is flushed completely and ready to be filled again. Simple, crude, but hopefully somewhat effective. I’m not a Javascript expert, but this will work for me. I hope someone else finds it useful and can use it as a starting point for their use-case.
$(function() {
var cache = {};
var cacheSize = 0;
$("#id_of_your_text_box").autocomplete({
delay: 400,
minLength: 2,
source: function(request, response) {
if (cache[request.term]) {
response(cache[request.term]);
return;
}
$.ajax({
url: "/your/url/goes/here/",
type: "GET",
data: {
q: request.term,
limit: 10
},
dataType: "json",
success: function(data, textStatus) {
if (cacheSize >= 16) {
cache = {};
cacheSize = 0;
}
cache[request.term] = data;
++cacheSize;
response(data);
},
error: function(xhr, textStatus, ex) {
alert('Oops, an error occurred. ' + xhr.statusText + ' - ' +
xhr.responseText);
}
});
}
});
});
The key to making this to work is to provide your own source function to the autocomplete widget. The widget will call this function when it needs data. Inside the function we simply check to see if request.term is already in our cache. If it is, then we simply return the cached result via the response callback function. If not, we have to make an ajax call to the server to retrieve the data. When the ajax call completes, we store the result in our cache and then return it to the widget.
Again, this code simply stores the last 16 requests. When we run out of room we simply empty the cache and start over. A more sophisticated algorithm could use a different strategy like removing only the first item put in the cache or even the “least recently used” cache item. Break out your college computer science textbook on caching strategies and go nuts here.
The other feature this code doesn’t do is provide matching capabilities. For example, if the user has typed “foo” in the input box, this code will not return results for “bar foo”. If you need this, I suggest looking at the caching example on the UI site, or even at Jörn Zaefferer’s source code.
Tags: autocomplete, javascript, jquery, jquery-ui, plugins