ooze1992
ooze1992

Reputation: 25

jquery- hide columns in table where there are rowspans

I need to hide columns in a table but there are rowspans involved and it messes up the function. I appreciate any help. Below is the link for my code:

http://jsfiddle.net/SEwVP/73/

Here is the function (in the example, I'm trying to hide the column 3):

$('#toggle').click(function(){
var lastChilds = $('#tbl td:nth-child(3)');
lastChilds.each(function(i){
    var rowSpan = $(this).attr('rowspan');
    if(rowSpan !== undefined){
      lastChilds.splice(i+1, rowSpan-1);

    }
     $(this).toggle();

  });
    });

Upvotes: 0

Views: 530

Answers (1)

Terry Young
Terry Young

Reputation: 3531

I was initially intrigued by this because it seems something trivial but in fact quite mind-boggling. I've tried various approaches to workaround the rowspans to toggle the right cells. I initially answered yesterday but I deleted it soon enough because I know it failed miserably.

When we say '3rd column', it doesn't necessarily mean the <td> would be the third child of the row, because in terms of how HTML and rowspans work.

Then comes the epiphany: tables are perfect grids, so for example, all cells that are "visually perceived" as the 3rd column all share one thing in common, they all share the same offset left.

This is the closest I could get so far, and this perhaps a somewhat radical approach that is based on one important assumption: that no colspans are involved in the entire table. (Or else, everything turns into poop)

This demo allows you to toggle any column you want, hopefully with any rowspan complexity.

(If there is a more elegant solution I'd certainly want to know myself)

DEMO: http://jsfiddle.net/terryyounghk/nGEHW/

$(document).ready(function () {

    var $table = $('#tbl');

    (function scanTable($table) {

        var $rows = $table.find('tr'),
            $cells = $table.find('td'),
            map = {};

        // the first row will always have all n columns of cells,
        // so this is the safest row to collect each columns offset().left
        $rows.first().find('td').each(function (i, cell) {
            var $cell = $(cell),
                left = Math.floor($cell.offset().left);
            map[left] = i+1;
            $cell.attr({
                'data-nth-col': i+1
            });
        });

        // now for the rest of the rows, 
        $rows.not(':first').each(function (i, row) {
            var $row = $(row),
                $cells = $row.find('td');

            $cells.each(function (j, cell) {
                var $cell = $(cell),
                    left = Math.floor($cell.offset().left);
                $cell.attr({
                    'data-nth-col': map[left]
                });
            });
        });
    })($table); // scan the entire table ONCE. 
                // We don't want to do this on every toggle


    $('button[name=toggle]').on('click', function () {
        var n = +$(this).val();
        $table.find('td[data-nth-col='+n+']').toggle();
    });

});

Upvotes: 3

Related Questions