views:

11601

answers:

8

I have an HTML table with several columns and I need to implement a column chooser using jquery. When a user clicks on a checkbox I want to hide/show the corresponding column in the table. I would like to do this without attaching a class to every td in the table, is there a way to select an entire column using jquery? Below is an example of the HTML.

<table>
    <thead>
     <tr><th class="col1">Header 1</th><th class="col2">Header 2</th><th class="col3">Header 3</th></tr>
    </thead>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
</table>

<form>
    <input type="checkbox" name="col1" checked="checked" /> Hide/Show Column 1 <br />
    <input type="checkbox" name="col2" checked="checked" /> Hide/Show Column 2 <br />
    <input type="checkbox" name="col3" checked="checked" /> Hide/Show Column 3 <br />
</form>
+3  A: 

you could use colgroups:

<table>
    <colgroup>
       <col class="visible_class"/>
       <col class="visible_class"/>
       <col class="invisible_class"/>  
    </colgroup>
    <thead>
        <tr><th class="col1">Header 1</th><th class="col2">Header 2</th><th class="col3">Header 3</th></tr>
    </thead>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
    <tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
</table>

your script then could change just the desire <col> class.

Luis Melgratti
I seem to remember colgroup not having cross browser support is that no longer true?
Brian Fisher
Maybe. i'm using this method for hilight columns, (firefox, safari, chrome works fine) never tried it in IE.
Luis Melgratti
@Brian - correct IE has issues with colgroups.
scunliffe
@Brian - IE8 does not work and IE8 with IE7 enabled seems to be working.
Nordes
+3  A: 

The following should do it:

$("input[type='checkbox']").click(function() {
    var index = $(this).attr('name').substr(2);
    $('table tr').each(function() { 
        $('td:eq(' + index + ')',this).toggle();
    });
});

This is untested code, but the principle is that you choose the table cell in each row that corresponds to the chosen index extracted from the checkbox name. You could of course limit the selectors with a class or an ID.

Eran Galperin
+1  A: 

The following is building on Eran's code, with a few minor changes. Tested it and it seems to work fine on Firefox 3, IE7.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
                "http://www.w3.org/TR/html4/loose.dtd"&gt;
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"&gt;&lt;/script&gt;
</head>
<script>
$(document).ready(function() {
    $('input[type="checkbox"]').click(function() {
        var index = $(this).attr('name').substr(3);
        index--;
        $('table tr').each(function() { 
            $('td:eq(' + index + ')',this).toggle();
        });
        $('th.' + $(this).attr('name')).toggle();
    });
});
</script>
<body>
<table>
<thead>
    <tr>
        <th class="col1">Header 1</th>
        <th class="col2">Header 2</th>
        <th class="col3">Header 3</th>
    </tr>
</thead>
<tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
<tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
<tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
<tr><td>Column1</td><td>Column2</td><td>Column3</td></tr>
</table>

<form>
    <input type="checkbox" name="col1" checked="checked" /> Hide/Show Column 1 <br />
    <input type="checkbox" name="col2" checked="checked" /> Hide/Show Column 2 <br />
    <input type="checkbox" name="col3" checked="checked" /> Hide/Show Column 3 <br />
</form>
</body>
</html>
Paolo Bergantino
+8  A: 

I would like to do this without attaching a class to every td

Personally, I would go with the the class-on-each-td/th/col approach. Then you can switch columns on and off using a single write to className on the container, assuming style rules like:

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

This is going to be faster than any JS loop approach; for really long tables it can make a significant difference to responsiveness.

If you can get away with not supporting IE6, you could use adjacency selectors to avoid having to add the class attributes to tds. Or alternatively, if your concern is making the markup cleaner, you could add them from JavaScript automatically in an initialisation step.

bobince
Thanks for the advice, I had wanted to keep the HTML cleaner, but performance definitely became an issue as the table size approached 100 rows. This solution, provided a 2-5x performance improvement.
Brian Fisher
A: 

I have a related question. I have a large table, and have classes on the TD's I want to toggle. This works fine in IE8, FF, Chrome, etc. However in IE7 and IE6, the class switching on the table doesn't seem to take effect. If I go into the IE developer toolbar, and manually turn the CSS class off and on, it then works, but I have to do that each time.

I found one place suggesting to toggle the visibility and display properties of the table, which is why you'll see the table flash when you click Show 1.

Here is a test page I set up: http://www.athletic.net/Demo/Josh/Test/ClassSwitching.htm

Any ideas?

Brian, the styles and jquery will work for what you are wanting (that is, if you don't need IE6 and 7 - unless someone is aware of a solution).

Thanks!

jobow
I'm not really sure what you are looking for here, but I'd suggest you ask a new question. People are more likely to provide answers to questions. Sorry I can't be of more help.
Brian Fisher
A: 

Sorry that I have to spam like this, but I cannot comment due to my rep.

Can someone please provide and example for the accepted answer. Thank you!

blank3
A: 

Hi

I hope the folowing site would help:

http://www.fiendish.demon.co.uk/html/javascript/hidetablecols.html

gabriel66
A: 

I implemented this solution using jQuery, and it worked perfectly for me:

http://www.devcurry.com/2009/07/hide-table-column-with-single-line-of.html

Aaron