Question

In this example:

<table border="1">
    <col id="col0" style="background-color: #FFFF00"/>
    <col id="col1" style="background-color: #FF0000"/>
    <tr><td rowspan="2">1</td><td>2</td><td>3</td></tr>
    <tr><td>4</td><td>5</td><td>6</td></tr>
    <tr><td>7</td><td>8</td><td>9</td></tr>
</table>

How can I get the col’s id of td 4?

If I get it's column number with this jquery command:

var cn = $(this).parent().children().index($(this));

cn will be 0, but it’s style shows that it belongs to col1 and I need a commend like td.col.id

when I set rowspan="2" at the td above a td (eg. td 4) this td's column number will be different from it's order of col(or colgroup) and I set background color to show it.

Edit: I believe there is a way to solve this problem, because when td knows about it's col(colgroup) there must be a way to ask it from td at dom tree. (Td4 you show style of a specific col, who is that col?)

Was it helpful?

Solution

<td>4</td> is the first child of the second tablerow, so you should indeed get column 0.

instead of elaborating a complex function that detects rowspans etc, it might be advisable to just assign ids to each table cell, or create another custom solution for your table. e.g. you know in advance how many columns each specific row has? Or you use the actual background color or a 'secret' css attribute as identification.

ps. my useless fiddle until I understood the actual problem.

edit (read discussion below): as described here, you are not supposed to create custom css attributes; these are often ignored by the browser (and not available via .attr()). Sahar's solution was to mark each element affected by a merging of rows to remember for how many columns the element should count.

OTHER TIPS

You first have to calculate the column number of the td itself.

This is done by counting the number of tds before our td; taking colspan attributes into account:

function getElementColumn(td)
{
    var tr = td.parentNode;
    var col = 0;
    for (var i = 0, l = tr.childNodes.length; i < l; ++i) {

        var td2 = tr.childNodes[i];

        if (td2.nodeType != 1) continue;
        if (td2.nodeName.toLowerCase() != 'td' && td2.nodeName.toLowerCase() != 'th') continue;

        if (td2 === td) {
            return col;
        }
        var colspan = +td2.getAttribute('colspan') || 1;
        col += colspan;
    }
}

Then you can iterate the col elements and return the one matching the column number.

We first have to find the colgroup element. Then it's similar to computing the column number of the td:

function getCol(table, colNumber)
{
    var col = 0;
    var cg;
    for (var i = 0, l = table.childNodes.length; i < l; ++i) {
        var elem = table.childNodes[i];
        if (elem.nodeType != 1) continue;
        if (elem.nodeName.toLowerCase() != 'colgroup') continue;
        cg = elem;
        break;
    }
    if (!cg) return;

    for (var i = 0, l = cg.childNodes.length; i < l; ++i) {
        var elem = cg.childNodes[i];
        console.log(elem);

        if (elem.nodeType != 1) continue;
        if (elem.nodeName.toLowerCase() != 'col') continue;

        if (col == colNumber) return elem;

        var colspan = +elem.getAttribute('span') || 1;
        col += colspan;
    }
}

With these two function you should be able to do this:

var id = getCol(table, getElementColumn(td)).id;

http://jsfiddle.net/wHyUQ/1/

jQuery version

function getElementColumn(td)
{
    var col = 0;
    $(td).prevAll('td, th').each(function() {
        col += +$(this).attr('colspan') || 1;
    });
    return col;
}

function getCol(table, colNumber)
{
    var col = 0, elem;
    $(table).find('> colgroup > col').each(function() {
        if (colNumber == col) {
            elem = this;
            return false;
        }
        col += +$(this).attr('span') || 1;
    });
    return elem;
}

http://jsfiddle.net/wHyUQ/2/

Resolving rowspans or colspans would be incredibly complex. I suggest you to iterate over all col-elements, set a width of 0px to them and check if this affected the width of your td or th element. If so, this is the related column.

Example:

// Your table elements
$table = $('yourTableSelector');
$cell = $('td or th');
$cols = $table.find('colgroup > col');

// determine the related col
// by setting a width of 0px. the 
// resulting width on the element should be negative or zero.
// this is hacky, but the other way would
// be to resolve rowspans and colspans, which
// would be incredibly complex.
var $relatedColumn = $();
$cols.each(function(){
    var $col = $(this);
    var prevStyle = $col.attr('style') === 'string' ? $col.attr('style'): '';
    $col.css('width', '0px');
    if($cell.width() <= 0){
        $relatedColumn = $col;
        $col.attr('style', prevStyle); // reset
        return false;
    } else {
        $col.attr('style', prevStyle); // reset
    }
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top