383

How do you create a simple, custom rule using the jQuery Validate plugin (using addMethod) that doesn't use a regex?

For example, what function would create a rule that validates only if at least one of a group of checkboxes is checked?

Maistrenko Vitalii
  • 994
  • 1
  • 8
  • 16
Edward
  • 4,331
  • 4
  • 20
  • 6
  • 44
    95 upvotes, I guess this mean http://bassistance.de/jquery-plugins/jquery-plugin-validation/ documentation might be unclear :P – Simon Arnold Dec 06 '12 at 22:03
  • Don't know if you are still searching (4 years later) but this could help http://learn.jquery.com/plugins/?rdfrom=http%3A%2F%2Fdocs.jquery.com%2Fmw%2Findex.php%3Ftitle%3DPlugins%2FAuthoring%26redirect%3Dno – Ron van der Heijden Jul 19 '13 at 08:11

8 Answers8

406

You can create a simple rule by doing something like this:

jQuery.validator.addMethod("greaterThanZero", function(value, element) {
    return this.optional(element) || (parseFloat(value) > 0);
}, "* Amount must be greater than zero");

And then applying this like so:

$('validatorElement').validate({
    rules : {
        amount : { greaterThanZero : true }
    }
});

Just change the contents of the 'addMethod' to validate your checkboxes.

Mark Spangler
  • 4,816
  • 2
  • 21
  • 23
105
$(document).ready(function(){
    var response;
    $.validator.addMethod(
        "uniqueUserName", 
        function(value, element) {
            $.ajax({
                type: "POST",
                url: "http://"+location.host+"/checkUser.php",
                data: "checkUsername="+value,
                dataType:"html",
                success: function(msg)
                {
                    //If username exists, set response to true
                    response = ( msg == 'true' ) ? true : false;
                }
             });
            return response;
        },
        "Username is Already Taken"
    );

    $("#regFormPart1").validate({
        username: {
            required: true,
            minlength: 8,
            uniqueUserName: true
        },
        messages: {
            username: {
                required: "Username is required",
                minlength: "Username must be at least 8 characters",
                uniqueUserName: "This Username is taken already"
            }
        }
    });
});
yesnik
  • 4,085
  • 2
  • 30
  • 25
