i Know Kung Foo Consulting

Check All Checkboxes with JQuery

I've been working with JQuery quite a bit lately and I'm aggravated that I didn't pick it up sooner. Someone on the DFW CFUG mailing list asked for a quick example of why they should use it. Another post on the JQuery list asked how to create a "Check All" box using JQuery. I decided to expand on the "check all" example I posted to the CFUG list to show how things have progressed from old school Javascript to JQuery.

Working Examples

So here's a basic form with 2 series of checkboxes.

myCB yourCB
A
B
C
D
E
F
G
H
I
J
K
L

1.

2.

3. Check All checkboxes with JQuery Automatically

4a. Check All named "myCB" with JQuery onclick.

4b. Check All named "yourCB" with JQuery onclick.

5a. JQuery Check All Left Column

5b. JQuery Uncheck All Right Column

Break It Down: Old School to JQuery

Each column in the form has a group of checkboxes of the same name. When you have multiple form elements of the same name, they represent an Array in the Document Object Model (DOM).

<form id="myForm" name="myForm" action="" method="post">
   <table border="1">
      <tr>
         <td>myCB</td>
         <td>yourCB</td>
      </tr>
      <tr>
         <td>
            <input type="checkbox" name="myCB" value="A" /> A<br />
            <!-- etc. -->
         </td>
         <td>
            <input type="checkbox" name="yourCB" value="G" /> G<br />
            <!-- etc. -->
         </td>
      </tr>
   </table>

1. Old School

The first set of buttons will check and uncheck all checkboxes named myCB.

<input type="button" name="ca_v1_on" value="Check All myCB" onclick="checkAll(1);"/>
<input type="button" name="ca_v1_off" value="Uncheck All myCB" onclick="checkAll(0);"/>

These buttons call the Javascript function checkAll() when you click them. This function determines if there is more than one form element named myCB. If so, then it loops through those elements, setting their checked attribute to true or false based on the value of flag. If there's only one, then it sets that one element's checked attribute to true or false based on the value of flag.

checkAll() - Old School Javascript
function checkAll(flag)
{
   if ( document.myForm.myCB.length )
   {
      for (var x = 0; x < document.myForm.myCB.length; x++)
      {
         if (flag == 1)
         {
            document.myForm.myCB[x].checked = true;   
         }
         else
         {
            document.myForm.myCB[x].checked = false;
         }
         
      }
   }
   else
   {
      if (flag == 1)
      {
         document.myForm.myCB.checked = true;            
      }
      else
      {
         document.myForm.myCB.checked = false;
      }
   }
}

That's a boat load of code. We could remove some of the hard coded bits like this:

function checkAll(id, name, flag)
{
   if ( document.forms[ id ].elements[ name ].length )
   /* ... */
}

or even using

function checkAll(id, name, flag)
{
   if ( document.getElementsById( id ).elements[ name ].length )
   /* ... */
}

but it's still a lot of code.

2. Stepping into JQuery

The second set of buttons will check or uncheck all checkboxes named myCB using JQuery.

<input type="button" name="ca_v2_on" value="JQuery Check All myCB" onclick="jqCheckAll('myForm', 'myCB', 1);"/>
<input type="button" name="ca_v2_off" value="JQuery Uncheck All myCB" onclick="jqCheckAll('myForm', 'myCB', 0);"/>

These buttons call the Javascript function jqCheckAll(). This function takes three arguments:

  1. The ID of the form that contains the checkboxes.
  2. The name of the checkboxes that will be checked.
  3. A flag to check (1) or uncheck (0) each checkbox.

jqCheckAll() - JQuery
function jqCheckAll( id, name, flag )
{
   if (flag == 0)
   {
      $("form#" + id + " INPUT[@name=" + name + "][type='checkbox']").attr('checked', false);
   }
   else
   {
      $("form#" + id + " INPUT[@name=" + name + "][type='checkbox']").attr('checked', true);
   }
}

Let's break down the JQuery code's syntax:

