The JS components of Twitter Bootstrap are somewhat lacking in functionality when compared to well established plugins that do the same things (autocompletes, tooltips, etc.). However, I still use them on Bootstrap projects just because it is nice to have homogeneous interfaces to things—and, of course, it is easy then to jump on other Bootstrap projects and be in familiar territory right off the bat.
One of the continuing problems I face is with Bootstrap Typeahead, in particular its lack of native support for non-String items. I constantly come across this; rare is it that one can identify an item in a list by that item’s user-friendly string representation, i.e. more often than not you need to be working with a fully typed thing, not just a string.
Other autocompletes and typeaheads support rich objects out of the box but Typeahead needs a little massaging—fortunately not much, and not anything requiring changes to the core. Here is a sample showing a Typeahead that uses a rich UsState
class (a natural extension to the Twitter demo using string state names):
Bootstrap Typeahead only gets tripped up with rich object sources for the updater
method namely. The key component here is ensuring your class has a toString()
method that serializes instances correctly, as well as a fromString()
static method to deserialize. For my purposes I include the popular json2.js for JSON.stringify()
and JSON.parse()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/** * @return {String} Serialized state. * * @see fromString() */ UsState.prototype.toString = function() { return JSON.stringify(this); }; /** * @static * * @param {String} serializedState * * @return {UsState} * * @see toString() */ UsState.fromString = function(serializedState) { return $.extend(new UsState(), JSON.parse(serializedState)); }; |
Then, in your Typeahead updater
:
1 2 3 4 5 |
updater: function(state) { state = UsState.fromString(state); $stateMessage.html('<strong>' + state.name + '</strong> has ' + state.numElectoralVotes + ' electoral votes.'); return state.name; }, |
Note that Typeahead passes the stringified object, which we deserialize, and expects a string return to stuff into the text input.
And because I love CoffeeScript so much, here is the same demo in CS: