The ASP.NET Ajax Control Toolkit contains a control extender for making a set of ASP.NET CheckBoxes mutually exclusive [ See HERE ]. In this post I’ll demonstrate implementing Mutually Exclusive CheckBoxes with jQuery.

ASP.NET Checkboxes are, of course, server-side controls. If you’ve been following along with this series, or you using ASP.NET WebMatrix or MVC instead of WebForms, you may want to be leveraging HTML elements instead of server-side controls so my sample code will demonstrate doing this with both HTML input elements (checkboxes) as well as ASP.NET CheckBox controls.

This requires two slightly different methods because of the way ASP.NET emits markup for the ASP.NET CheckBox controls.

Here is a screen shot :


Lets look at the code and then we’ll examine the difference between the two sets of checkboxes.


<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" 
         AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
    <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function () {

            $('.mecheckbox').click(function () {
                checkState = $(this).attr('checked');
                $('.mecheckbox:checked').each(function () {
                    $(this).attr('checked', false);
                });
                $(this).attr('checked', checkState);
            });

            $("span.aspmecheckbox input:checkbox").click(function () {
                checkState = $(this).attr('checked');
                $('span.aspmecheckbox input:checkbox').each(function () {
                   $(this).attr('checked', false);
                 });
                 $(this).attr('checked', true);
            });

        });       
    </script> 
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>Welcome to ASP.NET!</h2>
    <p>
        To learn more about ASP.NET visit 
        <a href="http://www.asp.net" title="ASP.NET Website">www.asp.net</a>.
    </p>
    <p>
        You can also find 
        <a href="http://go.microsoft.com/fwlink/?LinkID=152368&clcid=0x409"
           title="MSDN ASP.NET Docs">documentation on ASP.NET at MSDN</a>.
    </p>

    <div>           
        <input id="chkRed" type="checkbox" value="red" class="mecheckbox" 
               runat="server">Red<br />           
        <input id="chkBlue" type="checkbox" value="blue" class="mecheckbox" 
               runat="server">Blue<br /> 
        <input id="chkGreen" type="checkbox" value="green" class="mecheckbox" 
               runat="server">Green<br /> 
        <br /><br /> 
        <asp:CheckBox ID="CheckBox1" runat="server" ClientIDMode="Inherit" 
                      CssClass="aspmecheckbox" />One<br />
        <asp:CheckBox ID="CheckBox2" runat="server" ClientIDMode="Inherit" 
                      CssClass="aspmecheckbox" />Two<br />
        <asp:CheckBox ID="CheckBox3" runat="server" ClientIDMode="Inherit" 
                      CssClass="aspmecheckbox" />Three<br />
        <asp:CheckBox ID="CheckBox4" runat="server" ClientIDMode="Inherit" 
                      CssClass="aspmecheckbox" />Four<br />
    </div> 
    <br />
    <asp:Button ID="ButtonSubmit" runat="server" Text="Submit" 
        onclick="ButtonSubmit_Click" />
    <br /><br />
    <asp:Label ID="LabelResult" runat="server" Text=""></asp:Label>
</asp:Content>


The first set of checkboxes is created with plain old HTML :


$('.mecheckbox').click(function () {
    checkState = $(this).attr('checked');
    $('.mecheckbox:checked').each(function () {
        $(this).attr('checked', false);
    });
    $(this).attr('checked', checkState);
});

Making the ASP.NET CheckBox is a bit more complicated.

First lets look at our .aspx mark-up :


    <div>           
        <input id="chkRed" type="checkbox" value="red" class="mecheckbox" 
               runat="server">Red<br />           
        <input id="chkBlue" type="checkbox" value="blue" class="mecheckbox" 
               runat="server">Blue<br /> 
        <input id="chkGreen" type="checkbox" value="green" class="mecheckbox" 
               runat="server">Green<br /> 
        <br /><br /> 
        <asp:CheckBox ID="CheckBox1" runat="server" ClientIDMode="Inherit" 
                      CssClass="aspmecheckbox" />One<br />
        <asp:CheckBox ID="CheckBox2" runat="server" ClientIDMode="Inherit" 
                      CssClass="aspmecheckbox" />Two<br />
        <asp:CheckBox ID="CheckBox3" runat="server" ClientIDMode="Inherit" 
                      CssClass="aspmecheckbox" />Three<br />
        <asp:CheckBox ID="CheckBox4" runat="server" ClientIDMode="Inherit" 
                      CssClass="aspmecheckbox" />Four<br />
    </div>

Note that we assign the class “aspmecheckbox” to each ASP.NET CheckBox in our set.

If we use the “View Source” feature in Internet Explorer and look at the html code that the ASP.NET CheckBoxes emit we can see the issue.

The emitted code isn’t formatted but I’ve formatted it in the snippet below for readability :


<span class="aspmecheckbox">
    <input id="MainContent_CheckBox1" type="checkbox" 
           name="ctl00$MainContent$CheckBox1" />
</span>
One <br />

<span class="aspmecheckbox">
   <input id="MainContent_CheckBox2" type="checkbox" 
          name="ctl00$MainContent$CheckBox2" />
</span>
Two<br />

<span class="aspmecheckbox">
   <input id="MainContent_CheckBox3" type="checkbox" 
          name="ctl00$MainContent$CheckBox3" /></span>
Three<br />

<span class="aspmecheckbox">
   <input id="MainContent_CheckBox4" type="checkbox" 
          name="ctl00$MainContent$CheckBox4" />
</span>
Four<br />
 

As you can see, each ASP.NET CheckBox control emits an HTML Input element of type checkbox wrapped in a SPAN tag and that SPAN is assigned our CSS class name “aspmecheckbox”.

That means that instead of just finding and hooking the html checkboxes of a certain class our jQuery code needs to find all the checkbox elements inside a SPAN with a specific class and hook the click event of those checkboxes and “unchecks” all the others when one checkbox is clicked..

That code looks like this :



$("span.aspmecheckbox input:checkbox").click(function () {
    checkState = $(this).attr('checked');
    $('span.aspmecheckbox input:checkbox').each(function () {
       $(this).attr('checked', false);
     });
     $(this).attr('checked', true);
});
            

You can download my working sample [ HERE ].