<!DOCTYPE HTML>
<html>
<head>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet" />
</head>
<body>
<br/>
<div class="container">
<div class="row">
<div class="span12">
<form>
<input
type="text"
class="span6 typeahead"
placeholder="Who was your favorite James Bond?"
autocomplete="off"
data-provide="typeahead"
/>
<br/>
<input type="text" class="span1" name="bondId" id="bondId" value="" />
</form>
</div>
</div>
<div class="row">
<div class="span6">
<p>
This example is functionally equivalent to the previous one with one change: requests to the "api" are only made
after user input has stopped for 300ms. If you type slowly a request is made for every keypress, but if you
type relatively quickly then less requests are made. This is considered a good practice -- fewer requests
less frequently will save in total bandwidth usage and results will likely appear faster.
</p>
<p>
This is accomplished using the debounce function in the <a href="http://underscorejs.org">underscore.js</a> library.
</p>
</div>
</div>
</div>
<script src="//code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
<script src="//underscorejs.org/underscore-min.js"></script>
<script type="text/javascript">
$(function(){
var bondObjs = {};
var bondNames = [];
//get the data to populate the typeahead (plus an id value)
var throttledRequest = _.debounce(function(query, process){
//get the data to populate the typeahead (plus an id value)
$.ajax({
url: 'bonds.json'
,cache: false
,success: function(data){
//reset these containers every time the user searches
//because we're potentially getting entirely different results from the api
bondObjs = {};
bondNames = [];
//Using underscore.js for a functional approach at looping over the returned data.
_.each( data, function(item, ix, list){
//for each iteration of this loop the "item" argument contains
//1 bond object from the array in our json, such as:
// { "id":7, "name":"Pierce Brosnan" }
//add the label to the display array
bondNames.push( item.name );
//also store a hashmap so that when bootstrap gives us the selected
//name we can map that back to an id value
bondObjs[ item.name ] = item.id;
});
//send the array of results to bootstrap for display
process( bondNames );
}
});
}, 300);
$(".typeahead").typeahead({
source: function ( query, process ) {
//here we pass the query (search) and process callback arguments to the throttled function
throttledRequest( query, process );
}
, updater: function ( selectedName ) {
//save the id value into the hidden field
$( "#bondId" ).val( bondObjs[ selectedName ] );
//return the string you want to go into the textbox (the name)
return selectedName;
}
});
});
</script>
</body>
</html>
[
{ "id":1, "name":"Barry Nelson" }
,{ "id":2, "name":"David Niven" }
,{ "id":3, "name":"Sean Connery" }
,{ "id":4, "name":"George Lazenby" }
,{ "id":5, "name":"Roger Moore" }
,{ "id":6, "name":"Timothy Dalton" }
,{ "id":7, "name":"Pierce Brosnan" }
,{ "id":8, "name":"Daniel Craig" }
]