1

I am working on a way to autocomplete function to navigate through steps of a form. Here is the code that when 5 characters are entered into an input, it then moves to the next element. My delay is working great, but I don't have a way to stop it from completing if characters get deleted after 5 characters are entered. It just fires off the focus right after that no matter what has changed in the input.

Any thoughts?

var delay = (function(){
    var timer = 0;
    return function(callback, ms) {
        clearTimeout (timer);
        timer = setTimeout(callback, ms);
    }; 
})();

$('input').keyup(function(){
    if($(this).val().length == 5) {
        delay(function(){ $("#saveForm2").focus(); }, 2000 );  
    }
})
2
  • I don't see where you're using jQuery's .delay() method. Commented Aug 30, 2010 at 22:44
  • oh actually I'm not, I neglected that fact when I was writing out the subject, it's a custom delay function Commented Aug 30, 2010 at 22:54

2 Answers 2

3

If you're looking for an easy way to associate a timeout instance with an element, consider using jQuery's .data() method.

Something like this.

$('input').keyup(function() {
    var $th = $(this);
    var data = $th.data();
    if(data.timeout === undefined) {
        data.timeout = null;
    }
    if ($th.val().length == 5) {
        clearTimeout(data.timeout);
        data.timeout = setTimeout(function() {
            $("#saveForm2").focus();
        }, 2000);
    } else {
        clearTimeout(data.timeout);
    }
});​

I don't think the way you were using the closure was quite right. I think you would need to assign the handler to the element inside the closure as well, so it has a local reference to the instance.

EDIT: Made a little more efficient with earlier stored reference to data().

Sign up to request clarification or add additional context in comments.

Comments

0

Each time you call delay(), you clobber your timeout handle, which means that you can't manage it after the fact. It also means that you're going to fire off a request every time you hit 5 characters, if I read that correctly. Try something like this:

var delayTimer;
var nextField = function() { $("#saveForm2").focus(); }
$('input').keyup(function(){
  clearTimeout(delayTimer);
  if($(this).val().length >= 5) {
    delayTimer = setTimeout(nextField, 2000);
  }
})

That'll a) fire off no more than 1 request unless you wait more than 2 seconds between keystrokes, and b) will cancel any pending request if you drop back under 5 characters before the timeout expires. As a bonus, it won't create a whole mess of anonymous functions.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.