smitchelluk
smitchelluk

Reputation: 172

jQuery Validation of ASP.Net CheckBoxList

Before I start I'd just like to state that the code created by ASP.NET for CheckBoxLists is probably the worst thing I've ever seen.

Anyway,

I am using the jQuery validation plugin to validate my ASP.net form. There is a requirement to validate some checkboxes. These are generated by a CheckBoxList control.

<asp:CheckBoxList ID="CBContext" runat="server" RepeatColumns="2" 
              DataSourceID="sqlLibraryEnquiries" DataTextField="value" DataValueField="value" name="topic">
</asp:CheckBoxList>

This control produces the following abomination of xHTML

<table id="MainContent_CBContext" name="topic">
    <tr>
        <td>
          <input id="MainContent_CBContext_0" type="checkbox" name="ctl00$MainContent$CBContext$0" value="Business" /><label for="MainContent_CBContext_0">Business</label>
        </td>
        <td>
          <input id="MainContent_CBContext_2" type="checkbox" name="ctl00$MainContent$CBContext$2" value="Legal" /><label for="MainContent_CBContext_2">Legal</label>
        </td>
    </tr>
    <tr>
        <td>
           <input id="MainContent_CBContext_1" type="checkbox" name="ctl00$MainContent$CBContext$1" value="Business Development" /><label for="MainContent_CBContext_1">Business Development</label>
        </td>
        <td>
           <input id="MainContent_CBContext_3" type="checkbox" name="ctl00$MainContent$CBContext$3" value="Library" /><label for="MainContent_CBContext_3">Library</label>
        </td>
    </tr>
</table>

The issue I am having is actually getting the jQuery Validator plugin to hook into the checkbox list. In my rules section for all the other fields I can get to them with their names for example ctl00$MainContent$tbActions: but the checkboxes all have different names.

The cb_selectone rule isn't firing because the object I am trying to validate is never found. I have tried the following identifiers. CBContext, ctl00$MainContent$CBContext, MainContent_CBContext and checkboxes.

$("#Form1").validate({

     rules: {
     //WHAT GOES HERE???? --------->>    CBContext or ctl00$MainContent$CBContext or MainContent_CBContext or checkboxes all don't work: {
            cb_selectone: true
         }
      }
});

Thanks for your help.

SM

Upvotes: 4

Views: 10352

Answers (5)

soamazing
soamazing

Reputation: 1696

I made a small adjustment in the JAVASCRIPT method:

$.validator.addMethod('cb_selectone',
    function (value) {
        if ($('[id$=CBContext] input:checked').length > 0) {
            return true;
        }
        else
        {
            return false;
        }
    }, ""
);

Upvotes: 3

smitchelluk
smitchelluk

Reputation: 172

Ok I Solved it......

What I did was create a new validator method that gets all the objects of type input that match a regex of MainContent_CBContext. This returns an array of all the checkboxes.

Then loop round the array and check if the attr is checked. If any of them are then set the return as true.

$.validator.addMethod('cb_selectone', function (value, element) {
     if (debug) {
         $.jGrowl("Adding Validation");
     }
     var chkGroup = $("input[id^=MainContent_CBContext]");
     if (chkGroup.length > 0) {
         for (var i = 0; i < chkGroup.length; i++) {
             if ($(chkGroup[i]).attr('checked')) {
                 if (debug) {
                    // alert(i + $(chkGroup[i]).val());
                     $.jGrowl("Running loop " + i + " = " + $(chkGroup[i]).val());
                 }
                 return true;
             }
         }
         return false;
     }
     return false;
 }, 'Please select at least one option');

The part I was stuck on was finding an object to fire off the addMethod code. In the end I just used...

ctl00$MainContent$CBContext$2: {
   cb_selectone: true
}

This meant that the label is placed next to this field, it's purely cosmetic. The important thing is the validator code was finally bound to a real object and fired correctly.

SM

Upvotes: 1

ScottieB
ScottieB

Reputation: 4052

$("input:checked") 

is the selector that'll grab all checked checkboxes

I've used this for simple validation like:

function testChecks() {
    var n = $("input:checked").length;
    if (n > 6) {
        alert("Please select up to six attributes.");
        return false;
    }
    if (n < 1) {
        alert("You must select at least one attribute.");
        return false;
    }
    return true;
}

I imagine you could just do

$("input:checked").add("input:not(:checked)").Validate({
//....
});

Upvotes: 0

zgood
zgood

Reputation: 12621

Did you try something like this:

$("#Form1").validate({
     rules: {
        <%=CBContext.UniqueID %>: {
            cb_selectone: true
         }
      }
});

Upvotes: 0

Brian Mains
Brian Mains

Reputation: 50728

How the list renders makes it complex. I would consider creating your own validation method, and use the root control's ID, and have the validation method parse the inner children:

Upvotes: 0

Related Questions