13

How can I hide the column with all empty cells including the title <th> in that column, while leaving the other columns and their titles as it is. Following jquery hides the entire <th>, which is not I want. Here is a sample, where I want to hide only the entire 'Column3' including <th>. Many thanks in advance.

$('table#mytable tr').each(function() {
    if ($(this).children('td:empty').length === $(this).children('td').length) {
        $(this).hide();
    }
});
DGT
  • 2,604
  • 13
  • 41
  • 60
  • 2
    That code hides the table rows and not columns, as `$(this)` will get the values of each `tr`. – Dan Mar 02 '11 at 19:39
  • 1
    Do you want to hide column with all empty cells, or with one or more empty cells? – artyom.stv Mar 02 '11 at 19:40
  • I want to hide the column with all empty cells including the title in the column, while leaving the other column titles as it is. Thanks. – DGT Mar 02 '11 at 19:50

6 Answers6

16

Took a while to piece together. Thanks to nxt for some of the code.

$('#mytable th').each(function(i) {
    var remove = 0;

    var tds = $(this).parents('table').find('tr td:nth-child(' + (i + 1) + ')')
    tds.each(function(j) { if (this.innerHTML == '') remove++; });

    if (remove == ($('#mytable tr').length - 1)) {
        $(this).hide();
        tds.hide();
    }
});
Stephen Walcher
  • 2,565
  • 1
  • 21
  • 22
  • This doesn't remove the header if the header has content (a title) but nothing underneath. I'm still working that one out. – Stephen Walcher Mar 02 '11 at 19:43
  • Exactly, it doesn't hide the title, which is what i want to hide, while leaving the other titles as it is. Thanks. – DGT Mar 02 '11 at 19:46
  • [An anonymous user comments](http://stackoverflow.com/suggested-edits/213318): "I discovered that I needed to repeat the table id in the .find, otherwise it hides empty cells in other tables in the parent hierarchy. i.e. `.find('#mytable tr td:nth-child(' + (i + 1) + ')')`" – Rup Mar 03 '12 at 10:44
7

If you want to hide the column if all cells (ignoring the header) are empty, you could do something like:

$('#mytable tr th').each(function(i) {
     //select all tds in this column
     var tds = $(this).parents('table')
              .find('tr td:nth-child(' + (i + 1) + ')');
        //check if all the cells in this column are empty
        if(tds.length == tds.filter(':empty').length) { 
            //hide header
            $(this).hide();
            //hide cells
            tds.hide();
        } 
}); 

Sample: http://jsfiddle.net/DeQHs/

Sample 2 (adapted for jQuery > 1.7): http://jsfiddle.net/mkginfo/mhgtmc05/

Max Leske
  • 5,007
  • 6
  • 42
  • 54
nxt
  • 1,983
  • 12
  • 13
4

None of the solutions here worked for me. This was what I used to hide empty columns with or without a text in the header:

    $('table').each(function(a, tbl) {
        var currentTableRows = $(tbl).find('tbody tr').length;
        $(tbl).find('th').each(function(i) {
            var remove = 0;
            var currentTable = $(this).parents('table');

            var tds = currentTable.find('tr td:nth-child(' + (i + 1) + ')');
            tds.each(function(j) { if ($(this).text().trim() === '') remove++; });

            if (remove == currentTableRows) {
                $(this).hide();
                tds.hide();
            }
        });
    });
nmat
  • 7,430
  • 6
  • 30
  • 43
3

http://jsfiddle.net/nlovatt/JsLn8/

A multi-table example which avoids using the table id in the selectors

codefinger
  • 33
  • 4
1

You need the next code:

HTML

<table id="mytable" border="1">
    <thead>
        <tr><th>Column1</th><th>Column2</th><th>Column3</th><th>Column4</th></tr>
    </thead>
    <tbody>
        <tr class="data"><td>1st</td><td>1.1</td><td></td><td>1</td></tr>
        <tr class="data"><td>2nd</td><td>2.01</td><td></td><td>2</td></tr>  
        <tr class="data"><td>3rd</td><td>3.001</td><td></td><td>3</td></tr>  
        <tr class="data"><td>4th</td><td>4.01</td><td></td><td>4</td></tr>
    </tbody>
</table>

JavaScript

var $table = $('#mytable');
var thead = $table[0].tHead, tbody = $table[0].tBodies[0];
var colsLen = tbody.rows[0].cells.length, rowsLen = tbody.rows.length;
var hideNode = function(node) { if (node) node.style.display = "none"; };
for (var j = 0; j < colsLen; ++j) {
    var counter = 0;
    for (var i = 0; i < rowsLen; ++i) {
        if (tbody.rows[i].cells[j].childNodes.length == 0) ++counter;
    }
    if (counter == rowsLen) {
        for (var i = 0; i < rowsLen; ++i) {
            hideNode(tbody.rows[i].cells[j]);
        }
        hideNode(thead.rows[0].cells[j]);
    }
}
artyom.stv
  • 2,097
  • 1
  • 24
  • 42
0

If the table data are from a MySQL query it possible to verify if a column is empty by using count on the field (count = 0 means that there are no values).

It is quite fastidious when you have many fields, and the IF condition is needed for the corresponding header and footer cells too. But it works...

if ($sum_field>'0') echo "<th>field</th>";
if ($sum_field>'0') echo "<td>" . $row['field'] . "</td>";

@nmat solution works fine but doesn't handle footers.

Guppy
  • 426
  • 5
  • 9