jQuery Quickie: Highlighting a table row after selecting a checkbox

One of the nice little UI features in GMail is how it will highlight an entire table row when you check the checkbox for a particular mail message. It's a relatively simple thing to do but I wanted to whip up a quick sample for myself. Here is one way to do it with ColdFusion and jQuery.

First, our data:

<cfquery name="art" datasource="cfartgallery"> select * from art </cfquery>

Yes, I know, select * is evil. I figure as long as I don't drop an entire database in my SQL statement I'm coming out ahead. Next - the output:

<table id="artTable" border="1"> <tr> <td> </td> <th>Name</th> <th>Price</th> </tr> <cfoutput query="art"> <tr> <td><input type="checkbox" name="select" value="#artid#"></td> <td>#artname#</td> <td>#dollarFormat(price)#</td> </tr> </cfoutput> </table>

Nothing too fancy here. I display two columns from the query along with a checkbox in the left most column. Now for the JavaScript:

$(document).ready(function() {

$("#artTable input:checkbox").click(function() { $(this).parent().parent().toggleClass("highlight") }) })

Basically - listen to click events in checkboxes within my art table, and on click, toggle a CSS class named highlight. Not exactly rocket science, but it gets the job done! The entire template is below the screen shot. Enjoy!

<html>

<head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script> $(document).ready(function() {

$("#artTable input:checkbox").click(function() { $(this).parent().parent().toggleClass("highlight") }) }) </script> <style> .highlight { background-color:pink; } </style> </head>

<body>

<cfquery name="art" datasource="cfartgallery"> select * from art </cfquery>

<table id="artTable" border="1"> <tr> <td> </td> <th>Name</th> <th>Price</th> </tr> <cfoutput query="art"> <tr> <td><input type="checkbox" name="select" value="#artid#"></td> <td>#artname#</td> <td>#dollarFormat(price)#</td> </tr> </cfoutput> </table>

</body> </html>

Archived Comments

Comment 1 by Eric Hynds posted on 11/19/2009 at 12:37 AM

You might get better performance out of parents("tr") instead of calling parent() twice. I've always wondered that...

Comment 2 by Matt posted on 11/19/2009 at 12:52 AM

I needed something like this so I just put it in my code. Everything works, except on the first row, it takes two times for it to work. Is there something I did wrong? On every other row it works perfect.

Comment 3 by Raymond Camden posted on 11/19/2009 at 1:11 AM

@Eric: Thank you! I didn't know you could do parents('x') and have it find the parent going upwards.

@Matt: odd - it works ok for me. What browser?

Comment 4 by Chuck Savage posted on 11/19/2009 at 1:22 AM

@Ray,

There anyway to get your code examples without line numbers?

Comment 5 by Matt posted on 11/19/2009 at 1:22 AM

Firefox, but it may have just been for the page I'm using it on. Thanks for the code!!

Comment 6 by Raymond Camden posted on 11/19/2009 at 1:26 AM

@Chuck: Not yet - I may revert the option to include the line #s. Sorry about that!

@Matt: Let me know if you discover an issue though.

Comment 7 by Brian Lang posted on 11/19/2009 at 3:16 AM

Assumption: Each row in the database has a Unique ID (integer or uuid).
You could modify your <tr> tag to include an id attribute prefaced with a letter (for integers). For example: <tr id="a#artid#">.
Also change the <input> value attribute to "a#artid#". For example: <td><input type="checkbox" name="select" value="a#artid#"></td>
Then change your JQuery click function to the following:
$("#" + $(this).val()).toggleClass("highlight");
What this does: Concatenate the ID selector (#) with the value of the ID attribute and toggle the class.

Comment 8 by Justin Schier posted on 11/19/2009 at 5:59 AM

There's a new jQuery method for doing this. .closest() finds the one nearest parent matching the selector you specify.

$("#artTable input:checkbox").click(function() {
$(this).closest('tr').toggleClass("highlight")
})

Comment 9 by parthiban posted on 11/19/2009 at 7:04 AM

Hi amazing site for jquery explaination. Also see this site
www.phpjquery.com

Comment 10 by Tim Leach posted on 11/19/2009 at 10:23 AM

I'm surprised I'm the first to say this, but that only works if all of the check boxes are unchecked by default.

I'd be more comfortable with:
if(this.checked){
$(this).parents('tr').addClass("highlight");
}else{
$(this).parents('tr').removeClass("highlight");
}

Or for jQ 1.3 a simple:
$(this).parents('tr').toggleClass("highlight",this.checked);

Just becomes somewhere, somehow one of those will end up checked by default, and have the opposite effect.

Comment 11 by Tim Leach posted on 11/19/2009 at 10:24 AM

Sigh:
*because

Comment 12 by Raymond Camden posted on 11/19/2009 at 5:38 PM

@Tim: The reason why is that it was based on the gmail model - where on initial load, nothing is checked. It was intentional. :) As it stands, if the server side code checked it, and included the style highlight, then the toggle should still work (afaik).

Comment 13 by Raymond Camden posted on 12/31/2009 at 8:39 PM

@Tim, I've got a demo showing support for some items checked by default. Will blog it later today.

@Chuck - no more line #s. Thank Jason Delmore.