"Freeze Panes" in table to make body scrollable

M

Matt Kruse

This is a common requirement - "freeze panes" in a table, so that some
header rows and some columns on the left are frozen while the body content
scrolls. This makes large tables more usable on screen.

There are a number of solutions available. For example,
http://www.litotes.demon.co.uk/example_scripts/tableScroll.html

I'm just wondering if anyone knows of a "latest and greatest" script to
solve this problem.
My requirement at the moment happens to be IE6-only, but a generalized
solution is always preferred.

I like Richard's solution above, but as usual the code is so unreadable that
maintenance or tweaks would be impossible. I would love to see a technically
similar solution with a more sane coding style.

Any pointers?
 
M

Matt Kruse

Brett said:
Why use script at all? Links from here to variations on CSS theme:
http://web.tampabay.rr.com/bmerkey/examples/nonscroll-table-header.html

Locking the first column requires javascript. I've looked at the above
solution, and I've implemented something similar myself. But I don't like
expressions, and the solution needs to perform better on 40x250 tables, for
example.
If your target is IE6, then the very best solution in terms of
performance and maintenance is CSS combined with client-side data
binding.

Well, I disagree there. The output will actually be from a java webapp, so
client-side data binding isn't necessary at all. And CSS doesn't do the
whole job. :)
 
R

Richard Cornford

Why use script at all? Links from here to variations on
CSS theme:
http://web.tampabay.rr.com/bmerkey/examples/nonscroll-table-header.html

They don't actually work that well. If they did I would say use CSS, but
the header is not fixed in Opera 7.5, Mozilla puts up a horizontal
scroll bar and when you scroll it the header cells don't line up with
the horizontally scrolled body cells. The CSS makes an invalid
assumption about the dimensions of scroll bars (that they remain the
system defaults even though they are user configurable) and the table
cannot exceed the available horizontal space and be scrolled
horizontally to expose more headers and data cells. And above all you
cannot arrange that a single column is fixed next to a horizontally
scrolling body at all with CSS, let alone fix the top row and the
leftmost column.

As my script demonstrates that all of these things can be done, can be
done on many dynamic visual browsers, and can cleanly degrade into
entirely usable HTML in environments that do not support the script, the
reason for scripting it might be that it works where CSS alone cannot.

I agree on the cited Cornford script. Impressive but not
for the normal dev environment.

What is required in a development environment is code that does what it
was specified to do with the simplest possible interface. As the entire
public interface for my script is a single function you cannot get much
simpler. All anyone wanting to use the script has to do is write (or
script generate) an HTML table that conforms with the (limited)
restrictions in the documentation, style it, provide it with a unique ID
and pass the id as an argument to a function call, and it was designed
for, and lends itself to, having that process automated in server side
scripts.

When writing code to be used by others (and particularly server-side
programmers who don't know javascript, and don't want to) it is the
external view of an object that is important not the code inside it.
In addition, clients usually like a good print version
of a data table and all scripts usually fail that test
miserably.

That is mostly just a failure to understand an !Important aspect of CSS
in print style sheets.

Richard.
 
A

ASM

Matt said:
This is a common requirement - "freeze panes" in a table, so that some
header rows and some columns on the left are frozen while the body content
scrolls. This makes large tables more usable on screen.

There are a number of solutions available. For example,
http://www.litotes.demon.co.uk/example_scripts/tableScroll.html

Wonderfull !
I did understand on this page that table css rules are poor in IE
and some fiew bit of javascript code would delight our dazzled eyes

Sure ! what a marvellous table without any lift to scroll it

Was a free test with IE 5.2 on Mac :-/
My requirement at the moment happens to be IE6-only, but a generalized
solution is always preferred.

IE6 is not yet pensioner ?
Any body haven't offer him a wheelchair ?
I like Richard's solution above, but as usual the code is so unreadable that
maintenance or tweaks would be impossible. I would love to see a technically
similar solution with a more sane coding style.

Any pointers?

tbody {
height: 250px;
overflow: auto;
}

ignored by my Safari, my Opera, and of course my IE
 
M

Matt Kruse

ASM said:
tbody {
height: 250px;
overflow: auto;
}
ignored by my Safari, my Opera, and of course my IE

And does nothing to support horizontal scrolling or locked columns!

Implementing static headers is a much easier task than static headers +
horizontal scrolling + locked columns.
 
M

Matt Kruse

Richard said:
What is required in a development environment is code that does what
it was specified to do with the simplest possible interface. As the
entire public interface for my script is a single function you cannot
get much simpler.

I beg to differ.

