Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Table cellIndex and rowIndex with colspan/rowspan

I was using the answer provided in:

How can I find each table cell's "visual location" using jQuery?

But it doesn't seem to work in this case: http://jsfiddle.net/TRr6C/9/

Notice the 1,3 1,4 and 2,4 should be 1,4 1,5 and 2,5

Anyone see whats wrong?

Or is there any better solution to get the cellIndex and rowIndex from a table cell taking into consideration colspan and rowspan?

Here is the code:

function getCellLocation(cell) {

    var cols = cell.closest("tr").children("td").index(cell);
    var rows = cell.closest("tbody").children("tr").index(cell.closest("tr"));
    var coltemp = cols;
    var rowtemp = rows;

    cell.prevAll("td").each(function() {
        cols += ($(this).attr("colspan")) ? parseInt($(this).attr("colspan")) - 1 : 0;
    });

    cell.parent("tr").prevAll("tr").each(function() {
        //get row index for search cells
        var rowindex = cell.closest("tbody").children("tr").index($(this));
        // assign the row to a variable for later use
        var row = $(this);
        row.children("td").each(function() {
            // fetch all cells of this row
            var colindex = row.children("td").index($(this));
            //check if this cell comes before our cell
            if (cell.offset().left > $(this).offset().left) {
                // check if it has both rowspan and colspan, because the single ones are handled before
                var colspn = parseInt($(this).attr("colspan"));
                var rowspn = parseInt($(this).attr("rowspan"));
                if (colspn && rowspn) {
                    if(rowindex + rowspn > rows)
                    cols += colspn;                    
                }
            }

        });
    });

    return {
        rows: rows,
        cols: cols
    };
}
like image 656
Petah Avatar asked Nov 15 '12 22:11

Petah


People also ask

What is Rowspan and Colspan in Table tag?

The rowspan and colspan are <td> tag attributes. These are used to specify the number of rows or columns a cell should span. The rowspan attribute is for rows as well as the colspan attribute is for columns. These attributes have numeric values, for example, colspan=3 will span three columns.

Can we use Colspan and Rowspan together?

Of course, you can mix colspan and rowspan to get a range of various tables. Example 4-13 demonstrates a mix of column and row spanning.

Is Colspan horizontal or vertical?

The colspan attribute defines the number of columns a cell should span (or merge) horizontally. That is, you want to merge two or more Cells in a row into a single Cell.


Video Answer


1 Answers

My solution is in form of jQuery plugin since I can imagine more than one purpose of having this information. It can be used as in:

$("table tbody td").each(function(){ 
    $(this).text( $(this).cellPos().top +","+ $(this).cellPos().left );
});

The position is in form of { top: rows, left: cols }. On its first call, table is scanned and TD elements get data items with their cached position. (Cache can be rebuilt by calling with argument true). All further calls just return that cached value.

Hope this helps!

jsfiddle

Full source:

/*  cellPos jQuery plugin
    ---------------------
    Get visual position of cell in HTML table (or its block like thead).
    Return value is object with "top" and "left" properties set to row and column index of top-left cell corner.
    Example of use:
        $("#myTable tbody td").each(function(){ 
            $(this).text( $(this).cellPos().top +", "+ $(this).cellPos().left );
        });
*/
(function($){
    /* scan individual table and set "cellPos" data in the form { left: x-coord, top: y-coord } */
    function scanTable( $table ) {
        var m = [];
        $table.children( "tr" ).each( function( y, row ) {
            $( row ).children( "td, th" ).each( function( x, cell ) {
                var $cell = $( cell ),
                    cspan = $cell.attr( "colspan" ) | 0,
                    rspan = $cell.attr( "rowspan" ) | 0,
                    tx, ty;
                cspan = cspan ? cspan : 1;
                rspan = rspan ? rspan : 1;
                for( ; m[y] && m[y][x]; ++x );  //skip already occupied cells in current row
                for( tx = x; tx < x + cspan; ++tx ) {  //mark matrix elements occupied by current cell with true
                    for( ty = y; ty < y + rspan; ++ty ) {
                        if( !m[ty] ) {  //fill missing rows
                            m[ty] = [];
                        }
                        m[ty][tx] = true;
                    }
                }
                var pos = { top: y, left: x };
                $cell.data( "cellPos", pos );
            } );
        } );
    };

    /* plugin */
    $.fn.cellPos = function( rescan ) {
        var $cell = this.first(),
            pos = $cell.data( "cellPos" );
        if( !pos || rescan ) {
            var $table = $cell.closest( "table, thead, tbody, tfoot" );
            scanTable( $table );
        }
        pos = $cell.data( "cellPos" );
        return pos;
    }
})(jQuery);
like image 20
nrodic Avatar answered Oct 17 '22 21:10

nrodic