2

I've a html table, generated by code, of many rows and column. Some of this TD has a ON class to style it differently.

The structure of table has an header, a body, and a footer row.

I'd like to sum the quantity of all the TD with class 'ON' in each column and put the result on last row (footer) in each column.

How can I do it? (the rows and column are not a 'fixed matrix', so I don't know in advance how many rows and columns has the table)

Example table:

data       | id_1 | id_2 | id_3 | ...
2012-06-20 | "ON" |      |      | ...
2012-06-21 | "ON" |      |      | ...
2012-06-22 | "ON" | "ON" |      | ...
2012-06-23 | "ON" |      | "ON" | ...
2012-06-24 | "ON" | "ON" |      | ...
tot        |   5  |   2  |   1  | ...

UPDATE: mixing solutions of CRANIO and ALNITAK this is the result:

var a = [];
$('td').each(function() {

    var n = $(this).index();
    if($(this).hasClass('on')){
       a[n] = a[n] ? a[n] + 1 : 1;
    }else{
       a[n] = a[n] ? a[n] : 0;
    }
});

var t = $('<tr>').appendTo('#tableID > tfoot');
$.each(a, function(i, n) {
    t.append($('<td>', { text: i === 0 ? 'total' : n }));
});

In this way you add ZEROS (or empty space ---> a[n] = a[n] ? a[n] : ''; <--- to columns without TD.on and resolve little bug if there are some empty cols on the end of table (in the elegant solution of alnitak the TD on last row were not added)

P.S. useful also to create different total rows, on different TD.class, appending more TR based upon different class.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
keebOo
  • 83
  • 2
  • 10

2 Answers2

4

See http://jsfiddle.net/cranio/RTugL/

I've tried this table:

<table>
<tr>
    <td></td>
    <td></td>
    <td class='on'>.</td>
    <td class='on'>.</td>
</tr>    

<tr>
    <td class='on'>.</td>
    <td class='on'>.</td>
    <td></td>
    <td></td>
</tr>    
<tr>
    <td></td>
    <td class='on'>.</td>
    <td class='on'> .</td>
    <td class='on'>.</td>
</tr>    </table>

with this code:

var a = new Array();
$("table tr").each(
    function (i,e)
    {
        $(e).find("td").each(
            function (i,e)
            {
                if (!a[i]) a[i] = 0;
               if ($(e).hasClass("on")) a[i]++;   
            });});
var lastrow = $("<tr>");
$.each(a, function(i,e) { lastrow.append("<td>"+e+"</td>");});
$("table").append(lastrow);

What I do is count the occurrences of TD.on in an array, updated for every "position". ​

Cranio
  • 9,647
  • 4
  • 35
  • 55
  • This example counts for ALL the columns. If you want to exclude some columns tell me. – Cranio Jun 25 '12 at 12:58
  • 1
    Demos are great, but please post the code in your answer too - sometimes jsfiddle is unavailable. (No need to post any infrastructure that you setup just to make the fiddle work.) – nnnnnn Jun 25 '12 at 13:17
  • In this case I've posted the infrastructure to make sure I've interpreted the OP's request in the right way, @nnnnnn – Cranio Jun 25 '12 at 14:52
  • @Cranio ...longer but useful (little bug on version of Alnitak: if there are some empty colums at the end, no TD is added) ;) use this – keebOo Jun 25 '12 at 15:54
  • @keebOo and to be fair I think you've used much more of my answer than his ;-) – Alnitak Jun 25 '12 at 16:29
  • No problem if you feel you feel to have more credit, it's deserved, @Alnitak – Cranio Jun 25 '12 at 16:32
  • @Cranio nah, I'm not bothered. I just wondered where my 15 rep points had gone - I've hit the limit for "normal" rep points today... – Alnitak Jun 25 '12 at 16:32
2

Here's the shortest code I can currently come up with:

var a = [];
$('td.on').each(function() {
    var n = $(this).index();
    a[n] = a[n] ? a[n] + 1 : 1;
});

var t = $('<tr>').appendTo('table');
$.each(a, function(i, n) {
    t.append($('<td>', { text: i === 0 ? 'total' : n }));
});​

working sample at http://jsfiddle.net/alnitak/6XTvN/

EDIT to ensure an empty cell (and zeros) for columns that don't match here's a variant for the first code block:

var a = [];
$('td').each(function() {
    var n = $(this).index();
    a[n] = a[n] || 0;
    a[n] += $(this).hasClass('on');
});

My first version had the minor defect that a column with no matching cells would produce an undefined value in a, leading to a blank cell, but worse a completely missing cell for any trailing columns that had no matching cells.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • Much shorter than mine, good, upvoting :) Didn't think about `.index()` – Cranio Jun 25 '12 at 14:04
  • @Cranio mine also handles the header column ;-) – Alnitak Jun 25 '12 at 14:06
  • it' ok, but give me an error inside an ajax success (really don't find yet why, also beacuse on jsfiddle it's correct). but resolved using the first part on "count array" and write result on footer row. :) thanks – keebOo Jun 25 '12 at 15:07
  • @Alnitak really nice (I hate to use if when there is a so clear and elegant solution), I'll update again the code. thanks. – keebOo Jun 26 '12 at 06:21