4

I have a form which uses the jQuery validation plugin to validate its fields. In one of these fields, validation will be done by ajax. The problem is that every key stroke will trigger this validation rule and hence make ajax calls, which I don't want. Now I can disable onkeyup for this field, but I would prefer to have a delay of 5 seconds after the user types and then call upon my custom rule which contains the ajax method.

I've been searching for a while, came upon this How to delay the .keyup() handler until the user stops typing? but don't know how to use it with the validation plugin. Can someone help me figure this out?

jQuery.validator.addMethod("ruleName", function(value, element) {
   // AJAX call here to validate value
});

jQuery('form').validate({
   onkeyup: function(element) {
   // Do I do something here ?
   },
   rules: {
      name: {
      required: true,
      ruleName: true
     }
  }
});
Community
  • 1
  • 1
dr.jekyllandme
  • 613
  • 2
  • 11
  • 22
  • `.ajax()` validation may work better using the [built-in `remote` rule](http://jqueryvalidation.org/remote-method/). And typically, you would conditionally disable the `onkeyup` option depending on field, not use a delay. However, "yes", you would put something there... what have you tried? – Sparky Jan 11 '15 at 17:22
  • 1
    Built-in `remote` rule has no reference to the input element itself. So if you're better off using `addMethod` structure. – Slava Apr 26 '15 at 20:22

1 Answers1

2

You can change the onkeyup function, but this will have an effect on all fields in your form, so either you have a delay in every field or you have no delay.

From the jquery.validate.js the default onkeyup function is given as

onkeyup: function( element, event ) {

            // Avoid revalidate the field when pressing one of the following keys
            // Shift       => 16
            // Ctrl        => 17
            // Alt         => 18
            // Caps lock   => 20
            // End         => 35
            // Home        => 36
            // Left arrow  => 37
            // Up arrow    => 38
            // Right arrow => 39
            // Down arrow  => 40
            // Insert      => 45
            // Num lock    => 144
            // AltGr key   => 225
            var excludedKeys = [
                16, 17, 18, 20, 35, 36, 37,
                38, 39, 40, 45, 144, 225
            ];

            if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {
                // Do nothing
                return;
            } else if ( element.name in this.submitted || element.name in this.invalid ) {
                // Start validation
                this.element( element );
            }
        },

if you want to add a delay before the validation you need to change your code to

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

jQuery('form').validate({
   onkeyup: onkeyup: function( element, event ) {

            // Avoid revalidate the field when pressing one of the following keys
            // Shift       => 16
            // Ctrl        => 17
            // Alt         => 18
            // Caps lock   => 20
            // End         => 35
            // Home        => 36
            // Left arrow  => 37
            // Up arrow    => 38
            // Right arrow => 39
            // Down arrow  => 40
            // Insert      => 45
            // Num lock    => 144
            // AltGr key   => 225
            var excludedKeys = [
                16, 17, 18, 20, 35, 36, 37,
                38, 39, 40, 45, 144, 225
            ];

            if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {
                return;
            } else if ( element.name in this.submitted || element.name in this.invalid ) {

          // Here is the part where the delay is added. 
          // In this example, the delay time is 1000ms.
          var temp_obj = this;
          delay(function(){
            temp_obj.element( element );
          }, 1000);

            }
        },
   rules: {
      name: {
      required: true,
      ruleName: true
     }
  }
});
Adam
  • 25,960
  • 22
  • 158
  • 247