views:

96

answers:

6

i wanna send keystrokes typed in a text field but only in 1s interval.

this is to reduce the load of sending an ajax request on each keypress.

so eg. if the user types 4 letters within a sec the request will send all these 4 letters. and lets say he types nonstop in 1 min, then the script will send on 1s interval till he stops typing.

at the moment my script looks like this:

$("#type_post").live('keyup', function() {
      $.post('posts.php', {post: $("#type_post").val()});
});

but that sends on everything keypress.

could someone help me out here

UPDATE: here is the code i used.

var last_post = '';

$('#type_post').focus(function() {
     // check if text has been changed every second when input field is focused
     setInterval(function() {
          if($('#type_post').val() != last_post)
          {
               // if changed, post it and set the new text as last text
               $.post('posts.php', {post: $("#type_post").val()});
               last_post = $("#type_post").val();
          }
     }, 1000);
});
+4  A: 

Well, disregarding how annoying this feature will be, you'll want to use setTimeout() (info here) to run a function every second and grab the text. If it's different, then do the ajax call.

Further to this, you'll only want this enabled when the textbox has focus, so you might set up a field and relevant actions on the 'focus' and 'blur' events.

Noon Silk
but that doesnt sound like an ultimate solution. there must be another way to activate this just on keypress.
weng
noname: jspcal has the solution for you. You could activate it on keypress as well, but you need to figure out when to *stop* the timer (in my example), in jspcal's approach, you simply need to compare times and do the update. Probably, his solution is better.
Noon Silk
also do not use the live binding method .. use .bind('keyup',...) instead, unless you are creating new field boxes with that feature dynamically..
Gaby
looked like this was the greatest solution after all. read my question for the code i wrote.
weng
+3  A: 

you can store the last update time in a variable, then check if the delay period has elapsed before doing the post.

jspcal
good idea, ill try and come back with an update
weng
+1  A: 

I'm using the Ajax Autocomplete for jQuery, version 1.1 which solves that problem nicely, this is the piece of code included on the OnKeyUp event:

  clearInterval(this.onChangeInterval);
  if (this.currentValue !== this.el.val()) {
    if (this.options.deferRequestBy > 0) {
      // Defer lookup in case when value changes very quickly:
      var me = this;
      this.onChangeInterval = setInterval(function() { me.onValueChange(); }, this.options.deferRequestBy);
    } else {
      this.onValueChange();
    }
  }

I would suggest you review it further to fully understand.

Homer1980ar
so i have to download the autocomplete plugin?
weng
+3  A: 

It's a horrible idea to send an AJAX request every second. You should instead consider using a combination of setTimeout and clearTimeout to only send the keystroke requests after the user has stopped typing. I'll get an example fixed up in a hot minute.

var timer = 0;
$("#type_post").live('keyup', function(e) {
    var val = $(this).val();
    // clear any existing timer
    clearTimeout(timer);
    // set a 1 second timeout
    timer = setTimeout(function() { keyLogger(val) }, 1000);
});

function keyLogger(val) {
    $.post('posts.php', {post: $("#type_post").val()});
}
cballou
but i want to send every sec cause this is kind of a live thing where other users see what you are typing.
weng
@noname - this will send if the user has paused typing for 1 second. The pause is easily adjustable by changing the 1000 (in milliseconds) to a lower number, perhaps **250**. This will reduce requests (and bandwidth) and send when user's are thinking about what to type next.
cballou
+3  A: 

One important thing to keep in mind is that, in user interaction terms, 4 seconds is a very long time to wait for something to happen. It's rather impractical to expect the user to wait anywhere near that long for feedback.

That being said, here's a partial implementation I worked up. It doesn't account for sending any data after the user blurs so it might be a little awkward when they exit- maybe not. I haven't tested it, but the general principle is there.

var sendInterval;
var lastValue;
$("#type_post").focus(function() {
         var input = $(this);
    sendInterval = setInterval(function() { sendData(input.val()); }, 4000);
});

$("#type_post").blur(function() {
    if(sendInterval)
        clearInterval(sendInterval);
});

function sendData(data) {
    if(lastValue !=  data) {
        lastValue = data;
        $.post('posts.php', {post: data});
    }
}
Nathan Taylor
+1  A: 

I've done something similar before, except using MooTools instead of jQuery... Take a look at the registration form at http://obviousspoilers.com/member/register (type a username in).

I coded that before learning about unobtrusive JavaScript so it uses onkeyup="..." onblur="...". The code could definitely be cleaned up, but feel free to use any of it. JavaScript is at http://obviousspoilers.com/res/script.js, take a look at the Register object.

Edit: Didn't read your question correctly, so this probably won't help :(

Daniel15