'Specifiy the order of the validators in jQuery validate plugin

I'm wondering if it's possible to specify the order in which the validators are run.

Currently I wrote a custom validator that check if it's [a-zA-Z0-9]+ to make sure the login validates our rules and a remote validator to make sure that the login is available but currently the remote validator is lauched before my custom validator. I would like to launch the remote validator only if the element validates my custom validator.

Any clue ?

thanks for reading



Solution 1:[1]

As far as I understand, the rules for a given element are processed in the order they appear. And since version 1.12, "required" rule is always processed first, and "remote" last.

Solution 2:[2]

it's been a while since last message, but it could be useful for someone...

if you want to set more rules on the same tag, for example

<input data-rule-regex="(\w\d)+" data-rule-rangewords="[2,5]" data-rule-minlength="10" >

when you test your rule the order is not the same order as they are inserted, so in this case it's a problem because if you insert the following string

abcdefghi

jquery validator prints these messages

1) first error message related to minlength 2) second error message related to rangewords 3) third error message related to regex expression

but it is wrong because if I have already inserted the string

abcdefghi

and the message appeared has been the error message for minlength, and now I insert another character

abcdefghil --> length 10

at this point I have to clean the string because the second error message tells me that I have to insert at least two words or more... between [2,5] exactly

and the same thing for regular expression after inserting two or more words that it will appear the third error message about regex, and also in this case I have to clean my string ect...

this behavior is due to the list of methods inside jquery.validate.js

because the plugin take that order...

so, my solution is this:

put for each rule that you want to insert on a tag this attribute

data-rule-(method you want)-order

and initialize it with an index from zero...

for example in our case we have three rules

<input 
data-rule-regex="(\w\d)+" data-rule-regex-order="0" 
data-rule-rangewords="[2,5]" data-rule-rangewords-order="1"
data-rule-minlength="10" data-rule-minlength-order="2"
ofcourse you need also the messages (if you want)
data-msg-regex="..." etc...
>

at this point, if you don't want to override the library (jquery.validate.js) you can create a custom.js file and insert the following code:


$(document).ready(function() {
    (function($){
        $.validator.dataRules = function(element) {
            rules = {},
            $element = $( element ),
            type = element.getAttribute( "type" ),
            method, value, orderIndex, orderArr = {};

            for ( method in $.validator.methods ) {
                value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() +method.substring( 1 ).toLowerCase() );
                orderIndex = $element.data( "rule" + method.charAt( 0 ).toUpperCase() +method.substring( 1 ).toLowerCase() + "Order" );

                if(typeof orderIndex !== "undefined") orderArr[orderIndex] = {"rules":rules,"type":type, "method":method, "value":value};
            }       

            for ( var ord in orderArr ) this.normalizeAttributeRule( orderArr[ord].rules,orderArr[ord].type, orderArr[ord].method, orderArr[ord].value );

            return rules;

        }
    })(jQuery);             
});

I hope it will be useful for you

m.

Solution 3:[3]

I'm going to clean up @matty's soilution here. I'd comment there, but strange decision on reputation to do so??? ¯\(?)

matty's solution returns 'rules' but never writes to it. And as well, you'll need something like [email protected]+ for the 'normalizeAttributeRule' routine.

$(document).ready(function () {
    (function ($) {
        $.validator.dataRules = function (element) {
            var rules = {};
            var $element = $(element);
            var type = element.getAttribute("type");
            var method;
            var value;
            var orderIndex;
            var orderArr = {};

            for (method in $.validator.methods) {
                value = $element.data("rule" + method.charAt(0).toUpperCase() + method.substring(1).toLowerCase());
                orderIndex = $element.data("rule" + method.charAt(0).toUpperCase() + method.substring(1).toLowerCase() + "Order");

                if (typeof orderIndex !== "undefined") orderArr[orderIndex] = { "rules": rules, "type": type, "method": method, "value": value };
            }

            for (var ord in orderArr) {
                this.normalizeAttributeRule(orderArr[ord].rules, orderArr[ord].type, orderArr[ord].method, orderArr[ord].value);
                rules[orderArr[ord].method] = orderArr[ord];
            }

            return rules;
        }
    })(jQuery);
});

Seems to work for me after some adjustments.

Solution 4:[4]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 JotaDeAA
Solution 2
Solution 3
Solution 4 Scherbius.com