ajsie
ajsie

Reputation: 79716

send keystrokes with ajax after 1s?

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

Upvotes: 3

Views: 675

Answers (6)

Nathan Taylor
Nathan Taylor

Reputation: 24606

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

Upvotes: 3

Corey Ballou
Corey Ballou

Reputation: 43477

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

Upvotes: 3

Daniel Lo Nigro
Daniel Lo Nigro

Reputation: 3424

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 :(

Upvotes: 1

Homer1980ar
Homer1980ar

Reputation: 277

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.

Upvotes: 1

jspcal
jspcal

Reputation: 51904

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

Upvotes: 3

Noon Silk
Noon Silk

Reputation: 55082

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.

Upvotes: 4

Related Questions