maketechnologies
asked on
Table headers that don't scroll, and stay the right size
I need to find a way to code up a table on a web page such that:
1. Each column has a header
2. The table data scrolls (can be big) but the headers remain visible at all times
3. The header for each column stays the same width as its column, and right on top of it, even with arbitrary data in the table
4. The width of the columns can not be known ahead of time - they change based on the data
We have a javascript solution at the moment, BUT it doesn't redraw the header fast enough to keep it from blinking and sliding all over the place, especially when there's a lot of data in the table.
1. Each column has a header
2. The table data scrolls (can be big) but the headers remain visible at all times
3. The header for each column stays the same width as its column, and right on top of it, even with arbitrary data in the table
4. The width of the columns can not be known ahead of time - they change based on the data
We have a javascript solution at the moment, BUT it doesn't redraw the header fast enough to keep it from blinking and sliding all over the place, especially when there's a lot of data in the table.
ASKER
Thanks for the answer.
However, it doesn't quite solve the problem.
When I take that code and put a long string in one of the data cells, it makes the cell wider, and the headers no longer line up.
I'm looking for a solution that will keep the headers the same size as the data columns, given arbitrary data.
Any takers?
However, it doesn't quite solve the problem.
When I take that code and put a long string in one of the data cells, it makes the cell wider, and the headers no longer line up.
I'm looking for a solution that will keep the headers the same size as the data columns, given arbitrary data.
Any takers?
Take a look at this, I don't think you'll find a solution to matching header with col widths...
<head>
<title>Scroll test</title>
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
<style>
#div1 {
overflow: hidden;
height: 250;
}
#div2 {
overflow: hidden;
width: 300;
}
#div3 {
overflow: auto;
width: 300;
height:200;
}
</style>
<script>
window.onload = function () {
addScrollSynchronization(d ocument.ge tElementBy Id("div2") , document.getElementById("d iv3"), "horizontal");
addScrollSynchronization(d ocument.ge tElementBy Id("div1") , document.getElementById("d iv3"), "vertical");
//addScrollSynchronization (document. getElement ById("div4 "), document.getElementById("d iv1"), "both");
};
// This is a function that returns a function that is used
// in the event listener
function getOnScrollFunction(oEleme nt) {
return function () {
if (oElement._scrollSyncDirec tion == "horizontal" || oElement._scrollSyncDirect ion == "both")
oElement.scrollLeft = event.srcElement.scrollLef t;
if (oElement._scrollSyncDirec tion == "vertical" || oElement._scrollSyncDirect ion == "both")
oElement.scrollTop = event.srcElement.scrollTop ;
};
}
// This function adds scroll syncronization for the fromElement to the toElement
// this means that the fromElement will be updated when the toElement is scrolled
function addScrollSynchronization(f romElement , toElement, direction) {
removeScrollSynchronizatio n(fromElem ent);
fromElement._syncScroll = getOnScrollFunction(fromEl ement);
fromElement._scrollSyncDir ection = direction;
fromElement._syncTo = toElement;
toElement.attachEvent("ons croll", fromElement._syncScroll);
}
// removes the scroll synchronization for an element
function removeScrollSynchronizatio n(fromElem ent) {
if (fromElement._syncTo != null)
fromElement._syncTo.detach Event("ons croll", fromElement._syncScroll);
fromElement._syncTo = null;;
fromElement._syncScroll = null;
fromElement._scrollSyncDir ection = null;
}
</script>
</head>
<body leftmargin=15px>
<table border=0 cellpadding=0 cellspacing=0><tr><td valign=top>
<div id=div1>
<table border=0 cellpadding=8 cellspacing=0 style="border-color:white" >
<tr>
<td height=60 bgcolor=#838C93 bgcolor=#838C93 align=right></td>
</tr>
<tr>
<td nowrap height=70px bgcolor=#838C93 width=110><b>Row 1</td>
</tr>
<tr>
<td nowrap height=70px bgcolor=#838C93 width=110><b>Row 2</td>
</tr>
<tr>
<td nowrap height=70px bgcolor=#838C93 width=110><b>Row 3</td>
</tr>
<tr>
<td nowrap bgcolor=#838C93 height=70px width=110><b>Row 4</td>
</tr>
</table>
</div>
</td><td valign=top>
<DIV id=div2 name=div2>
<table border=0 cellpadding=8 cellspacing=0>
<tr>
<td nowrap height=60 width=110 align=center bgcolor=#838C93><font color=white face="Arial" style="font-size:12pt"><b> Col 1</td>
<td nowrap height=60 width=110 align=center bgcolor=#838C93><font color=white face="Arial" style="font-size:12pt"><b> Col 2</td>
<td nowrap height=60 width=110 align=center bgcolor=#838C93><font color=white face="Arial" style="font-size:12pt"><b> Col 3</td>
<td nowrap height=60 width=110 align=center bgcolor=#838C93><font color=white face="Arial" style="font-size:12pt"><b> Col 4</td>
<td nowrap height=60 width=20 align=center bgcolor=#838C93><font color=white face="Arial" style="font-size:12pt"></t d>
</tr>
</table>
</div>
<div id=div3 name=div3>
<table border=1 cellpadding=8 cellspacing=0>
<tr>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 1 Col 1
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 1 Col 2
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 1 Col 3
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 1 Col 4
</td>
</tr>
<tr>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 2 Col 1
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 2 Col 2
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 2 Col 3
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 2 Col 4
</td>
</tr>
<tr>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 3 Col 1
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 3 Col 2
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 3 Col 3
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 3 Col 4
</td>
</tr>
<tr>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 4 Col 1
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 4 Col 2
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 4 Col 3
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F FFFFF; border-top-width:2px; border-top-style:solid" height=70px width=110>
Row 4 Col 4
</td>
</tr>
</table>
</div>
</td>
</tr>
</table>
</body>
</html>
<head>
<title>Scroll test</title>
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
<style>
#div1 {
overflow: hidden;
height: 250;
}
#div2 {
overflow: hidden;
width: 300;
}
#div3 {
overflow: auto;
width: 300;
height:200;
}
</style>
<script>
window.onload = function () {
addScrollSynchronization(d
addScrollSynchronization(d
//addScrollSynchronization
};
// This is a function that returns a function that is used
// in the event listener
function getOnScrollFunction(oEleme
return function () {
if (oElement._scrollSyncDirec
oElement.scrollLeft = event.srcElement.scrollLef
if (oElement._scrollSyncDirec
oElement.scrollTop = event.srcElement.scrollTop
};
}
// This function adds scroll syncronization for the fromElement to the toElement
// this means that the fromElement will be updated when the toElement is scrolled
function addScrollSynchronization(f
removeScrollSynchronizatio
fromElement._syncScroll = getOnScrollFunction(fromEl
fromElement._scrollSyncDir
fromElement._syncTo = toElement;
toElement.attachEvent("ons
}
// removes the scroll synchronization for an element
function removeScrollSynchronizatio
if (fromElement._syncTo != null)
fromElement._syncTo.detach
fromElement._syncTo = null;;
fromElement._syncScroll = null;
fromElement._scrollSyncDir
}
</script>
</head>
<body leftmargin=15px>
<table border=0 cellpadding=0 cellspacing=0><tr><td valign=top>
<div id=div1>
<table border=0 cellpadding=8 cellspacing=0 style="border-color:white"
<tr>
<td height=60 bgcolor=#838C93 bgcolor=#838C93 align=right></td>
</tr>
<tr>
<td nowrap height=70px bgcolor=#838C93 width=110><b>Row 1</td>
</tr>
<tr>
<td nowrap height=70px bgcolor=#838C93 width=110><b>Row 2</td>
</tr>
<tr>
<td nowrap height=70px bgcolor=#838C93 width=110><b>Row 3</td>
</tr>
<tr>
<td nowrap bgcolor=#838C93 height=70px width=110><b>Row 4</td>
</tr>
</table>
</div>
</td><td valign=top>
<DIV id=div2 name=div2>
<table border=0 cellpadding=8 cellspacing=0>
<tr>
<td nowrap height=60 width=110 align=center bgcolor=#838C93><font color=white face="Arial" style="font-size:12pt"><b>
<td nowrap height=60 width=110 align=center bgcolor=#838C93><font color=white face="Arial" style="font-size:12pt"><b>
<td nowrap height=60 width=110 align=center bgcolor=#838C93><font color=white face="Arial" style="font-size:12pt"><b>
<td nowrap height=60 width=110 align=center bgcolor=#838C93><font color=white face="Arial" style="font-size:12pt"><b>
<td nowrap height=60 width=20 align=center bgcolor=#838C93><font color=white face="Arial" style="font-size:12pt"></t
</tr>
</table>
</div>
<div id=div3 name=div3>
<table border=1 cellpadding=8 cellspacing=0>
<tr>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 1 Col 1
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 1 Col 2
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 1 Col 3
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 1 Col 4
</td>
</tr>
<tr>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 2 Col 1
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 2 Col 2
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 2 Col 3
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 2 Col 4
</td>
</tr>
<tr>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 3 Col 1
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 3 Col 2
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 3 Col 3
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 3 Col 4
</td>
</tr>
<tr>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 4 Col 1
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 4 Col 2
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 4 Col 3
</td>
<td nowrap class=BACK6 bgcolor=#CFD2D5 style="border-top-color:#F
Row 4 Col 4
</td>
</tr>
</table>
</div>
</td>
</tr>
</table>
</body>
</html>
ASKER
You're right - that doesn't syncrhonize the header widths with the data cells. But it is cool. :)
It occurs to me - after the table is displayed, should it not be possible to read the widths of each data column, and set the header widths accordingly?
Or is there a reason nobody has proposed that?
Tom
It occurs to me - after the table is displayed, should it not be possible to read the widths of each data column, and set the header widths accordingly?
Or is there a reason nobody has proposed that?
Tom
>>read the widths of each data column
How would you do that?
How would you do that?
ASKER
Perhaps it's not possible to read the column widths at run time. I'm admittedly ignorant of the API. But it seems like something that ought to work.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
That works beautifully in IE - thanks for that!
The Holy Grail would be a cross-browser solution, but as it happens we are designing for an intranet.
Cheers,
Tom
The Holy Grail would be a cross-browser solution, but as it happens we are designing for an intranet.
Cheers,
Tom
This is a great bit of code, but do you have any idea how to fix a footer to the table as well as a header ?
I need to somehow fix it outside the DIV, but ensure the columns are exactly the same width.
I need to somehow fix it outside the DIV, but ensure the columns are exactly the same width.
God bless u buddy, code was treat
you will find a few different ways to approach this around here...here is one:
<html>
<head>
<title> scrollable table</title>
<style>
body {background-color:moccasin
th {color:snow;background-col
td {color:navajowhite;backgro
.maindiv {background-color:tan}
</style>
<body>
<div style="position:absolute;l
<table frame="border" width = 480>
<col width=80>
<col width=80>
<col width=80>
<col width=80>
<col width=80>
<col width=80>
<tr>
<th>first</th>
<th>second</th>
<th>third</th>
<th>fourth</th>
<th>fifth</th>
<th>sixth</th>
</tr>
</table>
<div class="maindiv" STYLE="overflow-X:hidden;o
<table frame="border" width=480 height=1200 >
<col width=80>
<col width=80>
<col width=80>
<col width=80>
<col width=80>
<col width=80>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
<tr>
<td height=60>Cd&</td>
<td height=60>:^)</td>
<td height=60>colC</td>
<td height=60>xxxx</td>
<td height=60>:^)</td>
<td height=60>Cd&</td>
</tr>
</table>
</div>
<table border=1 width=480 bgcolor="silver">
<col width = 80>
<col width = 80>
<col width = 80>
<col width = 80>
<col width = 80>
<col width = 80>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</table>
</div>
</body>
</html>