Jquery-validation: Throttle keyup validation when using remote method

Created on 25 Jul 2012  路  9Comments  路  Source: jquery-validation/jquery-validation

remote function is activated each time we press a key in input fields.
So it sends an ajax request for each typed key, it's not very accuracy.
I propose a delay time before sending a remote request.

Most helpful comment

Since it is not supported yet in jquery-validation, I implemented a temporary solution for delaying remote() like this:

$.validator.methods._remote = $.validator.methods.remote;

var timer = 0;
$.validator.methods.remote = function () {
    clearTimeout(timer);

    var args = arguments;

    timer = setTimeout(function() {
        $.validator.methods._remote.apply(this, args);
    }.bind(this), 500);

    return "pending";
};

All 9 comments

467 was an attempt to fix this, but has too many issues. I'm not sure if using setTimeout like that is a good idea, probably not. I also wonder if there's other cases, besides the remote method where delaying (or throttling) validation is useful.

How about adding a couple of options to the repertoire of rules for each individual field?

validate: onkeyup | onblur | eager

delay: [time in ms]

Note that the validate: eager option would set that field to onblur until it is found to be invalid, at which point the field woud switch over to onkeyup validation in order to get rid of the error message ASAP. Once it has re-validated, it would switch back to onblur.

Obviously the delay option would be counterproductive for onblur fields, or fields where the validation happens client-side. It would really only come in useful when remote is used in combination with onkeyup. In fact, perhaps it should be an option under the remote option:

remote: {
    url: "http://example.com/",
    delay: 150
}

Configurable delay would be helpful. @jzaefferer did this ever go anywhere?

+1 Would love to have a delay.

I'd be happy to review PRs that address this. Otherwise this will have to wait some more, since there's too many other issues I still have to deal with.

Since it is not supported yet in jquery-validation, I implemented a temporary solution for delaying remote() like this:

$.validator.methods._remote = $.validator.methods.remote;

var timer = 0;
$.validator.methods.remote = function () {
    clearTimeout(timer);

    var args = arguments;

    timer = setTimeout(function() {
        $.validator.methods._remote.apply(this, args);
    }.bind(this), 500);

    return "pending";
};

I'm sorry for the lack of activity on this issue. Instead of leaving it open any longer, I decided to close old issues without trying to address them, to longer give the false impression that it will get addressed eventually.

To the reporter (or anyone else interested in this issue): If you're affected by the same issue, consider opening a new issue, with a testpage that shows the issue. Even better, try to fix the issue yourself, and improve the project by sending a pull request. This may seem daunting at first, but you'll likely learn some useful skills that you can apply elsewhere as well. And you can help keep this project alive. We've documented how to do these things, too. A patch is worth a thousand issues!

@sup3rman thanks for that solution, it seems really simple and shouldn't have any issues. Do you want to submit it as a PR?

@lohfu Thank you for your method. It works for basic usage, but it tends to create issues when tabbing in and out of the validated field (e.g. re-triggering the keyup event), when the throttled remote validation failed.

I've created a throttling "hook" before the validator is even called, in onkeyup:

var timer = 0;
onkeyup: function(element, event, force) {
    /*
        this throttles the keyup event for fields with the remote rule set
    */
    var excludedKeys = [
            16, 17, 18, 20, 35, 36, 37,
            38, 39, 40, 45, 144, 225
        ], rules = $(element).rules();

    clearTimeout(timer);

    if (rules.remote && typeof(force) === "undefined") {
        timer = setTimeout(function() {
            // reapply self
            $.validator.defaults.onkeyup.apply(this, [element, event, true]);
        }.bind(this), 200);
        return;
    }

    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 ) {
        this.element( element );
    }
}

This doesn't result in any weird behaviour.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Bek81 picture Bek81  路  3Comments

cdog picture cdog  路  8Comments

jasonday picture jasonday  路  5Comments

starchild picture starchild  路  3Comments

mapeveri picture mapeveri  路  4Comments