Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get text from field on keyup, but with delay for further typing

I have a form which is submitted remotely when the various elements change. On a search field in particular I'm using a keyup to detect when the text in the field changes. The problem with this is that when someone types "chicken" then the form is submitted seven times, with only the last one counting.

What would be better is something like this

  • keyup detected - start waiting (for one second)

  • another keyup detected - restart waiting time

  • waiting finishes - get value and submit form

before I go off and code my own version of this (I'm really a backend guy with only a little js, I use jQuery for everything), is there already an existing solution to this? It seems like it would be a common requirement. A jQuery plugin maybe? If not, what's the simplest and best way to code this?

UPDATE - current code added for Dan (below)

Dan - this may be relevant. One of the jQuery plugins I'm using on the page (tablesorter) requires this file - "tablesorter/jquery-latest.js", which, if included, leads to the same error with your code as before:

jQuery("input#search").data("timeout", null) is undefined http‍://192.168.0.234/javascripts/main.js?1264084467 Line 11

Maybe there's some sort of conflict between different jQuery definitions? (or something)

$(document).ready(function() {
  //initiate the shadowbox player
//  Shadowbox.init({
//    players:  ['html', 'iframe']
//  });
}); 

jQuery(function(){
  jQuery('input#search')
    .data('timeout', null)
    .keyup(function(){
      jQuery(this).data('timeout', setTimeout(function(){
          var mytext = jQuery('input#search').val();
          submitQuizForm();
          jQuery('input#search').next().html(mytext);
        }, 2000)
     )
     .keydown(function(){
       clearTimeout(jQuery(this).data('timeout'));
     });
    });
});

function submitQuizForm(){
  form = jQuery("#searchQuizzes");
  jQuery.ajax({
    async:true, 
    data:jQuery.param(form.serializeArray()), 
    dataType:'script', 
    type:'get', 
    url:'/millionaire/millionaire_quizzes',
    success: function(msg){ 
     // $("#chooseQuizMainTable").trigger("update"); 
    }
  }); 
  return true;
}
like image 944
Max Williams Avatar asked Jan 20 '10 12:01

Max Williams


People also ask

How do I delay Keyup?

In this article, we will see how to use keyup with a delay in jQuery. There are two ways to achieve the same: Approach 1: Using the keypress(), fadeIn(), delay() and fadeOut() methods in the jQuery library and clearTimeout() and setTimeout() methods in native JavaScript.

How do you execute a function only after the user stops typing?

Executing a function after a certain amount of inactivity is known as debouncing. Debouncing can be helpful for many reasons. One of the most popular applications in web development is to execute a search or filter some results after a user has stopped typing text in a textbox.


2 Answers

Here's your fancy jquery extension:

(function($){

$.widget("ui.onDelayedKeyup", {

    _init : function() {
        var self = this;
        $(this.element).keyup(function() {
            if(typeof(window['inputTimeout']) != "undefined"){
                window.clearTimeout(inputTimeout);
            }  
            var handler = self.options.handler;
            window['inputTimeout'] = window.setTimeout(function() {
                handler.call(self.element) }, self.options.delay);
        });
    },
    options: {
        handler: $.noop(),
        delay: 500
    }

});
})(jQuery);

Use it like so:

    $("input.filterField").onDelayedKeyup({
        handler: function() {
            if ($.trim($(this).val()).length > 0) {
                //reload my data store using the filter string.
            }
        }
    });

Does a half-second delay by default.

like image 27
Steven Francolla Avatar answered Sep 18 '22 13:09

Steven Francolla


Sorry i haven't tested this and it's a bit off the top of my head, but something along these lines should hopefully do the trick. Change the 2000 to however many milliseconds you need between server posts

<input type="text" id="mytextbox" style="border: 1px solid" />
<span></span>

<script language="javascript" type="text/javascript">
    jQuery(function(){
      jQuery('#mytextbox')
        .data('timeout', null)
        .keyup(function(){
            clearTimeout(jQuery(this).data('timeout'));
            jQuery(this).data('timeout', setTimeout(submitQuizForm, 2000));
        });
    });
</script>
like image 71
dan richardson Avatar answered Sep 18 '22 13:09

dan richardson