Search code examples
jqueryjquery-pluginstablesorter

jQuery tablesorter grouping subtotals for child rows only


enter image description hereI need to have the group subtotals display in the group header rows of my table. Everything is working fine except the math. Inside each group, I have expanding parent rows that contain the total of all child rows for that parent. When I total my groups, it adds all parent & child rows together, giving me a total that is 2x the number I am looking for. Is there a way to add ONLY the child rows, or ONLY the parent rows? Here's what I have so far:

group_callback: function($cell, $rows, column, table) {
   if (column === column) {
      var t, successesTotal = 0;
      $rows.each(function() {
            successesTotal += parseInt($(this).parent('td').eq(successesColumn).text());
});

I have tried a few different ways that seem logical but none of them seem to work.

successesTotal += parseInt($(this).find('tbody tr.tablesorter-childRow td').eq(successesColumn).text());

Didn't work. Neither did:

$rows.each(function() {
     if ($('tr').hasClass('tablesorter-childRow')) {
         successesTotal += parseInt($(this).parent('td').eq(successesColumn).text());
 });

I am SO close to having this work exactly as I need it but I still need to exclude the parent rows from the calculation & it will be perfect. In the image attached, the bolded lines are the parent rows displaying the totals of their child rows. Successes should be 165 & total lines should be 6 (or 2, either way will work for me!) I have spent almost 2 full days now trying to get around this. Any suggestions would be appreciated!!

As requested, here is the table HTML (modified for simplification):

<table class="tablesorter">
   <thead>
     <th class="group-word">Column1</th>
     <th class="group-false filter-parsed">Column2</th>
     <th class="group-false filter-parsed">Column3</th>
   </thead>
   <tbody>
      <tr>
         <td>Category1</td>
         <td><a href="#" class="toggle">Category2</a></td>
         <td>Subtotal1</td>
      </tr>
      <tr class="tablesorter-childRow">
         <td>ChildData1</td>
         <td>ChildData2</td>
         <td>ChildData3</td>
      </tr>
      <tr class="tablesorter-childRow">
         <td>ChildData1</td>
         <td>ChildData2</td>
         <td>ChildData3</td>
      </tr>
  </tbody>

I want to add ChildData3 with ChildData3. I need to exclude SubTotal1.


Solution

  • The $rows parameter in the group_callback provides both the parent and all child rows, so you'll need to filter out one or the other.

    // only target child rows
    $rows.filter('.tablesorter-childRow')
    

    Here is the code from this demo

    var successesColumn = 0;
    $("#table").tablesorter({
      theme: "blue",
      widgets: ["group", "filter", "zebra"],
      widgetOptions: {
       group_collapsible : true,
        group_callback: function($cell, $rows, column, table) {
          if (column === successesColumn) {
            var t, successesTotal = 0;
            $rows.filter('.tablesorter-childRow').each(function() {
              successesTotal += parseInt($(this).find('td').eq(successesColumn).text(), 10);
            });
            $cell.find(".group-count").append("; Successes: " + successesTotal );
          }
        }
      }
    });
    

    Other fixes:

    • The $rows variable has trs in it, so use .find('td') instead of parent.
    • It's a good habit to get into to add a radix of 10 when using parseInt for decimal integers (ref)