Wednesday, 15 June 2011

How to validate a group of ASP.NET Check Boxes in Jquery

By default, ASP.NET will render a CheckBox or a CheckBoxList with an auto generated unique name attribute. This becomes a problem when you want to validate the group, since you can’t set a common name attribute for all the elements.
Here is an example of the HTML that would be rendered by a CheckBoxList with a layout of “Flow”.
----------------------------------------------------------------------------------
<span id="CheckBoxGroup">
  <input id="cbk1" name="cbk1" type="checkbox">Check Box 1</input>
  <input id="cbk2" name="cbk2" type="checkbox">Check Box 2</input>
  <input id="cbk3" name="cbk3" type="checkbox">Check Box 3</input>
</span>
<span class="jQueryValError"></span> ---------------------------------------------------------------------------------

My solution to the problem required a custom validator and a custom error Placement function, for the jQuery validaiton plug-in.
First, I added a custom validator that looked at a group of check boxes that are inside a wrapping “Parent()” element. I then count the number of checked check boxes to make sure the limit required (e.g. Must check at least 3 check boxes) is greater than the minimum we set.
----------------------------------------------------------------------
jQuery.validator.addMethod("minChecked",
 function(value, element, param) {
    var $p = $(element).parent();
    var selected = $p.children('input[type=checkbox]:checked').length;
    if (selected >= param) {
        $p.children().removeClass('error');
        $p.siblings('.error').remove();
        return true;
        }
    $p.children('input[type=checkbox]').addClass('error');
 
-------------------------------------------------------------------------------------


In order to hookup this custom event to all the controls inside of a wrapping “Parent()” control, we use jQuery’s $().each function to call the validator’s rules() function.

----------------------------------------------------------------------------------
$(".checkBoxGroup").children('input[type=checkbox]').each(function(){ $(this).rules("add", { minChecked: 3}); });
----------------------------------------------------------------------------------
Second, our plug-in will by default put an error message next to the control(s) that triggered the error. I over ride the default behavior, we setup a “errorPlacement” function to put one error beside the wrapping “Parent()” control.
---------------------------------------------------------------------------------
$("#<%= form1.ClientID %>").validate({
    errorPlacement: function(error, element){
        if(element.rules().minChecked > 0) {
            var $p = $(element).parent();
            if($p.siblings().hasClass("error") == false) {
                error.insertAfter($p);
            }
        }
        else {
            error.insertAfter(element);
        }
    }
});
--------------------------------------------------------------------------------
Here is what the form looks like when you have a error with your check boxes.
jQuery Validation of ASP.NET CheckBoxes
Here is source code used to create the example above.
----------------------------------------------------------------------------------
<head runat="server">
    <title>Contact Form Demo</title>
    <script src="styles/jQuery.js" type="text/javascript"></script>
    <script src="styles/jQuery.Validate.js" type="text/javascript"></script>
    <script src="styles/jQuery.Validate.AddOns.js" type="text/javascript"></script>
    <script type="text/javascript">
    jQuery.validator.addMethod("minChecked",
     function(value, element, param) {
        var $p = $(element).parent();
        var selected = $p.children('input[type=checkbox]:checked').length;
        if (selected >= param) {
            $p.children().removeClass('error');
            $p.siblings('.error').remove();
            return true;
            }
        $p.children('input[type=checkbox]').addClass('error');
        return false;}, jQuery.validator.format("Please check at least {0} items."));
        $(document).ready(function(){
            $("#<%= form1.ClientID %>").validate({
                rules: {
                    <%= FirstName.UniqueID %>: { required: true },
                    <%= LastName.UniqueID %>: { required: true },
                    <%= Email.UniqueID %>: { required: true, email: true },
                    <%= Phone.UniqueID %>: { required: true, phoneUS: true }
                },
                errorPlacement: function(error, element){
                    if(element.rules().minChecked > 0) {
                        var $p = $(element).parent();
                        if($p.siblings().hasClass("error") == false) {
                            error.insertAfter($p);
                        }
                    }
                    else {
                        error.insertAfter(element);
                    }
                }
            });
            $(".checkBoxGroup").children('input[type=checkbox]').each(function(){ $(this).rules("add", { minChecked: 3}); });
            $(".myGroupRandom").children('input[type=checkbox]').each(function(){ $(this).rules("add", { minChecked: 1}); });
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <fieldset>
            <ol>
                <li>
                    <label class="left">
                        First Name
                    </label>
                    <input type="text" id="FirstName" runat="server" /></li>
                <li>
                    <label class="left">
                        Last Name
                    </label>
                    <input type="text" id="LastName" runat="server" /></li>
                <li>
                    <label class="left">
                        Email
                    </label>
                    <input type="text" id="Email" runat="server" /></li>
                <li>
                    <label class="left">
                        Phone
                    </label>
                    <input type="text" id="Phone" runat="server" /></li>
                <li>
                    <label class="left">
                        Contact Method
                    </label>
                    <span class="checkBoxGroup">
                        <input type="checkbox" id="ReqEmail" runat="server" /><label>Email</label>
                        <input type="checkbox" id="ReqMail" runat="server" /><label>Mail</label>
                        <input type="checkbox" id="ReqPhone" runat="server" /><label>Phone</label>
                        <input type="checkbox" id="ReqNoContact" runat="server" /><label>No Contact</label>
                    </span></li>
                <li>
                    <label class="left">
                        New Letter Type
                    </label>
                    <span class="myGroupRandom" >
                        <input type="checkbox" id="Checkbox1" runat="server" /><label>Company News</label>
                        <input type="checkbox" id="Checkbox2" runat="server" /><label>Press Releases</label>
                        <input type="checkbox" id="Checkbox3" runat="server" /><label>Deals</label>
                        <input type="checkbox" id="Checkbox4" runat="server" /><label>Employement</label>
                    </span></li>
                <li>
                    <input type="submit" id="Submit" value="Submit" /></li>
            </ol>
        </fieldset>
    </div>
    </form>
</body>
</html>


 ------------------------------------------------------------------------------------

No comments:

Post a Comment