$("form#" + id + " INPUT[@name=" + name + "][type='checkbox']").attr('checked', false);

  1. $("form#" + id: Find a form whose ID is the value of the id argument.
  2. " INPUT[@name=" + name + "]: now find any INPUT element whose name matches the value of the name argument.
  3. [type='checkbox']: make sure that form element is of type "checkbox".
  4. .attr('checked', false);: set that element's checked attribute to true or false based on the value of the argument flag.

Ok, so that's a LOT less code. We also don't have to worry about there being one element or an array of elements. JQuery handles that for us.

3. Let JQuery handle things automatically.

Our third option for checking all these checkboxes involves a single form element. We don't even have to add any onclick or onchange events directly to the checkbox. JQuery will let us assign that outside of the HTML.

<input type="checkbox" name="checkAllAuto" id="checkAllAuto"/> Check All checkboxes with JQuery Automatically

Here we don't write a traditional Javascript function. Instead, we tell JQuery to assign a click event to a particular DOM object ( id="checkAllAuto" ). In that event, we will then define and run a function.

$( id ).click()
$('#checkAllAuto').click(
   function()
   {
      $("INPUT[type='checkbox']").attr('checked', $('#checkAllAuto').is(':checked'));   
   }
)

By not placing this code inside a defined function, we're defining the onclick event for the form element checkAllAuto when the page loads.

The line of JQuery inside the click event is broken down like this:

  1. $("INPUT[type='checkbox']"): Find all form elements of type "checkbox"
  2. .attr('checked', $('#checkAllAuto').is(':checked'));: and set their attribute checked to true or false
  3. $('#checkAllAuto').is(':checked'): based on the checked value of the form element checkAllAuto.

Wow! That's even less code. But there's a problem in that this code check or unchecks every checkbox in the form since we didn't specify a name attribute to find.

4. Merging options 2 and 3

Finally, we can merge the techniques used in the last two examples to check or uncheck multiple groups of checkboxes in the same form.

<p>4a.
   <input type="checkbox" name="checkAllMyCB" id="checkAllMyCB" onclick="jqCheckAll2( this.id, 'myCB' )"/> Check All named "myCB" with JQuery onclick.
</p>
   
<p>4b.
   <input type="checkbox" name="checkAllYourCB" id="checkAllYourCB" onclick="jqCheckAll2( this.id, 'yourCB' )"/> Check All named "yourCB" with JQuery onclick.
</p>

These two checkboxes will each mark a specific named group of checkboxes based on their own checked status.

jqCheckAll2()
function jqCheckAll2( id, name )
{
   $("INPUT[@name=" + name + "][type='checkbox']").attr('checked', $('#' + id).is(':checked'));
}

Broken down:

  1. $("INPUT[@name=" + name + "]: Find all INPUT elements whose name is the value of the name argument.
  2. [type='checkbox']"): and whose element type is checkbox
  3. .attr('checked', $('#' + id).is(':checked'));: and mark its checked attribute as true or false based on the checked status of the form element id.

5. I forgot your name (Added 7/16/2008)

You don't even have to use names or IDs on the checkboxes you want to check. All you need is the ID of their parent container. I've updated the FORM to add an ID to the two TDs that contain the groups of checkboxes.

<td id="left"><!-- check boxes --></td>
<td id="right"><!-- check boxes --></td>

And two more checkboxes to trigger checking any checkboxes they contain:

<p>5a.
   <input type="checkbox" id="checkL" onclick="jqCheckAll3(this.id, 'left');"/> JQuery Check All Left Column
</p>
<p>5b.
   <input type="checkbox" id="checkR" onclick="jqCheckAll3(this.id, 'right');"/> JQuery Uncheck All Right Column
</p>

And the function they call:

jqCheckAll3()
function jqCheckAll3( id, pID )
{
   $( "#" + pID + " :checkbox").attr('checked', $('#' + id).is(':checked'));
}

Broken down:

  1. $( "#" + pID: Find the element with this ID (could be a DIV, SPAN, FIELDSET, etc.)
  2. + " :checkbox"): and for all elements of type "checkbox" inside that element,
  3. .attr('checked', $('#' + id).is(':checked'));: mark their checked attribute as true or false based on the checked status of the form element id.

re: #1, you could even get more specific by saying:

$("TD#" + pID)

re: #2, I replaced [type='checkbox'] with " :checkbox" based on Richard's comment.

Summary

Hopefully, this simple (?!) example shows some of the power of the JQuery library. Give it a try when you start your next project or even better, see how you might incorporate it in an existing one. Once you get the basics down, you may find that you can get more done faster and with less code than you could by sticking to Old School Javascript.

References

The JQuery website
JQuery Google Group
DFW CFUG Google Group
JQuery Docs: Attributes/attr
JQuery Docs: Selectors/checked

I found the solution $('#' + id ).is(':checked'); here.

Related Blog Entries


Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Michael Brennan-White's Gravatar Very good article. I have been trying to learn jQuery also so this is very good. I don't use checkboxes very often but I will store this for reference when I do.
# Posted By Michael Brennan-White | 7/10/08 12:14 AM
Fedot Praslov's Gravatar that's no so fun as can be...
Let's use the power of jQuery:

jQuery.fn.checkAll = function(name,flag){
var selector = ':checkbox'+(name?'[@name='+name+']':'');
$(selector,this).attr('checked',flag);
}

And:

<input type="button" value="Check All myCB" onclick="$('#myForm').checkAll('myCB', 1);"/>
<input type="button" value="UnCheck All myCB" onclick="$('#myForm').checkAll('myCB', 0);"/>
<input type="button" value="Check All" onclick="$('#myForm').checkAll('', 1);"/>
# Posted By Fedot Praslov | 7/10/08 2:28 AM
Richard D. Worth's Gravatar Great post. One note: similar to :checked, there is also a :checkbox pseudo-selector you can use in place of INPUT[type='checkbox']. So it becomes simply $(":checkbox[name=" + name + "]").
# Posted By Richard D. Worth | 7/10/08 6:55 AM
Rey Bango's Gravatar Glad you're digging it Adrian. jQuery's been a big hit in the community.

Be sure to hit up the mailing list:

http://groups.google.com/group/jquery-en

and follow us on Twitter at @jquery & @jqueryui

Also, don't forget to check out the jQuery UI controls and effects library.

http://ui.jquery.com

Rey
jQuery Project Team
# Posted By Rey Bango | 7/16/08 1:06 AM
SeanJA's Gravatar Like Dave says:

"You start with 10 lines of jQuery that would have been 20 lines of tedious DOM JavaScript. By the time you are done it's down to two or three lines and it couldn't get any shorter unless it read your mind."

Which is what has happened in the comments ;)
# Posted By SeanJA | 7/16/08 3:40 AM
Dean's Gravatar Surely this only works if your checkboxes all have the same name? And for a form to work properly, checkboxes can't have the same name? Or am I missing something?
# Posted By Dean | 7/16/08 4:12 AM
Garrow's Gravatar Just to really get into the swing of things with what jQuery can do.

One liners for the win!!!!

$(':checkbox').click(function(){$(':checkbox[name='+ $(this).attr('name') +']').attr('checked',$(this).attr('checked'));});


Breaking that down.
      $(':checkbox').click(function() // Bind the following anonymous function to all checkboxes click event.
         {
               $(':checkbox[name=' + $(this).attr('name') +']') // Select all checkboxes with the same name as the calling element
                  .attr('checked',$(this).attr('checked')); // and set the checked attribute for these elements to the same as the calling element.
         });
# Posted By Garrow | 7/16/08 11:02 AM
Adrian J. Moreno's Gravatar @Dean: Any form element can certainly have the same name and they don't even have to be of the same type. Any elements of the same name become an array in the DOM.

It's the "id" attribute that's supposed to be unique per element. Since it's harder to specify a bunch of related elements by ID, you can have JQuery manipulate objects within some parent container.

I decided to add a 5th example to show that if I removed the name attributes from all the checkboxes and added an ID to each <td>, I could tell JQuery to check all elements of type "checkbox" that exist within a specific container.

HTH
# Posted By Adrian J. Moreno | 7/16/08 12:14 PM
Dean's Gravatar But if you try to process that form submission using PHP, only the last declared checkbox will be recognised if they all have the same name.
# Posted By Dean | 7/16/08 2:31 PM
Tim's Gravatar Just curious if you've played w/ Prototype at all, and what, if any advantages JQuery has over it (I'm partial to Prototype, personally, though I haven't had any practical experience with JQuery).
# Posted By Tim | 7/16/08 6:48 PM
Adrian J. Moreno's Gravatar @Tim: No, I haven't tried prototype myself, but my coworker directly to my right lives by it. I've seen him do some really cool things with it. I chose to work with JQuery since that's all I ever hear anyone talk about on the blogs I follow.

However, Remy Sharp has a great comparison of the two on Ajaxian.com:

http://ajaxian.com/archives/prototype-and-jquery-a...
# Posted By Adrian J. Moreno | 7/21/08 12:04 AM
Adrian J. Moreno's Gravatar @Dean: I haven't worked with PHP in a few years, but I thought if you added square brackets as part of the name, PHP would treat the results as an array.

<input type="checkbox" name="foo[]" value="0/>
<input type="checkbox" name="foo[]" value="1/>
<input type="checkbox" name="foo[]" value="2/>

IIRC, you also have to make sure you're using method="post" and not method="get" in the form tag.
# Posted By Adrian J. Moreno | 7/21/08 12:07 AM
Enrique's Gravatar Awesome post
I could make my select all checkboxes complicated stuff easily...
# Posted By Enrique | 7/24/08 8:52 PM
Kamil Saiyed's Gravatar How do you do the reverse: For example when all checkboxes have been checked, can unchecking one or more of the already checked boxes, also uncheck the check-all checkbox
# Posted By Kamil Saiyed | 8/20/08 9:23 PM
Alex Min's Gravatar @Dean: You can use unique names for all checkboxes and simply assign certain classes to their logical "groups." ([label for="q_1" class="c_1"][input type="checkbox" name="q_1" etc].

The js function to check/uncheck all would become:

function checkAll(elementclass,selectstatus){
$j(elementclass).each(function(){
var name = $j(this).attr('name');
var selector = ':checkbox'+(name?'[@name='+name+']':'');
$j(selector,this).attr('checked',selectstatus);
});
}
# Posted By Alex Min | 10/13/08 11:05 AM
Edu's Gravatar i`m a jquery newbie

I work with php.

i´m trying to use:

function jqCheckAll(id, name, flag){
if(flag == 0){
$("form#" + id + " INPUT[@name=" + name + "][type='checkbox']").attr('checked', false);
}
else{
$("form#" + id + " INPUT[@name=" + name + "][type='checkbox']").attr('checked', true);
}
}

with this form:

<div class="op"><input name="cursos[]" type="checkbox" id="curso0" value="1" />1ºA</div>

<div class="op"><input name="cursos[]" type="checkbox" id="curso1" value="2" />1ºB</div>

<div class="op"><input name="cursos[]" type="checkbox" id="curso2" value="3" />2ºA</div>

<div class="op"><input name="cursos[]" type="checkbox" id="curso3" value="4" />2ºB</div>

And this button:
onclick="jqCheckAll('form1', 'cursos[]', 1);"

it doesn't work
how can i do to use the name 'cursos[]' (with brackets).

Sorry, i write english very bad.
# Posted By Edu | 11/21/08 9:35 AM
Bagus's Gravatar We solved the [] issue for php by using a "starts-with" or ^ in front of the = operator in jqCheckAll2:<br>

$("INPUT[@name^=" + name + "][type='checkbox']").attr('checked', $('#' + id).is(':checked'));
# Posted By Bagus | 12/8/08 5:33 PM
trellis's Gravatar I am creating the checkboxes dynamically (in coldfusion) and they must have a different name.
I cannot use the 5th example (assign an ID to the <td>) because each row is dynamically created also.
For example I cannot not use onclick="jqCheckAll3(this.id, 'right');" because there is not only one 'right' row, each time there are many.
Any solutions to this problem?
# Posted By trellis | 3/18/09 1:41 PM
James's Gravatar @trellis - I just did this in ColdFusion by assigning a an ID for the checkbox groups. Also if you are using jQuery 1.3 you need to drop the @ (it was depreciated in 1.2). I used the following and it worked great:

function jqCheckAll( id, pID )
{
   $("INPUT[id=" + pID + "][type='checkbox']").attr('checked', $('#' + id).is(':checked'));
}

and

<input type="checkbox" name="chkApproveAll" onclick="jqCheckAll(this.id, 'chk#number#');">

<input type="checkbox" name="chkApprove" id="chk#number#" value="1" />
# Posted By James | 4/21/09 5:06 PM
Brian's Gravatar Cheers, this was a great resource. Thank you very much for taking the time to put this together.
# Posted By Brian | 2/6/10 9:33 PM