0

I am trying to create something like an onFinishTyping event which sets a timeout of 3 seconds. If the user writes something during these 3 seconds, I need to destroy that timer and set a new one. The problem is that after each button click, the event is fired.

Here is what I have:

//setup before functions
const jq = jQuery.noConflict();
var typingTimer; // Timer identifier.
var doneTypingInterval = 3000; // Time in ms.

jq(document).ready(function() {
  // On keyup, start the countdown.
  jq('.table-search-field').keyup(function(event) {
    var typingTimer = setTimeout(function() {
      doneTyping(event.target);
    }, doneTypingInterval);
  });

  // On keydown, clear the countdown.
  jq('.table-search-field').keydown(function() {
    clearTimeout(typingTimer);
  });
});

// User has “finished typing”, do something.
function doneTyping(field) {
  var value = jq(field).val().toLowerCase(); // lower case

  jq.ajax('index.php?option=com_mycomponent&task=player.search&keyword=' + value)
    .done(function(data) {
      console.log('ok');
    }).fail(function() {
      console.log('fail');
    });
};
Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
insanebits
  • 818
  • 1
  • 6
  • 24

2 Answers2

6

Don't declare this variable again, just remove var; you are creating a local copy of this variable by using the var keyword. The statement creates the variable locally in that specific function.

 typingTimer = setTimeout(function(){
War10ck
  • 12,387
  • 7
  • 41
  • 54
Govind Malviya
  • 13,627
  • 17
  • 68
  • 94
3

Try using a closure so that the timeout variable is within the scope of the functions you use it in:

(function() {

 //setup before functions
var typingTimer;                //timer identifier
var doneTypingInterval = 3000;  //time in ms
// Notice: jq = jQuery.noConflict();

jq(document).ready(function(){
    //on keyup, start the countdown
    jq('.table-search-field').keyup(function(event){
        var typingTimer = setTimeout(function(){
            doneTyping(event.target);
        }, doneTypingInterval);
    });

    //on keydown, clear the countdown
    jq('.table-search-field').keydown(function(){
        clearTimeout(typingTimer);
    });

});


//user is "finished typing," do something
function doneTyping (field) {
    var value = jq(field).val().toLowerCase();// lower case

    jq.ajax('index.php?option=com_mycomponent&task=player.search&keyword='+value)
    .done(function(data){
        console.log('ok');
    }).fail(function(){
        console.log('fail');
    }); 
};

})();

Don't just remove the var as suggested without considering the implications, you're needlessly dumping variables into the window object which can then be overwrote by other script blocks.

Lloyd
  • 29,197
  • 4
  • 84
  • 98
  • Thank's for your time, using separated namespace I believe would be better practice, and `var` was left there by accident while experimenting. But removing var wasn't complete solution, it appears that if you click multiple buttons at the same time multiple timers will be set and you will only have reference to the last set, thats why ajax request was sent multiple times. – insanebits Jul 29 '13 at 12:21
  • Ahh yes that is true. – Lloyd Jul 29 '13 at 12:42