469,287 Members | 2,652 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,287 developers. It's quick & easy.

Locking Table Headers (like Excel)

Hello Javascript enthusiasts!

I need to lock a TABLE HEADER vertically, so when you scroll up/down,
the content moves but the header is always visible, like you can do in
Excel.

It is for an intranet app, and only has to work in IE6 (and future
releases).

I have a working example at:

http://c.1asphost.com/giggy/locked_h...in/default.htm

which relies on this CSS hack applied to the TH:
{
top:expression(document.getElementById("table_cont ainer_1").scrollTop-0);
}

This example is seamless and solid -- and simple! -- but the problem is
it is too resource intensive on tables more than 100 rows or so... it
slows _EVERYTHING_ down on the page. Some of these tables are 1000
rows and more!

Anyone have any solutions that are less processor-expensive?

Thanks,
Ann

Apr 6 '06 #1
11 10283
A couple caveats:

1. Only has to work in IE6 and later
2. Resource Inexpensive
3. The header data is dynamically populated, but Wraps
4. The content is dynamically populated, but Nowraps
**3 and 4 means that the width of the widest data column determines the
width of each column, including the header for that column...
5. I cannot use fixed widths for the columns -- they must be determined
by the width of the dynamic data they display.

Basically, if you look at the example in the URL above, _THAT_ is what
I want in every way, except it is too slow/resource expensive...

Thanks,
Ann

Apr 6 '06 #2
Giggle Girl wrote:
I need to lock a TABLE HEADER vertically, so when you scroll up/down,
the content moves but the header is always visible, like you can do in
Excel.
Search the archives of this group for heated discussions of this topic ;)
It is for an intranet app, and only has to work in IE6 (and future
releases).
That is a good thing. It's easier to support either IE or Firefox(and others
that support a scrollable tbody) but not both.

One similar IE-only solution I have done is:
http://www.mattkruse.com/temp/floating_header.html

This is especially useful when there are multiple long tables on a page, and
you want to scroll the page like normal yet have the header rows "stick".
I've used this method many times and everyone seems to like it.
I have a working example at:
http://c.1asphost.com/giggy/locked_h...in/default.htm
which relies on this CSS hack applied to the TH:
{
top:expression(document.getElementById("table_cont ainer_1").scrollTop-0);
}
There are two main problems:
1. Expressions get evaluated constantly, with every mouse move, even if your
user interaction doesn't impact the expression evaluation. This is bad
design by IE, IMO.
2. Your document.getElementById() call is going to be slow. There's no need
to do it - instead use offsetParent[*] to find the scrollable container,
which should speed things up quite a bit.

Also, you should consider adding the rule to the TR rather than each TH.
Anyone have any solutions that are less processor-expensive?


Another option is to ditch expressions and instead have a javascript
function specific to the table that sets the "top" value of the TR when the
container is scrolled. This way expressions aren't evaluated constantly.

Of course, keep in mind that if your table contains select elements they are
going to show through your headers. Also, if your table has any cell
spacing, the data will bleed through that as well.

I've not tested any of these solutions on IE7, so I don't know how
forward-compatible they are.

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
Apr 6 '06 #3
Hey Matt,
thanks for your reply:
2. Your document.getElementById() call is going to be slow.
There's no need to do it - instead use offsetParent[*] to find the
scrollable container, which should speed things up quite a bit.


Could you supply me with the correct code for this, that I can plug
right in? (I have never used offsetParent and don't know where to put
it...)

And yes, I had searched the archives befoer posting and saw many
threads doing stuff similar, and some posts by you, as well. Nothing
was quite what I wanted (that I have seen so far.)

Regarding the sample you provided, it won't work for my purposes. No
offense, but it is too clunky, the way it jiggles, IMO. One thing I
loved about the example I provided was how "solid" it was; no jiggle.

Thanks so much for your reply! (Yay, Matt Kruse replied -- one of the
stars here!)

Thanks,
Ann

Apr 6 '06 #4
Giggle Girl wrote:
Could you supply me with the correct code for this, that I can plug
right in? (I have never used offsetParent and don't know where to put
it...)
That's custom consulting work, which I don't do :) Actually, it would take
time to inspect your code and html and time is something I don't have much
of, sorry.

I did pull this example out of my archives, though, which might help:
http://www.mattkruse.com/temp/grid.html
Regarding the sample you provided, it won't work for my purposes. No
offense, but it is too clunky, the way it jiggles, IMO. One thing I
loved about the example I provided was how "solid" it was; no jiggle.


True, they are different approaches. When I run mine, it doesn't "jiggle" at
all. It just floats nicely to the top of the page. Perhaps a different in
machine performance? I don't know. The benefit of the example I provided is
that it works well for any number of tables on a page, and allows the user
to scroll through a long page like normal, rather than having a small
separate "window" view of a table. I think both approaches do have their
merits.

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
Apr 6 '06 #5
>That's custom consulting work, which I don't do :)

No problem. Sorry, I thought it was just one line of code to replace
my little CSS hack...

One other "thinking outside the box" idea I have is this:

1. Put table "Headers" in its own table
2. Have an iframe below it, containing the Table Data (in its own
table)
3. Somehow set the Column width of the Headers table by detecting the
width of the Iframe's/Data columns...

