views:

264

answers:

3

I am trying to implement a similar feature like the autosuggest feature for tags available below the text area on this site using Jquery. I am trying to figure out how the requests are sent after a few keystrokes and not after every keystroke. I am using a 'keyup' event to trigger the request on my app. I was made to realize that this may result in too many server hits and may affect performance.

It would be awesome if some could explain how i could implement the kind of thing stackOverflow does by not having a query run on every keyup.

+5  A: 

I have a similar feature in one of my windows applications. When the user types a character, a timer is started with a 1 second interval. In the Tick event, the search is started. If the user types again, the timer is restarted. So the search is only performed if the keyboard has been idle for more than a second.

Short sample (it's in C#, but easy enough to follow):

public partial class Form1 : Form
{
    private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

    public Form1()
    {
        InitializeComponent();

        timer.Interval = 1000;
        timer.Tick += new EventHandler(timer_Tick);
    }

    void timer_Tick(object sender, EventArgs e)
    {
        timer.Stop();

        // Do search, or what ever you want to do
        Console.WriteLine("Searching...");
    }

    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
        if (timer.Enabled)
        {
            timer.Stop();
        }

        timer.Start();
    }
}

I'm not experienced in Javascript, but the anwswer from here will help you I think:

<input name="domain" type="text" id="domain" onKeyUp="javascript:chk_me();">

var timer;
    function chk_me(){

       clearTimeout(timer);
       timer=setTimeout(function validate(){...},1000);
    }
Philip Wallace
Thanks Philip. So how would i manage the timestamp. Would I need something like a class variable to maintain the last timestamp. I'm a newbie with javascript though i use it everyday. Is it possible without creating Javascript classes
Sid
Take a look at the accepted answer in this question:http://stackoverflow.com/questions/1381751/onkeyup-javascript-time-delay
Philip Wallace
+2  A: 
var activity = new ActivityTimer(1000, function() {
 doSearch();
});

$("#searchBox").keyup(function(){ activity.reset() });

function ActivityTimer(deadline, callback) {
 var timer = -1;

 this.reset = function() {
  this.cancel();
  timer = setTimeout(callback, deadline);
 };

 this.cancel = function() {
  if(timer >= 0) {
   clearTimeout(timer);
   timer = -1;
  }
 };
}
Pickle
+2  A: 

the method you are referring to is called "Debouncing"

I usually have a "Debounce" function at the bottom of all my scripts

var debounce=function(func, threshold, execAsap) {
    var timeout;
    return function debounced () {
        var obj = this, args = arguments;
        function delayed () {
            if (!execAsap)
                func.apply(obj, args);
            timeout = null; 
        };
        if (timeout)
            clearTimeout(timeout);
        else if (execAsap)
            func.apply(obj, args);
        timeout = setTimeout(delayed, threshold || 100); 
    }; 
};

And then whenever I do anything that will benefit from a debounce I can use it generically

So your code would be written as

$("#search_box").keyup(debounce(function() {
    //do stuff in this function  
}
,350 /*determines the delay in ms*/
,false /*should it execute on first keyup event, 
       or delay the first event until 
       the value in ms specified above*/
));

see http://stackoverflow.com/questions/1568312/facebook-style-ajax-search/1569337 for a similar usecase...

pǝlɐɥʞ