a) There is no documentation for your script
b) There are no comments in your script
c) There isn't a summary of the approach that the script uses to achieve the
goal, or caveats about when and where it won't work
d) The code is not tweakable in any way by even most experienced programmers
(to add, for example, the ability to lock two columns)
e) There is no "simplest case" example to start from, leaving the reader to
disect your source to figure out what is needed for the code to run, and
what is specific to your example

I have to wonder how much of your code is even necessary for this specific
purpose. Things like retFalse() being defined 3 times - why?

I like the result of your code. I haven't tested it in my specific case yet
(I have some pre-work to do) but since I might require locking of two
columns, and your solution doesn't seem to support that, then I have to
throw yours out entirely. There's no hope of me modifying your code to suit
my needs because it's incomprehensible.

If you added comments about intent and purpose of bits of code, it might
make it usable. I know you're a fan of complex, closure-based code, but
couldn't you accomplish the same task in a more readable way? Or at least
document your general approach, so others could take the same approach with
different code?
When writing code to be used by others (and particularly server-side
programmers who don't know javascript, and don't want to) it is the
external view of an object that is important not the code inside it.

Which is why documentation is vital :)
 
R

Richard Cornford

Matt said:
I beg to differ.

a) There is no documentation for your script

Yes there is, I just have not published the documentation (and will
not).
b) There are no comments in your script

The version that accompanies the documentation has every line commented.
c) There isn't a summary of the approach that the script
uses to achieve the goal,

It is in the introduction to the documentation.
or caveats about when and where it won't work

Define "work".
d) The code is not tweakable in any way by even most
experienced programmers

Rubbish. There is another version on my site that is entirely a tweaked
version of that that script.
(to add, for example, the ability to lock two columns)

If you mean two (or more) columns that are not both (all) leftmost
columns then no it will not. The strategy employed would not perform
well if asked to lock arbitrary numbers of physically separated columns.
That was not part of the design requirement and so was not designed into
the result.
e) There is no "simplest case" example to start from,
leaving the reader to disect your source to figure out
what is needed for the code to run, and what is specific
to your example

Why should there be? I published the script for no other reason than to
demonstrate that a scrollable table body could be done. The bare script
satisfies that aim.
I have to wonder how much of your code is even necessary
for this specific purpose. Things like retFalse() being
defined 3 times - why?

They are all inner functions in re-usable low-level components, moving
them outside of the components to use only a single example would make
the components themselves less self-contained, and they are very small
functions so the cost is negligible.
I like the result of your code. I haven't tested it in
my specific case yet (I have some pre-work to do) but
since I might require locking of two columns, and your
solution doesn't seem to support that, then I have to
throw yours out entirely.

That is fine by me, you couldn't afford the rights to use it anyway.
There's no hope of me modifying your code to
suit my needs because it's incomprehensible.

And people ask about obfuscation ;-)

But it isn't incomprehensible. You know full well that Yep, Michael
Winter, Lasse Reichstein Nielsen, et al would be capable of
understanding it, even without comments/documentation. All you are
saying is that you don't comprehend it, and presumably that many others
wouldn't either. That is true but what do you expect me to do about it?
I have already written and published the clearest explanation of
closures and their mechanism that I am capable of. I have also written
extensively on this group about my thoughts on script design, and posted
examples with (more or less complete) comments and explanations. There
is no arcane secret here; it is just a matter of people putting in the
effort to understand what javascript is capable off.
If you added comments about intent and purpose of bits
of code, it might make it usable.

Precisely, as a professional programmer it is my responsibility to
provide code that is sufficiently documented to facilitate its easy use,
deployment, and future development by other javascript programmers. But
what I do in my spare time, for fun, is another matter entirly.
I know you're a fan of complex, closure-based code, but
couldn't you accomplish the same task in a more readable
way?

I am a fan of object based code. I use closures because they give me
tidy and simple ways of achieving what would otherwise be complex and
ragged. You presumably would want to achieve the same with structures of
JS objects, but the scope chain in a closure-based script is a structure
of objects. If you don't perceive that structure, and understand its
mechanism and interactions, then the result will look complex. Once you
do perceive the structure you will see simplicity.

I am not a masochist and I do not write code that I perceive as any more
complex than it absolutely has to be. Disregarding the pre-existing
re-usable low-level components, the code that creates and operates the
scrollable table is about 150 lines, and took 4 hours to design, write,
test and debug. That is not a symptom of genuinely complex code, or a
flawed approach to code authoring.

As for "readable"; wouldn't learning the language aid in reading it?
Or at least document your general approach, so others
could take the same approach with different code?

My general approach is a matter of public record. The specific strategy
employed in that script is something you should be able to work out for
yourself. There are, after all, only a limited number of ways of
producing those results and, unintelligible as you may find it, the code
calls a couple of methods that should be a very obvious clue, if you
look for them.
Which is why documentation is vital :)

