javascripthtmlhtml-tablewidthoffsetwidth

Table Column Width Matching


UPDATE: Solution found

UPDATE: No proposed answers. No solution found on my end. Anybody?

I am using javascript to match the width of columns in two seperate tables (using this to create a scrollable, sticky header table. If the data is all visible (no overflow), the method works fine. If the tables do overflow, however, the table columns do not align. I have a debugging stream that shows the offsetWidths are still returning the same numbers. Any ideas on why this is happening?

Main HTML:

<link rel="stylesheet" type="text/css" href="CSS/APTEIT.css"/>
<script type="text/javascript" src="Utilities/Javascript/Utilities.js"></script>
<script type="text/javascript" src="Utilities/Javascript/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    HtmlLoggerControlInstance.getInstance().setLevel("debug",HtmlLogger.ALL);
    syncColumnWidths("headers",null,"data",null);
});
</script>
<html>
    <head>
        <title>APTEIT</title>
    </head>
    <body>
        <!--#include file="Utilities/Debug.aspx"-->
        <img src="Images/logo.png" />
        <div id="headersDiv">
            <table class="tbl" id="headers">
                <tr>
                    <td>head1</td>
                    <td>head2reallyreallylong</td>
                    <td>hd3</td>
                    <td>4</td>
                </tr>
            </table>
        </div>
        <div id="dataDiv" onscroll="syncScrolling('dataDiv','headersDiv');">
            <table class="tbl" id="data">
            <tr>
                <td>alsdja;lksdjaljkdf</td>
                <td>kdki</td>
                <td>k39</td>
                <td>lsjdl</td>
            </tr>
            <tr>
                <td>alsdja;lksdjaljkdf</td>
                <td>kdki</td>
                <td>k39</td>
                <td>lsjdl</td>
            </tr><tr>
                <td>alsdja;lksdjaljkdasdfaf</td>
                <td>kdki</td>
                <td>k39</td>
                <td>lsjdl</td>
            </tr><tr>
                <td>alsdja;lksdjaljkdf</td>
                <td>kdki</td>
                <td>k39</td>
                <td>lsjdl</td>
            </tr><tr>
                <td>alsdja;lksdjaljkdfs</td>
                <td>kdki</td>
                <td>k39</td>
                <td>lsjdl</td>
            </tr><tr>
                <td>alsdf</td>
                <td>kdki</td>
                <td>k39</td>
                <td>lsjdl</td>
            </tr>
            </table>
        </div>
    </body>
</html>

Javascript Method:

/*
Syncs column sizes between two tables. 

@param string table1 : First table to sync
@param int table1HeadRow : Row to use as column width sync for table1 (if null, uses first row)
@param string table2 : Second table to sync
@param int table2HeadRow : Row to use as column width sync for table2 (if null, uses first row)
*/
function syncColumnWidths(table1, table1HeadRow ,table2, table2HeadRow){
    UtilLogger.log(HtmlLogger.INFO,"-Syncing Column Widths-")
    if((typeof table1 == "string" ||table1.constructor == String) && (typeof table2 == "string" ||table2.constructor == String)
        && (typeof table1HeadRow == "number" || table1HeadRow == null) && (typeof table2HeadRow == "number" || table1HeadRow == null)){
        tableOne = document.getElementById(table1);
        tableTwo = document.getElementById(table2);

        //Set row to check and get row
        if(table1HeadRow == null){
            t1Start = 0;
        }
        else{
            t1Start = table1HeadRow;
        }
        if(table2HeadRow == null){
            t2Start = 0;
        }
        else{
            t2Start = table2HeadRow;
        }
        t1Row = tableOne.rows[t1Start];
        t2Row = tableTwo.rows[t2Start];

        //Get end number
        if(t1Row.cells.length < t2Row.cells.length){
            tEnd = t1Row.cells.length;
        }
        else{
            tEnd = t2Row.cells.length;
        }

        //Sync widths
        for(i = 0; i < tEnd; i++){
            UtilLogger.log(HtmlLogger.CONFIG,"syncColumnWidths:t1 width:"+t1Row.cells[i].offsetWidth+"   t2 width:"+t2Row.cells[i].offsetWidth);
            if(t1Row.cells[i].offsetWidth > t2Row.cells[i].offsetWidth){
                t2Row.cells[i].style.width = t1Row.cells[i].offsetWidth+"px";
                t1Row.cells[i].style.width = t1Row.cells[i].offsetWidth+"px";
                UtilLogger.log(HtmlLogger.FINE,"syncColumnWidths:setting t2 width to t1");
            }
            else{
                t1Row.cells[i].style.width = t2Row.cells[i].offsetWidth+"px";
                t2Row.cells[i].style.width = t2Row.cells[i].offsetWidth+"px";
                UtilLogger.log(HtmlLogger.FINE,"syncColumnWidths:setting t1 width to t2");
            }
        }

    }
    else{
        alert("syncColumnWidths takes parameters (string, int|null, string, int|null)");
    }
    UtilLogger.log(HtmlLogger.INFO,"-Syncing Column Widths Complete-");
}

CSS:

.tbl{
border-collapse:collapse;
}
.tbl tr td{
border-width:1px;
border-color:black;
border-style:solid;
}

#headersDiv{
max-width:100px;
overflow:hidden;
}

#dataDiv{
max-width:100px;
overflow:auto;
}

Debug prints:

-Syncing Column Widths Complete-
syncColumnwidths:t1 style width:28px t2 style width:28px
syncColumnWidths:setting t1 width to t2
syncColumnWidths:t1 width:12 t2 width:28
syncColumnwidths:t1 style width:27px t2 style width:27px
syncColumnWidths:setting t1 width to t2
syncColumnWidths:t1 width:26 t2 width:27
syncColumnwidths:t1 style width:129px t2 style width:129px
syncColumnWidths:setting t2 width to t1
syncColumnWidths:t1 width:129 t2 width:30
syncColumnwidths:t1 style width:137px t2 style width:137px
syncColumnWidths:setting t1 width to t2
syncColumnWidths:t1 width:40 t2 width:137
-Syncing Column Widths-
-Default Page Loaded-
-Default Page Loading-

Solution

  • Table-layout for both tables needs to be fixed in order to adjust the size of the cells and have it affect the table as a whole. By default, this is auto, and the table adjusts to the size of it's container/contents of its cells.