How to customize Bootstrap typeahead layout/function for more than just text?

Use the highlighter method:

$('.typeahead').typeahead({
    highlighter: function(item){
        return "<div>.......</div>";
    }
});

Method used to highlight autocomplete results. Accepts a single argument item and has the scope of the typeahead instance. Should return html.


mgadda's answer neatly solves the issue for how to augment rendering items with custom data. Unfortunately this metadata isn't available once an item is selected, because bootstrap's select() method calls your updater() with a value taken from the DOM, not your loaded String:

var val = this.$menu.find('.active').attr('data-value');

One way around this is to set the metadata you need to DOM elements in highlighter(), then find them in your updater(). Since we only needed an integer, we set an ID to the image tag itself, and in updater, find it based on the image tag that's still visible:

$('.your_textboxes').typeahead({
  highlighter: function(item) {
    return('<img src="' + item.friend.img + '" id="klid_' + item.friend.id + '" />' + item);
  },
  updater: function(val) {
    var klid = $('ul.typeahead li.active:visible a img');
    if (klid && klid.length) {
      klid = klid[0].id.substr(5);
      // do stuff with metadata...
    }
    return(val);
}

Need more metadata? Wrap your highlighter in a span, or add some hidden form fields.

This feels kludgey though. If anyone has a cleaner solution, I'd love to see it.


Typeahead expects that everything passed into the process callback from the source callback will be a string. Unfortunately, this means that your highlighter callback is somewhat limited in the kind of HTML it can generate since you can only modify a string so much.

You can, however, define your source method such that it returns the usual array of string objects each of which have an additional data property that contains all the data you'll need to generate HTML in the highlighter.

$('.typeahead').typeahead
  source: (query, processCallback)->
    $.get '/users', q: query, (data)->
      processCallback data.map (user)->
        item = new String("#{user.first_name} #{user.last_name}")
        item.data = user
        item

In this form, item will be passed around the internals of typeahead as a string, and when it finally reaches your custom highlighter, you can use the data property to build more complex html:

$('.typeahead').typeahead
  highlighter: (item)->
    "<img src=\"#{item.data.avatar_url}\" /> #{item}"