0

I need to provide users with the ability to hide/show table columns. Using previous examples with my own adjustments i have used checkboxes to hide/show columns, but now need to remove form elements.

I'm very new to jquery/javascript so hoping someone can help with info on now how to
1. Hide some columns on load (based on trigger in code)
2. Swap images when column is toggled to give users visual feedback as to which columns are shown/hidden.

I have a fiddle at http://jsfiddle.net/IllusionVK/DqQFP/14/ which has the following code in it:

Previously used following code

$("input:checkbox:not(:checked)").each(function() {
var column = "table ." + $(this).attr("name");
$(column).hide();
});

$("input:checkbox").click(function(){
var column = "table ." + $(this).attr("name");
$(column).toggle();
});
});

but had to remove form elements (checkboxes), and am now trying to use img tag in place of checkbox:

$('img').click(function(){
var column = $(this).attr('id');
$('td:nth-child('+ column +')').toggle();
});

I'm hoping that the final code will be useful for all to hide/show columns without needing to add any code to the actual tables and is using nth-child dynamically.

Any help would be very much appreciated!! Cheers, Charlie.

Sources of help so far:
http://www.devcurry.com/2009/07/hide-table-column-with-single-line-of.html
Uses nth-child, BUT is hardcoded, and designed for only one column show/hide

hide table columns automatically by checking a checkbox with jQuery
But requires that table is overburdened with extra classes=bad for me, use checkboxes=also bad

Community
  • 1
  • 1
IllusionVK
  • 83
  • 1
  • 6

2 Answers2

0

If you use index() you should be able to dynamically show/hide columns if you make a convention that your text of your tags match the table header tags.

$('span').click(function() {
    var t = $.trim($(this).text());
    var i = $(".headercell td:contains(" + t + ")").index() + 1;
    $('td:nth-child(' + i+ ')').toggle();
});

Updated jsfiddle.

side note, a img element can't have text <img>text</img>, so I adjusted the list to use a span tag instead.

update If you want to easily toggle the legend items you could do something like this..

<div class="legend">
    <div>Name</div>
    <div>Sex</div>
    <div>Age</div>
</div>

And the following css:

.legend div.unchecked
{
    background-image:url(http://jquery.bassistance.de/validate/demo/images/unchecked.gif);
}
.legend div
{
    background-repeat:no-repeat;
    background-image:url(http://jquery.bassistance.de/validate/demo/images/checked.gif);
    cursor:pointer;
    background-position:left center;
    padding-left:20px;
}

And your jquery could toggle the class to change the background-image

$('div.legend div').click(function() {
    $(this).toggleClass("unchecked");
    var t = $.trim($(this).text());
    var i = $(".headercell td:contains(" + t + ")").index() + 1;
    $('td:nth-child(' + i + ')').toggle();
});

If you want to hide columns on page load simply add a uncheck class to the legend div you want to uncheck.

<div class="legend">
    <div>Name</div>
    <div>Sex</div>
    <div class="uncheckThis">Age</div>
</div>

Then running this script will trigger which ones to uncheck.

$('div.legend div.uncheckThis').click();

Example on jsfiddle.

Mark Coleman
  • 40,542
  • 9
  • 81
  • 101
  • Cheers for the reply mark, as I'm a real novice in js, to my untrained eye, looks like you've helped to tidy my code up to be more efficient? - thanks for this.. Any hints on how to do the image swapping and auto hide columns on load ? – IllusionVK Feb 28 '11 at 14:24
  • The easiest way to change the image would be to extract out your img into css classes and simply toggle the class on the clicked element. See update for an example... – Mark Coleman Feb 28 '11 at 14:51
0

I was guessing that classes for the controls would be okay. So I wrapped the "checkboxes" in a instead of the you had it in... IE doesn't like tables without a tbody, tr or td inside. So this is what I did (demo):

HTML (just the updated part)

<div id="tableControl">
    <div class="checked">Name</div>
    <div class="checked">Sex</div>
    <div>Age</div>
</div>

CSS (updated portions)

#tableControl div  {
    cursor: pointer;
    background:url(http://jquery.bassistance.de/validate/demo/images/unchecked.gif) no-repeat;
    padding-left:  20px;
}
#tableControl div.checked {
    background:url(http://jquery.bassistance.de/validate/demo/images/checked.gif) no-repeat;
}

Script

var hideColumn = function(el) {
    var $el = $(el),
        name = $.trim($el.text()),
        checked = !$el.is('.checked'),
        column = $('.headercell td:contains(' + name + ')').index() + 1;
    $('td:nth-child(' + column + ')').toggle(checked);
    $el.toggleClass('checked', checked);
};

$('#tableControl div')
    .each(function() {
        if (!$(this).is('.checked')) {
            // add class so the script can remove it (on startup)
            $(this).addClass('checked');
            hideColumn(this);
        }
    }).click(function() {
        hideColumn(this);
    });
Mottie
  • 84,355
  • 30
  • 126
  • 241
  • Hi, Thanks so much for this (and sorry for the very delayed reply). Your solution is far beyond what my limited skills would been able to achieve!! The only thing i notice is that it also affects items with a similar class name, is there anyway to only affect the specified classes ? Cheers, Charlie. – IllusionVK Mar 20 '11 at 11:56
  • Yes, it can always be made more specific... I generalized the script because of the requirements you initially provided. So please provide the HTML with the specific classes. – Mottie Mar 20 '11 at 15:02