How can I get the col's id of a td (not column number of a td)?
Asked Answered
B

3

8

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?)

Bunker answered 28/8, 2011 at 15:10 Comment(0)
C
1

<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.

Canto answered 28/8, 2011 at 16:26 Comment(6)
in fact, I'm trying to create a html table builder and I face this problem when user want to merge td 1 and 2 and 4 (or lasso select these tds) and I not only use background color but also use some custom attribute of col tag to define data structure. after all 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. (Td4 you show style of a col, who is that col?)Bunker
exactly, the browser knows what style to apply depending on the column, so why not make a style attribute specific for each column (other than the color), that does not trigger any visual change in your case, e.g. any from these that would contain a number and would be OKCanto
you accepted my answer (thanks!) For completeness-sake, may I ask what css attribute you have chosen?Canto
I add a custom attribute (e.g. colName) to style attributes of col tag and td inhrited this attribute so I know the col of each td by currentStyle in IE and getComputedStyle() in firefox.Bunker
I'll keep thinking of a better solution though: it does not seem to work in Chrome, custom attributes are often ignored, see hereCanto
yes, and the bigger problem is that there isn't correct currentStyle or anything about dynamically generated htaml tags. finally I add an attribute to the td4(td below a rowspan) after every vertical merge that shows it stands for 2 tds(or 2 columns).Bunker
S
1

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/

Shoemaker answered 28/8, 2011 at 15:22 Comment(2)
I have not problem with colspan, my problem is rowspan. if you consider my sample and check it in the link that you shared, it will say col0 for td 4 so it's wrong.Bunker
wow it's a lot more complicated than i thought to simply find the col for a corresponding td!Disinterested
C
1

<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.

Canto answered 28/8, 2011 at 16:26 Comment(6)
in fact, I'm trying to create a html table builder and I face this problem when user want to merge td 1 and 2 and 4 (or lasso select these tds) and I not only use background color but also use some custom attribute of col tag to define data structure. after all 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. (Td4 you show style of a col, who is that col?)Bunker
exactly, the browser knows what style to apply depending on the column, so why not make a style attribute specific for each column (other than the color), that does not trigger any visual change in your case, e.g. any from these that would contain a number and would be OKCanto
you accepted my answer (thanks!) For completeness-sake, may I ask what css attribute you have chosen?Canto
I add a custom attribute (e.g. colName) to style attributes of col tag and td inhrited this attribute so I know the col of each td by currentStyle in IE and getComputedStyle() in firefox.Bunker
I'll keep thinking of a better solution though: it does not seem to work in Chrome, custom attributes are often ignored, see hereCanto
yes, and the bigger problem is that there isn't correct currentStyle or anything about dynamically generated htaml tags. finally I add an attribute to the td4(td below a rowspan) after every vertical merge that shows it stands for 2 tds(or 2 columns).Bunker
S
0

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
    }
});
Secondrate answered 5/2, 2016 at 13:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.