HugeBob
HugeBob

Reputation: 467

Validating Checkbox States With jQuery Validator

I'm using the jQuery form validator plugin. The form has 5 check boxes. The first of which (master), if checked, checks the remaining 4 and makes them unalterable by the user. If master is unchecked, the remaining 4 boxes go back to being togglable by the user. This functionality works fine. Now, what I want to do is, if all of the check boxes are unchecked, invalidate the form. I also want one specific area (checkBoxErrorHolder) to house the validation error message for the check boxes only. The other error messages should appear in their default positions by their inputs. Here's what I have so far:

<script language="javascript">
$(function() {
    $.validator.addMethod("validateCheckBoxes",
                          function (value, element, params)   {

                              var master=false, 
                                  slave1=false, 
                                  slave2=false,
                                  slave3=false,
                                  slave4=false;

                              if ($("#master").attr("checked"))
                                  master = true;
                              if ($("#slave1").attr("checked"))
                                  slave1 = true;
                              if ($("#slave2").attr("checked"))
                                  slave2 = true;
                              if ($("#slave3").attr("checked"))
                                  slave3 = true;
                              if ($("#slave4").attr("checked"))
                                  slave4 = true;

                              return (master || (slave1&&slave2&&slave3&&slave4));
                          }, 
                          "One or more check boxes must be checked");

    $("#theForm").validate({
        rules: { 
                   first: required,
                   last:  required,
                   email: {required: true, email: true},
                   master: { required: true, 
                             validateCheckBoxes: true},
                             errorPlacement: function(error, element) {
                                                 $("#checkBoxErrorHolder").html(error);
                                             }
                           }
                   slave1: { required: true, 
                             validateCheckBoxes: true},
                             errorPlacement: function(error, element) {
                                                 $("#checkBoxErrorHolder").html(error);
                                             }
                           }
                   slave2: { required: true,
                             validateCheckBoxes: true},
                             errorPlacement: function(error, element) {
                                                 $("#checkBoxErrorHolder").html(error);
                                             }
                           }
                   slave3: { required: true, 
                             validateCheckBoxes: true},
                             errorPlacement: function(error, element) {
                                                 $("#checkBoxErrorHolder").html(error);
                                             }
                           }
                   slave4: { required: true, 
                             validateCheckBoxes: true,
                             errorPlacement: function(error, element) {
                                                 $("#checkBoxErrorHolder").html(error);
                                             }
                           }
               },
        messages: {
            first: "required",
            last: "required",
            email: {
                       required: "Email address required",
                       email: "Please supply a valid email address"
                   }
        }
    });
});
</script>

<form id="theForm" ...>
<input type="text" name="first" value="" />
<input type="text" name="last" value="" />
<input type="text" name="email" value="" />
<input type="checkbox" id="master" value="master" class="validateCheckBoxes"/>
<input type="checkbox" id="slave1" value="slave1" class="validateCheckBoxes"/>
<input type="checkbox" id="slave2" value="slave2" class="validateCheckBoxes"/>
<input type="checkbox" id="slave3" value="slave3" class="validateCheckBoxes"/>
<input type="checkbox" id="slave4" value="slave4" class="validateCheckBoxes"/>
<input type="submit" />
</form>
<div id="checkBoxErrorHolder"></div>

Needless to say, I'm not getting the results I expected.

Upvotes: 1

Views: 2036

Answers (2)

Sparky
Sparky

Reputation: 98738

Your code:

rules: { 
               first: required,
               last:  required,
               email: {required: true, email: true},
               master: { required: true, 
                         validateCheckBoxes: true},
                         errorPlacement: function(error, element) {
                                             $("#checkBoxErrorHolder").html(error);
                                         }
                       } // <-- missing comma
               slave1: { required: true, 
                         validateCheckBoxes: true},
                         errorPlacement: function(error, element) {
                                             $("#checkBoxErrorHolder").html(error);
                                         }
                       } // <-- missing comma

Basically, you broke the plugin through a variety of syntax and formatting errors...


1) errorPlacement is not a rule that you apply along with the other rules. It's a callback function that you apply once along with the other options...

$(document).ready(function () {

    $("#theForm").validate({
        rules: {
            // your rules
        },
        messages: {
            // your messages
        },
        errorPlacement: function (error, element) {
            $("#checkBoxErrorHolder ").html(error);
        },
        // other options and callback functions,
    });

});

2) Your checkbox elements are missing a name attribute. Every input, select, radio, checkbox, etc., except for the submit button, must have a name attribute in order for this plugin to function properly.


3) Whenever you use the shorthand for a rule like required, it must be in quotes. Here's an example showing both ways correctly...

rules: {
    first: "required",
    last: {
        required: true
    },
},

4) I started constructing a jsFiddle for this but I stopped because there are way too many syntax errors than I care to fix. Please run your JavaScript through jsFiddle's jsHint function to see them all. I got your basic validation working so now you can troubleshoot your custom validateCheckBoxes method.

Here's a working jsFiddle Demo of your basic form: http://jsfiddle.net/gHKyb/


5) EDIT: I took another look at your custom validateCheckBoxes method and cleaned up the last of the syntax errors. But it still wasn't working because you accidentally defined a required rule on every checkbox, which simply means that the checkbox is always required despite anything else.

I removed the required rule from all checkboxes and everything seems to work now as per your spec. I also condensed your code. (either the first box must be checked OR the last four must be checked)

$.validator.addMethod("validateCheckBoxes", function (value, element, params) {
    var master,
        slave = [];
    if ($("#master").attr("checked")) {
        master = true;
    }
    $("[id^='slave']").each(function(i) {
        if ($(this).attr("checked")) {
            slave[i+1] = true;
        }
    });
    return (master || (slave[1] && slave[2] && slave[3] && slave[4]));
}, "One or more check boxes must be checked");

6) And finally, to fix the placement of your error labels, I simply modified the errorPlacement callback function as follows:

errorPlacement: function (error, element) {
    if ($(element).attr("type") === "checkbox") {
        $("#checkBoxErrorHolder").html(error); // just for checkboxes
    } else {
        error.insertAfter(element); // default placement
    }
},
success: function() { // need "success" to dynamically clear any checkbox errors
    $("#checkBoxErrorHolder").html();
},

Working DEMO: http://jsfiddle.net/AKgmH/

Upvotes: 2

pistou
pistou

Reputation: 2867

Seems like a " is missing after each 'checked'

if ($("#master").attr("checked"))
  master = true;
if ($("#slave1").attr("checked"))
  slave1 = true;
if ($("#slave2").attr("checked"))
  slave2 = true;
if ($("#slave3").attr("checked"))
  slave3 = true;
if ($("#slave4").attr("checked"))
  slave4 = true;

I don't know if it will resolve your problem, but it can help :)

Upvotes: 0

Related Questions