0

I have a html table like this:

Group Amount
x     3
x     1
test  2
test  5

But I would like to have this:

Group    Amount
x        3
x        1
sum x    4
test     2
test     5
sum test 7

I already can add a row at a index:

$('.mytable > tbody > tr').eq(i-1).after(html);

But how could I get the index and the sum with jquery?

6
  • you can get the amount adding an id to the tr and use $('#id').val() parse to int and sum them. Commented Sep 14, 2015 at 13:47
  • Are the groups set, or can they change in the future? Commented Sep 14, 2015 at 13:50
  • The groups can change Commented Sep 14, 2015 at 13:54
  • @phpjssql I've updated my answer. Commented Sep 14, 2015 at 14:00
  • Will the groups always be together, or could they be mixed? Commented Sep 14, 2015 at 14:12

3 Answers 3

1

This will do what you need, for all future groups, with the values in any order, but I'd strongly recommend doing all this on the server when you first get the information....

var groups = {};

// get the sums of all the groups in the table, and the index of the last row of each
$(".mytable tbody tr").each(function(i) {
    var group = $(this).find("td").eq(0).text();
    var value = parseInt($(this).find("td").eq(1).text(), 10);
    if (groups.hasOwnProperty(group)) {
        groups[group].sum += value;
    }
    else {
        groups[group] = {
            sum: value
        };
    }
    groups[group].index = i;
});

// convert the group information into an array so it can be sorted...
var groupArray = [];
for(var group in groups) {
    groups[group].name = group;
    groupArray.push(groups[group]);
}

// sort the groups in reverse index order
groupArray = groupArray.sort(function(a, b) {
    return b.index - a.index;
});

// parse the groups of values and add them to the table, after the final row of each group
for (var i = 0, l = groupArray.length; i < l; i++) {
    $(".mytable tbody tr").eq(groupArray[i].index).after("<tr><td>Sum " + groupArray[i].name + "</td><td>" + groupArray[i].sum + "</td></tr>");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table class="mytable">
    <thead>
        <tr>
            <th>Group</th>
            <th>Amount</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>x</td>
            <td>3</td>
        </tr>
        <tr>
            <td>x</td>
            <td>1</td>
        </tr>
        <tr>
            <td>test</td>
            <td>2</td>
        </tr>
        <tr>
            <td>test</td>
            <td>5</td>
        </tr>
    </tbody>
</table>

Sign up to request clarification or add additional context in comments.

Comments

1

Please try this one.

var sums = [];

$("table.mytable tbody tr").each(function(index) {
  var label = $(this).find("td:first-child").html();
  var value = parseInt($(this).find("td:last-child").html());
  if (sums.length == 0 || sums[sums.length - 1].label != label)
    sums.push({
      index: index,
      label: label,
      sum: value
    });
  else
    sums[sums.length - 1].sum += value;
});

for (var i = 0; i < sums.length; i++)
  $('table.mytable > tbody > tr').eq(sums[i].index + i).after("<tr><td>" + sums[i].label + "</td><td>" + sums[i].sum + "</td></tr>");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<table class="mytable">
  <thead>
    <tr>
      <th>Group</th>
      <th>Amount</th>
    </tr>
    <thead>
      <tbody>
        <tr>
          <td>x</td>
          <td>3</td>
        </tr>
        <tr>
          <td>x</td>
          <td>1</td>
        </tr>
        <tr>
          <td>test</td>
          <td>2</td>
        </tr>
        <tr>
          <td>test</td>
          <td>5</td>
        </tr>
      </tbody>
</table>

Comments

1

The row index you can use de .rowIndex property of the table row element ($tr[0].rowIndex).

The sum, you would have to iterate over the elements, if you elements are ordered by group:

var group, sum = 0;

$('table tr').each(function () {

    var $tr = $(this);

    if (!group)
        group = $tr.children('td:first-child').text();

    sum += parseFloat($tr.children('td:last-child').text());

    if ($tr.next().children('td:first-child').text() !== group) {

        $tr.after('<tr><td>sum of ' + group + '</td><td>' + sum + '</td></tr>');

        sum = 0;
        group = null;

    }

});

Although you can achieve the desired result with that, I encourage you not to do this. You are strongly relying on the data and HTML structure. Your code is going to be fragile, hard to maintain and, probably, with poor performance.

4 Comments

He needs to add up the groups, not every row.
Thanks a lot, it nearly works perfect. But now the index is to high and the sum includes the first amount of the next group. The sum of the last group is missing.
I did not test it. Soon I will fix it.
@phpjssql fixed it. Hope i've helped.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.