views:

27094

answers:

10

I am new to JQuery and am using the JQuery validation plugin. Great stuff! I want to migrate my existing ASP.NET solution to use JQuery instead of the ASP.NET validators. I am missing a replacement for the regular expression validator. I want to be able to do something like this:

$("Textbox").rules("add", { regularExpression: "^[a-zA-Z'.\s]{1,40}$" })

Could anyone give me a hint how to add a custom rule to achieve this?

+12  A: 

You can use the addMethod()

e.g

$.validator.addMethod('postalCode', function (value) { 
    return /^((\d{5}-\d{4})|(\d{5})|([A-Z]\d[A-Z]\s\d[A-Z]\d))$/.test(value); 
}, 'Please enter a valid US or Canadian postal code.');

good article here http://dev.distilldesign.com/log/2008/mar/16/extending-jquery-form-validation-plugin/

redsquare
Don't really answer the question. What if you want a general regex rule?With this answer you would have to addMethod for each diffrent regex.
AndreasN
if you have a better answer feel free....
redsquare
"good article here" site is dead
Pat James
can I help that.....
redsquare
+42  A: 

Thanks to the answer of redsquare I added a method like this:

$.validator.addMethod(
        "regex",
        function(value, element, regexp) {
            var check = false;
            var re = new RegExp(regexp);
            return this.optional(element) || re.test(value);
        },
        "Please check your input."
);

now all you need to do to validate against any regex is this:

$("Textbox").rules("add", { regex: "^[a-zA-Z'.\s]{1,40}$" })
PeterTheNiceGuy
What is the point of the unused variable assignment "var check = false;"? "check" is not checked anywhere, pun intended.
JK
$("Textbox") should be $("#Textbox").
Ryan Shripat
Works for me, thanks: +1
JK
I would have let the RegExp be defined outside the method as a literal, instead of the invocation from a string..
Tracker1
+5  A: 

Extending PeterTheNiceGuy's answer a bit:

$.validator.addMethod(
        "regex",
        function(value, element, regexp) {
            if (regexp.constructor != RegExp)
                regexp = new RegExp(regexp);
            else if (regexp.global)
                regexp.lastIndex = 0;
            return this.optional(element) || regexp.test(value);
        },
        "Please check your input."
);

This would allow you to pass a regex object to the rule.

