Twitter Bootstrap comes packaged with a simple auto-complete library that’s stylistically integrated into the CSS framework. It’s convenient, but not the most-documented part of Bootstrap. I was working on a hobby project recently, and I wanted to have an auto-completing search field, but it took a bit of work to extend the basic implementation.
The first, and probably most important, step was to implement an AJAX data source. The plugin supports this out of the box, but the documentation page doesn’t have an example. It’s easy enough. You pass a function that takes the query and hands it off to one of jQuery’s magic asynchronous request functions, like so:
$(document).ready(function() { $("#searchfield").typeahead({ minLength: 3, source: function(query, process) { $.post('/search/typeahead', { q: query, limit: 8 }, function(data) { process(JSON.parse(data)); }); } }); });
Your request URL needs to respond with a JSON array of strings, which the typeahead library will process. The variables “q” and “limit” are sent along with the POST request in this example, and a PHP back-end returns the relevant data in response.
["Electric Light Orchestra", "Elvis Costello", "Eric Clapton"]
Once I had the asynchronous search working, I decided that it would be better if the user was taken to the search page as soon as they selected a suggested item, rather than having them click a search button. So I hooked in to the updater method, which runs whenever an item is selected.
$(document).ready(function() { $("#searchfield").typeahead({ minLength: 3, source: function(query, process) { $.post('/search/typeahead', { q: query, limit: 8 }, function(data) { process(JSON.parse(data)); }); }, updater: function (item) { document.location = "/search?q=" + encodeURIComponent(item); return item; } }); });
It’s just a simple matter of intercepting the selected item and jumping to a new page, passing the search string in the query. As far as I can tell, updater
is not documented at all on the Bootstrap site.
Now…what if a user doesn’t want to search for one of the suggestions? In its present form, the typeahead doesn’t give much choice. If it finds a suggestion, it’s automatically selected. While this is good for some situations, it might not make sense for some. My solution was to dynamically insert an additional item at the top of the suggestions list, matching the search query. The sorter
function worked well for that, as it runs whenever the list is updated.
$(document).ready(function() { $("#searchfield").typeahead({ minLength: 3, source: function(query, process) { $.post('/search/typeahead', { q: query, limit: 8 }, function(data) { process(JSON.parse(data)); }); }, updater: function (item) { document.location = "/search?q=" + encodeURIComponent(item); return item; }, sorter: function (items) { items.unshift(this.query); return items; } }); });
You just slip the query into the items array with unshift
and return the array with no further tampering.