I am not sure if it is possible to retrieve and set table column widths
like this, but I am looking into it...

Any other ideas anyone?

Thanks,
Ann

Apr 6 '06 #6
Giggle Girl wrote:
One other "thinking outside the box" idea I have is this:

1. Put table "Headers" in its own table
2. Have an iframe below it, containing the Table Data (in its own
table)
3. Somehow set the Column width of the Headers table by detecting the
width of the Iframe's/Data columns... ....
Any other ideas anyone?


One issue with your idea is that either of the two subtables may be
dictating the widths of the columns in the original table. Also, if
you get the widths at the outset and get your two subtables to align
horizontally, the user may then adjust the screen size and everything
will have to be recomputed. Well, it might work with an onresize event
handler.

I had another idea along these lines. Duplicate the underlying table
(by cloning it). Insert the cloned table into a div with no scroll
that is sized to be exactly the width and height of the header row.
Right under this div (and top aligned with it) is a second div that
scrolls, containing the original table. A variation on this idea is
that the second div is immediately below the first div and it clips the
top part of the included table. Don't know if either one is possible.
These also mandate an onresize handler, which I'm thinking would be
easier, if the ideas work at all, that is.

Csaba Gabor from Vienna

Apr 6 '06 #7
Csaba Gabor wrote:
<snip>
I had another idea along these lines. Duplicate the
underlying table (by cloning it). Insert the cloned
table into a div with no scroll that is sized to be exactly
the width and height of the header row. Right under this div
(and top aligned with it) is a second div that scrolls,
containing the original table. A variation on this idea is
that the second div is immediately below the first div and
it clips the top part of the included table. Don't know if
either one is possible. These also mandate an onresize handler,
which I'm thinking would be easier, if the ideas work at all,
that is.


That is possible, and it works (in some senses of the word):-

<URL: http://www.litotes.demon.co.uk/examp...bleScroll.html >

Indeed it is an approach that handles things like the user choosing to
re-size the displayed text without everything falling apart, or the
programmer having to continually measure the size of all the columns and
rows all the time and compensate for such changes themselves.

(On the other hand Matt doesn't seem to like that approach much ;)

Richard.
Apr 7 '06 #8
Giggle,

I took a similar approach for a "non-jiggly" scroll table but am doing
the CSS "lock" on the TR tag of the header rather than the individual
TH tags. I am wondering if my approach may be faster in the sense that
the expression is only evaluated on one tag rather than a multiple.
Here is my CSS:

DIV.scrollTable {
border:1px solid #B3C0C9;
width:100%;
height:150px;
overflow:auto;
}
DIV.scrollTable TABLE {
width:100%;
}
DIV.scrollTable TR.fixed {
position:relative;
top:expression(
this.parentElement.parentElement.parentElement.scr ollTop);
}
DIV.scrollTable TH {
border-bottom:1px solid #264a6f;
border-right:1px solid #909090;
background-color:#B7D1E1;
font-weight:normal;
padding:1px 3px;
text-align:left;
color:#264a6f;
white-space:nowrap;
}

And the HTML:

<p>Table One</p>
<div class="scrollTable">
<table cellpadding=2 cellspacing=0>
<tr class="fixed">
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
<th>Header 4</th>
<th>Header 5</th>
<th>Header 6</th>
</tr>
<tr>
<td>aaaaaaaaaaaaaa</td>
<td>bbbbbbb</td>
<td>cccccccccccccccccccc</td>
<td>ddddddddddd</td>
<td>eeeeeee</td>
<td>fff</td>
</tr>
<! --- Repeat the above TR ad nauseum -- ->
</table>
</div>

Note that I hacked my "CSS hack" a bit further by using parentElements
to reference the DIV rather than needing to identify it by ID. The
advantage of this approach (if we ignore the disadvantages of using
expression in the first place) is that I can easily create a second
table on the page without needing to make additional copies of the
original CSS definitions. Just use the same class names and you are
good to go.

For what it's worth,
Yukky.

Apr 7 '06 #9
Yukky Korpulent wrote:
^^^^^^^^^^^^^^^
Is this supposed to be some kind of fake-troll? (The similarity to the
name of Jukka "Yucca" K. Korpela, a well-known Web development specialist
from Finland, is obvious.) If yes, I suggest you change name at once.
[...]
border:1px solid #B3C0C9;
[...]
DIV.scrollTable TH {
border-bottom:1px solid #264a6f;
border-right:1px solid #909090;
background-color:#B7D1E1;
Neither color is Web-safe.
[...]
<! --- Repeat the above TR ad nauseum -- ->


This is not a Valid "comment declaration".

<URL:http://validator.w3.org/>
PointedEars
Apr 7 '06 #10
Thomas Lahn wrote:
Is this supposed to be some kind of fake-troll?
No.
Neither color is Web-safe.
The example set forth was to illustrate locking table rows, not colors.
This is not a Valid "comment declaration".


Clearly, that line is informational only.

Apr 7 '06 #11
Good stuff, Yukky!

I will plug this into some of the massive tables I am working with and
let you know how much better the performance hit is compared to what I
had!

And no jiggles!

Thanks,
Ann

Apr 8 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Michael Chermside | last post: by
1 post views Thread by Peter Rilling | last post: by
2 posts views Thread by Wensui Liu | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.