$("Textbox").rules("add", { regex: /^[a-zA-Z'.\s]{1,40}$/ });

Resetting the lastIndex property is necessary when the g-flag is set on the RegExp object. Otherwise it would start validating from the position of the last match with that regex, even if the subject string is different.

Some other ideas I had was be to enable you use arrays of regex's, and another rule for the negation of regex's:

$("password").rules("add", {
    regex: [
        /^[a-zA-Z'.\s]{8,40}$/,
        /^.*[a-z].*$/,
        /^.*[A-Z].*$/,
        /^.*[0-9].*$/
    ],
    '!regex': /penis|password|123/
});

But implementing those would maybe be too much.

MizardX
+9  A: 

As mentioned on the addMethod documentation:

Please note: While the temptation is great to add a regex method that checks it's parameter against the value, it is much cleaner to encapsulate those regular expressions inside their own method. If you need lots of slightly different expressions, try to extract a common parameter. A library of regular expressions: http://regexlib.com/DisplayPatterns.aspx

So yes, you have to add a method for each regular expression. The overhead is minimal, while it allows you to give the regex a name (not to be underestimated), a default message (handy) and the ability to reuse it a various places, without duplicating the regex itself over and over.

Jörn Zaefferer
Your answer is much apreciated! Thanks. I will think about it again. In our case the Regex validation seemed to be the best fit. However I understand your point in using "named" validations...
PeterTheNiceGuy
+3  A: 

Please say you're checking the input server side and not just relying on client side validation as this can obviously be turned off.

Si Philp
of course! :-) Validation on the server is a must
PeterTheNiceGuy
A: 

Hi all,

Apologies for my ignorange but how would something like your example:

$("Textbox").rules("add", { regex: /^[a-zA-Z'.\s]{1,40}$/ });

Fit in to a normal jquery validate configuration, for example:

$("#adForm").validate({
  rules: {
    advertWidth: {
      required: true,
  number: true,
      range: [1, 1600]
    },
    advertHeight: {
      required: true,
  number: true,
      range: [1, 1600]
    }
  }

Thanks!

Boba

+7  A: 

I had some trouble putting together all the pieces for doing a jquery regular expression validator... but got it to work.. here is a complete working example. It uses the 'Validation' plugin which can be found here: http://bassistance.de/jquery-plugins/jquery-plugin-validation/

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="http://YOURJQUERYPATH/js/jquery.js" type="text/javascript"></script>
<script src="http://YOURJQUERYPATH/js/jquery.validate.js" type="text/javascript"></script>
<script type="text/javascript">

    $().ready(function() {

    $.validator.addMethod("EMAIL", function(value, element) {  
    return this.optional(element) || /^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,5}$/i.test(value);  
    }, "Email Address is invalid: Please enter a valid email address.");

    $.validator.addMethod("PASSWORD",function(value,element){
    return this.optional(element) || /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,16}$/i.test(value);
    },"Passwords are 8-16 characters with uppercase letters, lowercase letters and at least one number.");

    $.validator.addMethod("SUBMIT",function(value,element){
    return this.optional(element) || /[^ ]/i.test(value);
    },"You did not click the submit button.");

     // validate signup form on keyup and submit
     $("#LOGIN").validate({
      rules: {
       EMAIL: "required EMAIL",
       PASSWORD: "required PASSWORD",
       SUBMIT: "required SUBMIT",
      },

     });

    });

</script>
</head>
<body>
<div id="LOGIN_FORM" class="form">
  <form id="LOGIN" name="LOGIN" method="post" action="/index/secure/authentication?action=login">
    <h1>Log In</h1>
    <div id="LOGIN_EMAIL">
      <label for="EMAIL">Email Address</label>
      <input id="EMAIL" name="EMAIL" type="text" value="" tabindex="1" />
    </div>
    <div id="LOGIN_PASSWORD">
      <label for="PASSWORD">Password</label>
      <input id="PASSWORD" name="PASSWORD" type="password" value="" tabindex="2" />
    </div>
    <div id="LOGIN_SUBMIT">
      <input id="SUBMIT" name="SUBMIT" type="submit" value="Submit" tabindex="3" />
    </div>
  </form>
</div>
</body>
</html>
Thank you, using your complete working example allowed me to implement this. The other answers failed to work for me.
Pat James
+3  A: 

No reason to define the regex as a string.

$.validator.addMethod(
    "regex",
    function(value, element, regexp) {
        var check = false;
        return this.optional(element) || regexp.test(value);
    },
    "Please check your input."
);

and

telephone: { required: true, regex : /^[\d\s]+$/, minlength: 5 },

tis better this way, no?

Sam
A: 

$("#adForm").validate({ rules: { advertWidth: { required: true, number: true, range: [1, 1600], add: { regex: /^[a-zA-Z'.\s]{1,40}$/ } }, advertHeight: { required: true, number: true, range: [1, 1600] } }

Daniel
A: 

Sorry Sam

but your answer does not work. :-(

This is my peace of code: '

$.validator.addMethod(
       "regex",
        function(value, element, regexp) {
        var check = false;
        return this.optional(element) || regexp.test(value);
        },
        "Please check your input."
        );


           $(
function () {
            $('#uiEmailAdress').focus();
            $('#NewsletterForm').validate({
rules: {
    uiEmailAdress:{
        required: true,
        email: true,
        minlength: 5
    },
    uiConfirmEmailAdress:{
        required: true,
        email: true,
        equalTo: '#uiEmailAdress'
    },
    DDLanguage:{
        required: true
    },
    Testveld:{
        required: true,
        regex: ^[0-9]{3}$
    }
},
messages: {
    uiEmailAdress:{
        required: 'Verplicht veld',
        email: 'Ongeldig emailadres',
        minlength: 'Minimum 5 charaters vereist'
    },
    uiConfirmEmailAdress:{
        required: 'Verplicht veld',
        email: 'Ongeldig emailadres',
        equalTo: 'Veld is niet gelijk aan E-mailadres'
    },
    DDLanguage:{
        required: 'Verplicht veld'
    },
    Testveld:{
        required: 'Verplicht veld',
        regex: '_REGEX'
    }
  }
 });
            }
     );
    </script>

` Now when i do the validation i get no validation @ all.

When is put the regex between ' ' then i get an exception that the validation of regex object --> Object doesn't support this property or method with rule method regex.

Can you tell me what is wrong ...

Thanx

Le Moustique