40

I want to display a basic html table with controls to toggle showing/hiding of additional columns:

<table id="mytable">
    <tr>
        <th>Column 1</th>
        <th class="col1">1a</th>
        <th class="col1">1b</th>
        <th>Column 2</th>
        <th class="col2">2a</th>
        <th class="col2">2b</th>
    </tr>
    <tr>
        <td>100</td>
        <td class="col1">40</td>
        <td class="col1">60</td>
        <td>200</td>
        <td class="col2">110</td>
        <td class="col2">90</td>
    </tr>
</table>

So Column 1 and Column 2 will be the only columns displayed by default - but when you click on the Column 1 I want 1a and 1b to toggle, and same with Column 2 with 2a and 2b. I may end up with more columns and lots of rows - so any javascript looping approaches have been too slow to work with when I tested.

The only approach that seems to be fast enough is to set up some css like this:

table.hide1 .col1 { display: none; }
table.hide2 .col2 { display: none; }
table.hide3 .col3 { display: none; }

table.show1 .col1 { display: table-cell; }
table.show2 .col2 { display: table-cell; }
table.show3 .col3 { display: table-cell; }

And then set up onClick function calls on the table header cells that will trigger a toggle - and determine which css class to set "mytable" to that will create the toggle effect that I'm looking for. Is there an easy way to set this up so that the code can work for n # of columns?

Update

Here is what I came up with, works great - and really fast. Let me know if you can think of ways to improve.

CSS

.col1 {display: none; }
.col2 {display: none; }
.col3 {display: none; }

table.show1 .col1 { display: table-cell; }
table.show2 .col2 { display: table-cell; }
table.show3 .col3 { display: table-cell; }

Javascript

function toggleColumn(n) {
    var currentClass = document.getElementById("mytable").className;
    if (currentClass.indexOf("show"+n) != -1) {
        document.getElementById("mytable").className = currentClass.replace("show"+n, "");
    }
    else {
        document.getElementById("mytable").className += " " + "show"+n;
    }
}

And the html snippet:

<table id="mytable">
<tr>
    <th onclick="toggleColumn(1)">Col 1 = A + B + C</th>
    <th class="col1">A</th>
    <th class="col1">B</th>
    <th class="col1">C</th>
    <th onclick="toggleColumn(2)">Col 2 = D + E + F</th>
    <th class="col2">D</th>
    <th class="col2">E</th>
    <th class="col2">F</th>
    <th onclick="toggleColumn(3)">Col 3 = G + H + I</th>
    <th class="col3">G</th>
    <th class="col3">H</th>
    <th class="col3">I</th>
</tr>
<tr>
    <td>20</td>
    <td class="col1">10</td>
    <td class="col1">10</td>
    <td class="col1">0</td>
    <td>20</td>
    <td class="col2">10</td>
    <td class="col2">8</td>
    <td class="col2">2</td>
    <td>20</td>
    <td class="col3">10</td>
    <td class="col3">8</td>
    <td class="col3">2</td>
</tr>
</table>
3
  • Ok so there doesn't seem to be another way to do this - but is there a way to do it so its a "sticky" toggle? Right now, every time I show one column, the other column that was showing goes into the hide state. I guess I have to add css rules to specifically handle every permutation??? I hope not...won't be fun if I'm dealing with 5 show/hide columns. Commented May 18, 2010 at 15:56
  • 1
    Hmm IE7 does not like the solution I posted. I can get it to work with all the columns showing by default, but not with hiding by default... Commented May 18, 2010 at 20:00
  • You can add multiple classes: table.className= 'show1 show3' etc. I suspect the IE problem is that, as I mentioned, it does not support display: table-cell. I'd use classes like hide instead of show, so you only have to declare table.hide1 col1 { display: none; }. Commented May 18, 2010 at 20:09

5 Answers 5

35

One line of code using jQuery:

$('td:nth-child(2)').hide();

// If your table has header(th), use this:
//$('td:nth-child(2),th:nth-child(2)').hide();

Source: Hide a Table Column with a Single line of jQuery code

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

3 Comments

Thanks! This selector also works great when you are trying to hide certain columns for a print style sheet.
After fiddling about with <col> tags, which don't appear to work in chrome, this worked perfectly
Keep in mind this will only work as expected for tables with an equal number of cells per row. If, for instance, you have some cells with colspan="2" and fewer cells in the remainder of that row, then nth-child will select (and in this case hide) cells from the wrong "column". For this reason, make sure you keep a note/comment of your column-hiding mechanism next to wherever the table will be edited, so that future editors don't break the layout.
22

No, that's pretty much it. In theory you could use visibility: collapse on some <col>​s to do it, but browser support isn't all there.

To improve what you've got slightly, you could use table-layout: fixed on the <table> to allow the browser to use the simpler, faster and more predictable fixed-table-layout algorithm. You could also drop the .show rules as when a cell isn't made display: none by a .hide rule it will automatically be display: table-cell. Allowing table display to revert to default rather than setting it explicitly avoids problems in IE<8, where the table display values are not supported.

4 Comments

+1 for mentioning table-layout:fixed. I've found that to be a huge help when displaying table formatted data.
Thanks for bringing up the table-layout:fixed, but it didn't work in my case. Dealing with a monster table with fluctuating column sizes which ends up needing table-layout:auto to look presentable.
That's a shame. Fixed tables can be much smoother than auto. (fixed doesn't necessarily mean all the columns have to have a fixed width, just that the widths don't depend on the amount of content in each cell.)
15

if you're looking for a simple column hide you can use the :nth-child selector as well.

#tableid tr td:nth-child(3),
#tableid tr th:nth-child(3) {
    display: none;
}

I use this with the @media tag sometimes to condense wider tables when the screen is too narrow.

Comments

1

I don't think there is anything you can do to avoid what you are already doing, however, if you are building the table on the client with javascript, you can always add the style rules dynamically, so you can allow for any number of columns without cluttering up your css file with all those rules. See http://www.hunlock.com/blogs/Totally_Pwn_CSS_with_Javascript if you don't know how to do this.

Edit: For your "sticky" toggle, you should just append class names rather than replacing them. For instance, you can give it a class name of "hide2 hide3" etc. I don't think you really need the "show" classes, since that would be the default. Libraries like jQuery make this easy, but in the absence, a function like this might help:

var modifyClassName = function (elem, add, string) {
var s = (elem.className) ? elem.className : "";
var a = s.split(" ");
if (add) {
  for (var i=0; i<a.length; i++) {
      if (a[i] == string) {
          return;
          }
      }
  s += " " + string;
  }
else {
    s = "";
    for (var i=0; i<a.length; i++) {
        if (a[i] != string)
            s += a[i] + " "; 
        }
    }
elem.className = s;
}

1 Comment

Your edit helped me a lot! The sticky toggle is really easy now that I saw this!
0

I use the dblclick of jquery to hide rows and columns of table on double click of mouse.

  • Double click on table data (TD) hide the line.
  • Double click on table header (TH) hide the column.

$('table td').dblclick(function(){
    $(this).parent().hide();
});
$('table th').dblclick(function(){
    $('th:nth-child('+($(this).index()+1)+')').hide();
    $('td:nth-child('+($(this).index()+1)+')').hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<table>
<tr><th>COL1</th><th>COL2</th><th>COL3</th></tr>
<tr><td>one</td><td>one</td><td>one</td></tr>
<tr><td>two</td><td>one</td><td>one</td></tr>
<tr><td>three</td><td>one</td><td>one</td></tr>
</table>

The smaller they are, the better they are.

Comments

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.