2012-04-01 20 views
10

Sto utilizzando l'API film rottentomatoes in combinazione con il plug-in typeahead di Twitter che utilizza bootstrap 2.0. Sono stato in grado di integerare l'API ma il problema che sto avendo è che dopo ogni evento di keyup viene chiamata l'API. Questo è tutto bene e dandy, ma preferirei effettuare la chiamata dopo una breve pausa che consente all'utente di digitare prima diversi caratteri.Posso ritardare l'evento keyup per jquery?

Ecco il mio codice attuale che chiama l'API dopo un evento KeyUp:

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); 

       }); 

      } 
     } 
    }); 

E 'possibile impostare un piccolo ritardo e evitare di chiamare l'API dopo ogni keyup?

risposta

9

che può essere fatto facilmente in questo modo:

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 
} 
+0

Funziona bene ma sembra rimanere bloccato in un ciclo, effettuando una chiamata al datarequest ogni 200 ms? – Paul

+0

Nel codice, si attiva la chiave dopo la chiave: 'self.trigger ('keyup')'. Per la corretta gestione degli eventi keyup devi rimuovere 'ev.stopPropagation();' e 'self.trigger ('keyup')' –

+0

Questo ha fatto il trucco ... grazie! – Paul

-1

Piuttosto che un ritardo, se si desidera consentire all'utente di immettere alcuni caratteri prima della richiesta $ .getJSON ajax, è possibile modificare l'istruzione if in modo che l'utente debba immettere un numero minimo di caratteri, per esempio 3, prima di richiedere i dati:

if(!self.data('active') && self.val().length >=3){ 
4

In generale, ciò può essere ottenuto con setTimeout e clearTimeout metodi:

var timer; 

$('#textbox').keyup(function() { 
    if (timer) { 
     clearTimeout(timer); 
    } 
    timer = setTimeout('alert("Something cool happens here....");', 500); 
}); 

setTimeout eseguirà il javaScript fornito dopo il specificato intervallo in millisecondi. clearTimeout annullerà questa esecuzione.

Ho anche preparato jsFiddle demo mostrando lo snippet di codice in azione.

Riferimenti:

2

Per le persone che lavorano con v0.11 di typeahead.js e utilizzando Bloodhound per andare a prendere i suggerimenti a distanza, è possibile utilizzare l'opzione rateLimitWait di strozzare le richieste:

var search = new Bloodhound({ 
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'), 
    queryTokenizer: Bloodhound.tokenizers.whitespace, 
    remote: { 
    url: '/search?q=%QUERY', 
    rateLimitWait: 500 
    } 
});