Twitter Bootstrap TypeAhead + Knockout.js
A small example of how to databind observableArrays, normal arrays or even object properties to your typeahead.
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.0/bootstrap.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.1.0.js"></script>
<h1> Here's three examples of ways to add datasource to Twitter Bootstraps Typeahead. </h1>
<div class="container">
<p>Color</p>
<input type="text" data-bind="typeahead: colors"/>
<br/>
<p>Tasts</p>
<input type="text" data-bind="typeahead: 'mySuggestions'"/>
<br/>
<p>Animals</p>
<input type="text" data-bind="typeahead: 'myComplexObject.animals'"/>
<br/>
</div>
CSS
@import url('http://twitter.github.com/bootstrap/assets/css/bootstrap.css');
.container {
margin-top: 10px;
margin-left: 30px;
}
JavaScript
var ViewModel = function() {
this.colors = ko.observableArray(["Red", "Green", "Gray", "Golden", "Yellow", "Black", "Blue"]);
}
var mySuggestions = ["Sweet", "Sour", "Salt"]; // this may for example be from ajax call...
var myComplexObject = {
animals: ["pig", "pony", "dog", "cat", "cow", "chicken", "fish", "fox"]
}; // some sort of object that you're using.
//here's the binding
ko.bindingHandlers.typeahead = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var typeaheadSource; // <-- this is where our typeahead options will be stored in
//this is the parameter that you pass from you data-bind expression in the mark-up
var passedValueFromMarkup = ko.utils.unwrapObservable(valueAccessor());
if (passedValueFromMarkup instanceof Array) typeaheadSource = passedValueFromMarkup;
else {
// if the name contains '.', then we expect it to be a property in an object such as myLists.listOfCards
var splitedName = passedValueFromMarkup.split('.');
var result = window[splitedName[0]];
$.each($(splitedName).slice(1, splitedName.length), function(iteration, name) {
result = result[name];
});
// if we find any array in the JsVariable, then use that as source, otherwise init without any specific source and hope that it is defined from attributes
if (result != null && result.length > 0) {
typeaheadSource = result;
}
}
if (typeaheadSource == null) $(element).typeahead();
else {
$(element).typeahead({
source: typeaheadSource
});
}
},
};
ko.applyBindings(new ViewModel());