Before I attempt to reinvent the wheel (via jQuery plugin or similar), I'm trying to see if there is an easier way to do this or an existing plugin that users may know of. What I'm looking to do is scroll the body of a table that contains multiple table headers. For example, imagine something of this structure:
<table>
<thead>
<tr>
<td colspan="2"></td>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
<thead>
<tr>
<td colspan="2"></td>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
Honestly, I haven't tried out the above syntax to even see if its valid. The actual markup I have does not currently use thead/tbody and instead scrolls the whole parent div (seen below).
What I want to achieve is scrolling of the whole table such that the header of the most relevant section is viewed on top. Currently the header scrolls out of view is there are enough rows.
I know the various techniques used to scroll a table with one header, but what about multiple? Are there any existing ways to achieve this? I'm open to different ideas, but right now I'm thinking of simply displaying the most relevant table header for the content on top.
A few months ago, I wrote some code that did exactly that where I wanted the headers to perform similar to section headers on iOS.
Utilising a Jquery, the solution I ended up with involved creating an onScroll (and onResize for window resizing) event listener that ran a check through all $('table thead')
and checked their $(this).position()
on the page.
The check was whether the thead
had a position which was above the top of the current viewport.
Once I had found the most relevant header (the bottommost thead
that was above the viewport), I created a new table
, with position: fixed
at (0, 0) and copied into it a new column for each column of the headers rows and manually set its width
properties to match the original table.
I have put together a Proof of Concept which shows how this all works.
Here is some pseudo-code of how it works:
thead
sections in the tablethead
in the array with a top position less than scrollTop
of the body
element[0, originalTable.left]
outerWidth
of the original tabletd
found to the width of the matching td
from the original tableThere are some other edge case details that made this even nicer too:
tbody
below the one with the fixed header should be pushing it away.This approach worked a lot better others I tried such as trying to position:absolute
an object due to the fact that Firefox and IE aren't incredibly fast at running the onScroll handler so you tend to see 'juddering'. I also tried mucking with the position
attribute of the thead
s, this just ended in the table column widths jumping about and not matching the data.
thead
nodes aren't strictly required for this solution as you can use some other selector to determine which rows are headers etc.
Update: Added example code and pseudo-code Update: Dropbox changed their system, replaced example with jsfiddle URL
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With