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?
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>
This question is related to
javascript
html
css
html-table
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;
}
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
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.
Source: Stackoverflow.com