PDA

View Full Version : Floating Table Header


hgs
01-17-2010, 03:49 PM
Ok my first post here.

This work would not be possible without all the good free javascript code
out there to learn from, so, thanks for this.

Here we go ...

To have this work you should not use the 'border' property for your table in the HTML part like <table border=1>
Better style your table using CSS.

Next your table must have an id specified like <table id=mytable>
It is assumed that the very first row of teh table is the header for this table.

To activate the floating header use the onload event on the body of your
HTML like <body onload="float_header('mytable');>

I have tested it with IE 8 and FF 2.x

A working demo page can be found here http://www.hgsweb.de/
Just look at the source of this page and you will see how to use this.

Have fun
Regards
Heinz



function float_header(tablename)
/*****************************/
{
var obj=document.getElementById(tablename);
var mytable=obj;
var floatoffsetleft=0;
var ns=(navigator.appName.indexOf("Netscape") !== -1);

while(obj.offsetParent.tagName!=="BODY"){
floatoffsetleft+=obj.offsetParent.offsetLeft;
obj=obj.offsetParent;
}
obj=mytable;
startX = mytable.offsetLeft+floatoffsetleft;

window.stayTopLeft=function(floater)
/**********************************/
{

// this function is called by a timer every so often (10ms) to check
// if the floating header has been srcolled out and,
// If so move it back in right at the top edge of the page.

var ftlObj=document.getElementById(floater);
var pY = ns ? pageYOffset : document.body.scrollTop ;

if(pY===0){
//
// Page is at the top position nothing to do
// Do not display floating header
//
ftlObj.style.display="none";
setTimeout("stayTopLeft('"+floater+"')", 10);
return;
} else {
if(pY>ftlObj.ybottom){
//
// header and the entire table has been srcolled out
// nothing to do here come back later to check
//
setTimeout("stayTopLeft('"+floater+"')", 10);
return;
}
if(ftlObj.tabtop-pY < 0){
//
// Original header has been moved out of view
// now bring in the floating header
//
ftlObj.y=pY;
ftlObj.sP(ftlObj.x, ftlObj.y);
ftlObj.style.display="block";
setTimeout("stayTopLeft('"+floater+"')", 10);
return;
} else {
//
// Original haeder is still in view.
// Do not display floating header
//
ftlObj.style.display="none";
setTimeout("stayTopLeft('"+floater+"')", 10);
return;
}
}
}

///////////////////////////////////////////////////////////////
////////////////////////// MAIN //////////////////////////
///////////////////////////////////////////////////////////////

//
// Create table with same header as the originla one
// For this copy over all header cells their classes and geometrie
//

obj=mytable;
tablefloat=document.createElement("table");
tablefloat.id="float"+mytable.id;
tablefloat.className=mytable.className;
tablefloat.width=mytable.clientWidth+"px";
tablefloat.style.position="absolute";
tablefloat.style.background="";
tablefloat.insertRow(0);
tablefloat.rows[0].width=mytable.rows[0].clientWidth+"px";
var nc=mytable.rows[0].cells.length;
for(i=0;i<nc;i++){
var th=document.createElement("th");
tablefloat.rows[0].appendChild(th);
tablefloat.rows[0].cells[i].innerHTML=mytable.rows[0].cells[i].innerHTML;
tablefloat.rows[0].cells[i].className=mytable.rows[0].cells[i].className;
tablefloat.rows[0].cells[i].width=mytable.rows[0].cells[i].clientWidth+"px";
}
document.body.appendChild(tablefloat);


var py,el,obj,offsettop,height,id;

// Now get the absolute Y position of the original table within the page
// set this for the floating header as well as the absolute X position of
// the original table.

obj=mytable;
ytop=obj.offsetTop;
while(obj.offsetParent.tagName!=="BODY"){
obj=obj.offsetParent;
ytop+=obj.offsetTop;
}
height=mytable.clientHeight;

tablefloat.ybottom=ytop+height-tablefloat.clientHeight;
tablefloat.tabtop=ytop;
tablefloat.sP=function(x,y){this.style.left=x;this.style.top=y;};
tablefloat.x = startX;
py = ns ? pageYOffset : document.body.scrollTop;
tablefloat.y = py+ytop;
tablefloat.py = py;
stayTopLeft(tablefloat.id); // no go check
}

Dormilich
01-17-2010, 08:28 PM
actually, the demo page does nothing on Firefox 3.5, Opera 10 & Safari 4 (besides that the tables are too small)

hgs
01-17-2010, 09:09 PM
Sorry to here that is not working for you.

Everything works as expected.
When I resize the browser window down to a size that I get a vertical
scroll bar and start scrolling out the two top table headers I see them floating back in.

Just tested on XP with
Safari 4.0.4
FireFox 3.5.7
Opera 10.10
IE 6.0.2

On windows 7
IE 8
FireFox 2.x

Should I attach some screen shots ?

Regards
Heinz

Mike_O
01-22-2010, 10:10 PM
Hey Heinz,

It's pretty neat. To be honest though, I would have a simpler solution to achieve this (and I have done so in the past). Basically, I would put the table inside a scrollable div, and put the header row on top. There are many variations to this idea, both server and client-side. The biggest challenge I found was trying to perfectly align the column widths between the floating header and the table inside, but it's all doable.

Don't want you to think that I'm criticizing your work. It's just what I would do to achieve this effect.

Regards,
Mike