Tracy
  • 1,107
  • 1
  • 7
  • 2
  • I tried this method and it works pretty good, however, men returning any other msg than true it still doesnt validate "ok" it is stuck in "Username is Already Taken", what can be wrong? i have also checked that it is returned properly by echoing values instead of returning false and true, and this works. seems to me that my browser is not picking up the return false , return true? this is making me crazy.. – Mikelangelo May 25 '10 at 15:33
  • 1
    got it to work by inserting a variable that is called result before the addmethod, seems the true, false values are registering properly within the success function – Mikelangelo May 27 '10 at 09:19
  • @Mikelangelo: Can you show us what you mean by "added a variable before the addMethod"? I'm lost on that line and I'm having the same issues that you did. Thanks in advance! – Loony2nz May 27 '10 at 21:38
  • @Mikelangelo i met same problem help me even true is returned jquery.validate shoes out an error – Mohan Ram Jun 09 '11 at 05:51
  • @Matthew: Why the hassle with the extra variable? What's wrong with just `return !(msg == "true");` or whatever the JavaScript equivalent of logical negation is? – sarnold Jan 22 '12 at 02:14
  • As could be found here: [http://stackoverflow.com/questions/2628413/jquery-validator-and-a-custom-rule-that-uses-ajax](http://stackoverflow.com/questions/2628413/jquery-validator-and-a-custom-rule-that-uses-ajax) An improvement to Tracy's answer, isSuccess variable is perhaps the 'result' variable Mikelangelo is talking about. –  Oct 22 '11 at 03:00
  • 25
    Be careful with this. This is not fully functional code in that the AJAX "success" is going to come back after 'return response;' runs, resulting in unexpected behaviors – Malachi Apr 21 '12 at 11:29
  • Agree with @Malachi, $.ajax is asynchronous and so `response` will be returned before the AJAX call comes back. – robbrit Jun 25 '12 at 18:02
  • 1
    @Malachi is correct. This can be fixed by doing a sync call instead but that's nasty. I wonder if there's some other way of achieving this? There is `remote` as others have suggested but as far as I can tell that only allows one validation, so it wouldn't work if you need to to two async validations or have several error messages depending on the response. – Adam Bergmark Mar 19 '13 at 17:57
  • 2
    there is a remote method for jquery validate: http://jqueryvalidation.org/remote-method/ – TecHunter Sep 22 '14 at 08:23
73
// add a method. calls one built-in method, too.
jQuery.validator.addMethod("optdate", function(value, element) {
        return jQuery.validator.methods['date'].call(
            this,value,element
        )||value==("0000/00/00");
    }, "Please enter a valid date."
);

// connect it to a css class
jQuery.validator.addClassRules({
    optdate : { optdate : true }    
});
commonpike
  • 10,499
  • 4
  • 65
  • 58
  • 8
    addClassRules is a nice addition to the answer. – Four May 10 '11 at 18:51
  • unclear documentation links: [Rules](https://jqueryvalidation.org/reference/#link-refactoring-rules) and [Error Messages](https://jqueryvalidation.org/reference/#link-error-messages) – mangupt Oct 04 '22 at 14:08
56

Custom Rule and data attribute

You are able to create a custom rule and attach it to an element using the data attribute using the syntax data-rule-rulename="true";

So to check if at least one of a group of checkboxes is checked:

data-rule-oneormorechecked

<input type="checkbox" name="colours[]" value="red" data-rule-oneormorechecked="true" />

addMethod

$.validator.addMethod("oneormorechecked", function(value, element) {
   return $('input[name="' + element.name + '"]:checked').length > 0;
}, "Atleast 1 must be selected");

And you can also override the message of a rule (ie: Atleast 1 must be selected) by using the syntax data-msg-rulename="my new message".

NOTE

If you use the data-rule-rulename method then you will need to make sure the rule name is all lowercase. This is because the jQuery validation function dataRules applies .toLowerCase() to compare and the HTML5 spec does not allow uppercase.

Working Example

$.validator.addMethod("oneormorechecked", function(value, element) {
  return $('input[name="' + element.name + '"]:checked').length > 0;
}, "Atleast 1 must be selected");

$('.validate').validate();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.14.0/jquery.validate.min.js"></script>

<form class="validate">
    red<input type="checkbox" name="colours[]" value="red" data-rule-oneormorechecked="true" data-msg-oneormorechecked="Check one or more!" /><br/>
    blue<input type="checkbox" name="colours[]" value="blue" /><br/>
    green<input type="checkbox" name="colours[]" value="green" /><br/>
    <input type="submit" value="submit"/>
</form>
BenG
  • 14,826
  • 5
  • 45
  • 60
  • 2
    only for jquery.validate ver >= 1.10 – Pavel Nazarov Nov 16 '17 at 08:42
  • 1
    I couldn't for the life of me find this in the official documentation, I wish they made this more clear. Thanks! – Josh Mc May 25 '20 at 00:18
  • unclear documentation links: [Rules](https://jqueryvalidation.org/reference/#link-refactoring-rules) and [Error Messages](https://jqueryvalidation.org/reference/#link-error-messages) – mangupt Oct 04 '22 at 14:08
22

Thanks, it worked!

Here's the final code:

$.validator.addMethod("greaterThanZero", function(value, element) {
    var the_list_array = $("#some_form .super_item:checked");
    return the_list_array.length > 0;
}, "* Please check at least one check box");
Ciarán Bruen
  • 5,221
  • 13
  • 59
  • 69
19

You can add a custom rule like this:

$.validator.addMethod(
    'booleanRequired',
    function (value, element, requiredValue) {
        return value === requiredValue;
    },
    'Please check your input.'
);

And add it as a rule like this:

PhoneToggle: {
    booleanRequired: 'on'
}        
Luca
  • 9,259
  • 5
  • 46
  • 59
Bogdan Mates
  • 520
  • 4
  • 8
2

For this case: user signup form, user must choose a username that is not taken.

This means we have to create a customized validation rule, which will send async http request with remote server.

  1. create a input element in your html:
<input name="user_name" type="text" >
  1. declare your form validation rules:
  $("form").validate({
    rules: {
      'user_name': {
        //  here jquery validate will start a GET request, to 
        //  /interface/users/is_username_valid?user_name=<input_value>
        //  the response should be "raw text", with content "true" or "false" only
        remote: '/interface/users/is_username_valid'
      },
    },
  1. the remote code should be like:
class Interface::UsersController < ActionController::Base
  def is_username_valid
    render :text => !User.exists?(:user_name => params[:user_name])
  end
end
Zoe
  • 27,060
  • 21
  • 118
  • 148
Siwei
  • 19,858
  • 7
  • 75
  • 95
-1

Step 1 Included the cdn like

     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

     <script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>

Step 2 Code Like

  $(document).ready(function(){
        $("#submit").click(function () {
              $('#myform').validate({ // initialize the plugin
                rules: {
                    id: {
                        required: true,
                        email: true
                    },
                    password: {
                        required: true,
                        minlength: 1
                    }
                },
                messages: {
                    id: {
                        required: "Enter Email Id"

                    },
                    password: {
                        required: "Enter Email Password"

                    }
                },
                submitHandler: function (form) { // for demo
                    alert('valid form submitted'); // for demo
                    return false; // for demo
                }
            });
       }):
  }); 
Devang Hire
  • 174
  • 1
  • 5