Creating Checkboxes that Behave Like Radio Buttons with jQuery

Some time ago I received a question on the Wrox P2P forum about checkboxes that should behave like radio buttons. The poster of the question was looking for a (client side) solution to have multiple checkboxes per row in a GridView with multiple rows. A user should only be able to check off at most one of the checkboxes in each row. My first thought was to use radio buttons instead, but then I realized that with radio buttons you lose the ability to uncheck all options. Once you've selected a radio button in a group of radio buttons, there's no way for an end user to uncheck it again.

Fortunately, with a bit of jQuery, this is really simple to accomplish with checkboxes as I'll show you in this short article.

First, take a look at the demo page to see the final behavior. As you can see, you can only check one checkbox per row. As soon as you check the other checkbox, the first one gets deselected. You can also uncheck the selected checkbox again, something that wouldn't be possible if you'd use a radio button instead.

To see how this works, take a look at the code. First, the page contains a standard HTML table with rows and cells. Each cell contains a checkbox:

<table border="0" cellpadding="0" cellspacing="0" id="myTable">
<tr>
  <td>
    <input type="checkbox" />
  </td>
  <td>
    <input type="checkbox" />
  </td>
</tr>
<tr>
  <td>
    <input type="checkbox" />
  </td>
  <td>
    <input type="checkbox" />
  </td>
</tr>
... More rows here
</table>

While this is just a plain and clean HTML table, you could accomplish the same with an ASP.NET GridView as in the end it renders rows and cells similar to this.

To make the selection feature work, I used jQuery. At the top of the demo page you find a link to the jQuery library on the Google CDN. Right below that, you find the following code:

<script type="text/javascript">
  $(document).ready(function ()
  {
    $("#myTable input[type=checkbox]").click(function ()
    {
      if (this.checked)
      {
        $(this).closest('tr').find('input[type=checkbox]').attr('checked', false);
        this.checked = true;
      }
    });
  }); 
</script>

This code uses jQuery's document ready to hook up some code that fires when the page is done loading. The code then sets up a click handler for all checkboxes (in all rows) that it finds in the table with an id of myTable. The function that gets executed when you click one of the checkboxes first checks if the checkbox that got clicked (referred to with the this parameter) has just been checked by the user. If it hasn't, no code should be run as you should be able to uncheck the current item.

But if the item did get clicked, the code first unchecks all checkboxes in the current row. It does that with this code:

$(this).closest('tr').find('input[type=checkbox]').attr('checked', false);

In this code, $(this) converts the current checkbox to a jQuery matched set (with a single element in it) so you can execute further jQuery code. The closest method then walks up the DOM tree looking for the nearest <tr> element. This finds the parent table row of the current checkbox. The find method then walks down the Dom tree again, finding all checkboxes (including the one that you clicked). The checkboxes are then unchecked using the attr method by setting their checked attribute to false (e.g. unchecked). Finally, the current item gets checked again by setting its checked property again (you could also have used the attr method but since I already had a reference to the checkbox in the this parameter, using this.checked felt like the quickest way to do it.

And there you have it: checkboxes that behave somewhat like radio buttons, with only a few lines of code, all made possible by the power that the jQuery library gives you.


Where to Next?

Wonder where to go next? You can read existing comments below or you can post a comment yourself on this article .


Consider making a donation
Please consider making a donation using PayPal. Your donation helps me to pay the bills so I can keep running Imar.Spaanjaars.Com, providing fresh content as often as possible.



Feedback by Other Visitors of Imar.Spaanjaars.Com

On Friday, December 02, 2011 9:13:32 PM Omar said:
Thanks Imar. Nice. Just what I was looking for. However, when tha table is sortable, like the one you can get with http://www.tablefixedheader.com/, the functionality is lost after the table is sorted.

Do you have some idea of what is going wrong here?

Looking forward,

Omar

PS: 2+9 = 11 wasn't working in a previous attempt. I send it through your contact page and I'm repeating this out of curiosity.
On Sunday, December 04, 2011 3:37:50 AM Imar Spaanjaars said:
Hi Omar,

Not sure why it doesn't work. My guess is that the table sorter recreates the underlying HTML so the jQuery attached behavior gets lost. You may be able to execute that code again after the table has been sorted.

And the calculation issue is a small bug. When you open multiple pages on my site in different tabs, each new page changes the calculation server side, but not client side. Therefore, you're looking at old data when you try to sumit it. Will need to fx it one day...

Imar
On Tuesday, September 04, 2012 7:45:11 AM ameer said:
Hi, this is really what i needed thanks alot for sharing this info...just needed to ask you one more thing the checkboxes are in horizontal position i want to position them vertically but i get the problem with the next tr. i in the same tr there is no problem...any suggestions
On Wednesday, September 05, 2012 7:32:05 AM ameer said:
hi, i tried to modify your code by using CheckBoxList instead of the checkboxes but it isnt working.....
On Wednesday, September 05, 2012 7:36:08 AM Imar Spaanjaars said:
Hi ameer,

You need to look at the underlying structure; the CheckBoxList renders other HTML than you might expect.

Cheers,

Imar

Talk Back! Comment on Imar.Spaanjaars.Com

I am interested in what you have to say about this article. Feel free to post any comments, remarks or questions you may have about this article. The Talk Back feature is not meant for technical questions that are not directly related to this article. So, a post like "Hey, can you tell me how I can upload files to a MySQL database in PHP?" is likely to be removed. Also spam and unrealistic job offers will be deleted immediately.

When you post a comment, you have to provide your name and the comment. Your e-mail address is optional and you only need to provide it if you want me to contact you. It will not be displayed along with your comment. I got sick and tired of the comment spam I was receiving, so I have protected this page with a simple calculation exercise. This means that if you want to leave a comment, you'll need to complete the calculation before you hit the Post Comment button.

If you want to object to a comment made by another visitor, be sure to contact me and I'll look into it ASAP. Don't forget to mention the page link, or the QuickDocId of the document.

For more information about the Talk Back feature, check out this news item.