Toggle Table Rows with jQuery, no plug-in required

Last week I encountered a situation with one of our web apps that required a toggle-able table row. Essentially the existing table was populated with information from four different tables. In addition to several joins there were some nested queries, and it was killing the MySQL server.

So, I decided to pull the information from the nested queries out of the rows and use a hidden table row below each existing row where I would show the formerly nested information using an ajax call to retrieve. Removing the nested queries significantly improved query performance.

The biggest problem in this was creating a table row that toggles. The native toggle() jquery function didn’t work at first, and this is because a table row’s display attribute is “table-row”, and not “block” as toggle() resets to.

I found this jQuery plugin by Janko at Warp Speed for doing exactly what I need. It is simple and works quite well with the minimum necessary amount of code. This is accomplished by using jQuery calls to add an anonymous click function to the even rows. However, there are some drawbacks. First, if you observe the demo, notice that a click anywhere in the parent row triggers the toggle.  This is great unless you have a link in the parent row.  What to do if you have, say, a table of employees and you want a link to their full record in the parent row?

Quite unintentionally, after fiddling with jQuery for a couple of hours I came up with a solution.  Only after I tested did I realize I had Janko’s plugin commented out.  I was able to confirm my solution works with no plugin required.  Rather than using the odd/even selectors in jQuery, I have used row ID numbers as you will see in the demo.  To exempt the cell with the link from the anonymous click function, I have added the clickable class to each cell instead.  If you don’t want this extra layer of complexity, just strip out all the parent() business from the JavaScript.

Please help yourself to the code and let me know what you think. View the demo…

P.S. In case you are wondering why I have an empty third row for each record:  This is to preserve the jQuery-based alternating table row highlighting that uses the jQuery even selector.  Since Janko’s solution also relies on this method, it was wiping out my table striping.

delicious | digg | reddit | facebook | technorati | stumbleupon | chatintamil

13 thoughts on “Toggle Table Rows with jQuery, no plug-in required

  1. It’s interesting you chose to tackle the problem on the client-side. Have you considered creating a view to handle the table concatenation, and then using the view for your web app? The view only gets updated when the underlying tables are updated, and you save all the expensive query overhead your app is putting on the system.

  2. Hey Trent,

    I don’t consider a little client side JS very expensive, unless perhaps the client is IE6 running on a Pentium 3 or some such. Most of my apps are MySQL driven, and though MySQL supports views, they are very inefficient as compared to the way views are implemented in, say, Oracle. I tend to prefer to minimize database transactions, since such actions produce noticeable slow downs in page load time.

    Oh, and really cool to hear from you!

  3. Worked perfectly. Small footprint and to the point. Thanks for sharing.
    I also tried to use Janko’s plugin first, but like you stated, the entire row is the trigger and you can’t have links (nor nested tables in the hidden row). Besides, it’s always a nice bonus not to need a plugin.

    If there was one thing that I would like to add to it, it would be the following:
    I have a simple hover effect for the visible table rows when the user moves the mouse over them, just to make it easier to see what data is associated with what row. I would like the row that is clicked to maintain this color until the user clicks the row again. Is that possible?

    In either case, thanks again for sharing.

  4. You’re very welcome, thanks for visiting!

    Would be very possible to add the preserved highlight. Would just need to use jQuery to bind a click event to the table rows which would execute an .addClass(‘highlight’).

  5. Check the demo again. I added two new css lines at lines 34 and 35 of index.html, and added a .toggleClass call to line 49. It doesn’t highlight the entire row (just the previously hidden row), but with the way I’ve set this up (adding the alternating row css class on click) it would be way more complicated to highlight the whole thing. I’ve basically got two addclass calls conflicting with each other.

  6. Chris-

    Fantastic! I love it. I’m doing a complete revamp on a site right now and your solution was just what I needed to solve my problem and keep me rolling along. I sure appreciate it.

  7. Hi,

    Thanks for sharing!
    Please Can you tell me How do I call Ajax and append dynamid id (record id), above your code:

    $(document).ready(function(){

    // jQuery striped stables
    // http://docs.jquery.com/Tutorials:Zebra_Striping_Made_Easy
    $(‘.dataTable tr:even’).addClass(“alt”);

    $(“#items tr.itemDetail”).hide();
    $(“#items tr.data td.clickable”).click(function(){

    $(this).parent().next(“tr”).toggle().toggleClass(‘highlight’);
    if($(this).parent().hasClass(‘alt’)) {
    $(this).parent().next(“tr”).addClass(‘alt’);
    } else {
    $(this).parent().next(“tr”).removeClass(‘alt’);
    }

    $(this).parent().find(“.arrow”).toggleClass(“up”);

    $(“.slidingDiv”).html(”);

    HERE I ADDED BUT NO WORKS …..
    $(this).parent().attr(‘id’).html(”);
    $(this).parent().attr(‘id’).load(“ajcall.php”);

    // getAjaxedContent($(this).parent().attr(‘id’)); // if you ajax what’s in the in the hidden row, you’d want to fire your ajax function here’
    $(‘#items tr.data td’).css(‘border-collapse’, ‘collapse’);

    });

    });

    THANKS

  8. Thanks for the easy to follow code. Not knowing much about jquery (yet) is it possible you could share how to perform an ajax query for the toggled table row?

    Another thing, would you know how to add a function that one could click on the toggled row and have it hide?

    Thanks!

  9. Thank you so much for this code. It is exactly what I was looking for and modifying it is so easy. Cheers!

  10. Thanks a lot for this code. It´s been a while since you did this, but I hope you still is in business and would like to help me. My problem is that I have several links on each row and don’t want the whole row to be clickable. Is it possible to just let the arrow-link to toggle the row?

  11. I Solved it! 🙂

    //$(“#report tr.odd”).click(function () {
    $(“#report tr.odd .arrow”).click(function () {
    //$(this).next(“tr”).toggle();
    //$(this).find(“.arrow”).toggleClass(“up”);
    $(this).parent().parent().next(“tr”).toggle();
    $(this).toggleClass(“up”);
    });

Leave a Reply

Your email address will not be published. Required fields are marked *