Which is why documentation is created and distributed in a development
environment.

Richard.
 
M

Matt Kruse

Richard said:
Why should there be? I published the script for no other reason than
to demonstrate that a scrollable table body could be done.

I misunderstood your intent, apparently.

I thought you had published the example and code as a proof of concept, for
others to use and/or learn from. Obviously your intent was not to share your
knowledge or experience. Fantastic!
But it isn't incomprehensible. You know full well that Yep, Michael
Winter, Lasse Reichstein Nielsen, et al would be capable of
understanding it, even without comments/documentation. All you are
saying is that you don't comprehend it, and presumably that many
others wouldn't either.

I assumed you published it as a learning tool for others. Otherwise, I don't
see any reason for publishing it at all (other than to 'brag'?). But that's
your perogative.

I understand closures, and I can follow your code when I dig into it. It's
just formatted so badly, lacks any comments, and contains unused code, that
going through the effort is not worthwhile. I've already achieved very
similar results with much less and more readable code. I was hoping to get
some further insight into things I hadn't considered or ideas that you and
others had to make my code better. But since your intent isn't to share or
help with your examples, then I guess I was looking to the wrong place to
begin with.
 
M

Matt Kruse

Richard said:
My general approach is a matter of public record. The specific
strategy employed in that script is something you should be able to
work out for yourself.

After spending a small amount of time looking into your technique, I find:

1) Three total copies of the initial table, which in my case is rather
large. I don't think this is an elegant solution.

2) After your script executes, there are three tables with the same ID. This
is illegal, of course. A valid solution would not have this side-effect.

So, while your solution may appear to work, I think I'll continue down my
road which I think will result in a better overall solution.
 
R

Richard Cornford

Matt said:
I misunderstood your intent, apparently.

It wouldn't be the first time.
I thought you had published the example and code as
a proof of concept,

So in your unusual use of English there is a distinction between
demonstrating that something can be done and a "proof of concept"?
for others to use and/or learn from.

Two things don't necessarily follow from a proof of concept.
Obviously your intent was not to share
your knowledge or experience. Fantastic!


I assumed you published it as a learning tool for others.

And you didn't find the absence of technical explanations, comments,
etc, suggesting that that assumption was misguided.
Otherwise, I don't see any reason for
publishing it at all (other than to
'brag'?). But that's your perogative.

It has been questions as to whether scripted table scrolling could be
flexible, fluid, cleanly degrading, etc. Examples that demonstrate some
of those characteristics go some way towards answering that question.
I understand closures,

No you don't. You may recognise them but if you did understand them
there would be many fewer inner functions (or at least as deeply nested)
functions in your "AJAX" library.
and I can follow your code when I dig into it.
It's just formatted so badly, lacks any comments,

I would have thought it would be obvious that the component code had
been deliberately stripped of comments and formatting.
and contains unused code,

What makes you think that?

But since your intent isn't to share or help with
your examples,

That is not a particularly accurate generalisation of my published
script examples.
then I guess
I was looking to the wrong place to begin with.

Looking to me for help does seem a bit unrealistic in your case.

Richard.
 
R

Richard Cornford

Matt said:
After spending a small amount of time looking into your technique, I
find:

1) Three total copies of the initial table, which in my
case is rather large. I don't think this is an elegant solution.

As I said, it is not an approach that will be viable if more than two
copies of the table are going to be needed, so fixing more than one
header column and one header row would not be a good idea. Apart form
that the trade off is between arranging for the browser to apply the
same row and column widths and heights (because all three tables are
essentially the same table, with the same constrains on the same
contents. The header rows/cells in one table are automatically the same
size as the header rows/cells in the others), and calculating all of the
dimensions and applying them to the headers, and re-applying them when
the user changes some display configuration (and so detecting those
changes in order not to re-do all that work on every re-draw).

Having the browse do all that work struck me as a better option than
coding all of that process myself given that there never was any
intention to have more than one of each fixed row and column.
2) After your script executes, there are three tables
with the same ID.

What makes you think that? If the browser had a problem with the
existence of more than one elements with the same its authors would
write the - clone - method such that it didn't copy the ID.
This is illegal, of course. A valid solution would not
have this side-effect.

Assuming the browser actually does copy the ID during a - clone -, did
you see a side effect. But if you think it matters it is just two
assignment operations to have explicitly distinct IDs.
So, while your solution

It is not a "solution", it is just a scirpt.
may appear to work, I think I'll continue down my road
which I think will result in a better overall solution.

Did I ever propose that you do anything else?

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top