...

View Full Version : Syncing table column widths



StevenTNorris
03-20-2012, 05:57 PM
I am attempting to sync the column widths of two tables. Currently, I have a working method that uses the DOM to traverse each cell of a given row of two tables and set the style.width element to the largest offsetWidth of the the two cells. However, when the divs my tables are in are given an overflow: auto property, causing scrollbars, the widths no longer sync. They style.width elements are still being set (I'm using a debugging method to check the style.width elements for their values), but no sizes are changing. Ideas?

ASPX

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<%@language = "C#" inherits="APTEIT.Default"%>
<!--
Default.aspx
Author: Steven T. Norris Created: 2/28/2012
Last Updated: Updated By:
Default page of APTEIT
-->
<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>


CSS

/*
APTEIT.css
Author: Steven T. Norris Created: 2/28/2012
Updated By: Last Updated:
Copyright 2012

CSS stylesheet for default page of APTEIT
*/

/*Utilities Styles*/
.debug
{
display:block;
}
.LOG_INFO
{
color:blue;
}

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

#headersDiv
{
max-width:200px;
overflow:hidden;
}
#dataDiv
{
max-width:200px;
overflow:auto;
}
#headers
{
table-layout:fixed;
}
#data
{
table-layout:fixed;
}



Javascript

/*
Utilities.js
Author: Steven T. Norris Created: 3/2/2012
Updated By: Last Updated:
Copyright 2012

Utility functions
Logs to debug window if using Debug.aspx or a logger named 'debug' with the HtmlLoggerControlInstance
*/

/*
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");
UtilLogger.log(HtmlLogger.FINER,"syncColumnwidths:t1 style width:"+t1Row.cells[i].style.width+" t2 style width:"+t2Row.cells[i].style.width);
}
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");
UtilLogger.log(HtmlLogger.FINER,"syncColumnwidths:t1 style width:"+t1Row.cells[i].style.width+" t2 style width:"+t2Row.cells[i].style.width);

}
}

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

/*
Syncs scrolling of two divs. Meant to be part of onscroll event for primary div

@param string div1 : primary div. normally the div who's onclick event houses this method
@param string div2 : secondary div
*/
function syncScrolling(div1,div2){
if((typeof div1 == "string" || div1.constructor == String) && (typeof div2 == "string" || div2.cosntructor == String)){
$("#"+div2).scrollLeft($("#"+div1).scrollLeft());
}
else{
alert("syncScrolling takes parameters (string, string)");
}
}

webdev1958
03-21-2012, 03:00 AM
Ideas?

Without seeing your code, I can only take a guess.

Try changing the tables' table-layout style to fixed. By default, it is set to auto which means the table's width is determined by cell contents to a large extent. Setting it to fixed means the table width is determined by the width you set to it and any cells and the cell contents are not taken into account at all.

felgall
03-21-2012, 03:06 AM
Are you applying the same class to the various <col> or <colgroup> tags in both tables? That's the easiest way to make sure the same styles are applied to both tables.

StevenTNorris
03-21-2012, 02:28 PM
Without seeing your code, I can only take a guess.

Try changing the tables' table-layout style to fixed. By default, it is set to auto which means the table's width is determined by cell contents to a large extent. Setting it to fixed means the table width is determined by the width you set to it and any cells and the cell contents are not taken into account at all.

The fixed bit worked... sort of... The columns are the same size, but aren't resizing. I think I'll need to change the overall table width as well with this method. Also, now I'm having a scrolling issue. I'll edit my above post to include code, because I'm pretty sure figuring this one out without it is going to be hard. Thanks for you help, if you have any insight on the scrolling problem, please let me know. The columns appear aligned, but the scrolling gets off towards the end of the scrolling. I'm assuming because the scrollbar is taking up space. Is there a way to move the scrollbar to the outside a bit so it will not be taking up that space?

StevenTNorris
03-23-2012, 03:44 PM
UPDATE:

This is still not working correctly. I've added some to the javascript, changing the table-length as well as the cell lengths, but when there is overflow, they are still disaligned, even if overflow is set to hidden to avoid the scrollbars. If there is no overflow, they alilgn fine. What is going on??


/*
Utilities.js
Author: Steven T. Norris Created: 3/2/2012
Updated By: Last Updated:
Copyright 2012

Utility functions
Logs to debug window if using Debug.aspx or a logger named 'debug' with the HtmlLoggerControlInstance
*/

/*
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) {
var tableTotal = 0
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");
UtilLogger.log(HtmlLogger.FINER, "syncColumnwidths:t1 style width:" + t1Row.cells[i].style.width + " t2 style width:" + t2Row.cells[i].style.width);
tableTotal = tableTotal + t1Row.cells[i].offsetWidth
}
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");
UtilLogger.log(HtmlLogger.FINER,"syncColumnwidths:t1 style width:"+t1Row.cells[i].style.width+" t2 style width:"+t2Row.cells[i].style.width);
tableTotal = tableTotal + t2Row.cells[i].offsetWidth
}
}
UtilLogger.log(HtmlLogger.FINE, "setting main table width to " + tableTotal + "px");
tableOne.style.width = tableTotal + "px"
tableTwo.style.width = tableTotal + "px"

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

/*
Syncs scrolling of two divs. Meant to be part of onscroll event for primary div

@param string div1 : primary div. normally the div who's onclick event houses this method
@param string div2 : secondary div
*/
function syncScrolling(div1,div2){
if((typeof div1 == "string" || div1.constructor == String) && (typeof div2 == "string" || div2.cosntructor == String)){
$("#"+div2).scrollLeft($("#"+div1).scrollLeft());
}
else{
alert("syncScrolling takes parameters (string, string)");
}
}



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum