I'm using the rottentomatoes movie API in conjunction with twitter's typeahead plugin using bootstrap 2.0. I've been able to integerate the API but the issue I'm having is that after every keyup event the API gets called. This is all fine and dandy but I would rather make the call after a small pause allowing the user to type in several characters first.
Here is my current code that calls the API after a keyup event:
var autocomplete = $('#searchinput').typeahead()
.on('keyup', function(ev){
ev.stopPropagation();
ev.preventDefault();
//filter out up/down, tab, enter, and escape keys
if( $.inArray(ev.keyCode,[40,38,9,13,27]) === -1 ){
var self = $(this);
//set typeahead source to empty
self.data('typeahead').source = [];
//active used so we aren't triggering duplicate keyup events
if( !self.data('active') && self.val().length > 0){
self.data('active', true);
//Do data request. Insert your own API logic here.
$.getJSON("http://api.rottentomatoes.com/api/public/v1.0/movies.json?callback=?&apikey=MY_API_KEY&page_limit=5",{
q: encodeURI($(this).val())
}, function(data) {
//set this to true when your callback executes
self.data('active',true);
//Filter out your own parameters. Populate them into an array, since this is what typeahead's source requires
var arr = [],
i=0;
var movies = data.movies;
$.each(movies, function(index, movie) {
arr[i] = movie.title
i++;
});
//set your results into the typehead's source
self.data('typeahead').source = arr;
//trigger keyup on the typeahead to make it search
self.trigger('keyup');
//All done, set to false to prepare for the next remote query.
self.data('active', false);
});
}
}
});
Is it possible to set a small delay and avoid calling the API after every keyup?
it can be easily done like this:
var autocomplete = $('#searchinput').typeahead().on('keyup', delayRequest);
function dataRequest() {
// api request here
}
function delayRequest(ev) {
if(delayRequest.timeout) {
clearTimeout(delayRequest.timeout);
}
var target = this;
delayRequest.timeout = setTimeout(function() {
dataRequest.call(target, ev);
}, 200); // 200ms delay
}