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.
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.
Share Improve this question edited Nov 26, 2016 at 23:42 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Nov 7, 2011 at 22:36 achinda99achinda99 5,0784 gold badges37 silver badges42 bronze badges 4- This is a pretty specialized case - It may have been done before, but I doubt you'll find an existing plugin. Are you just looking for answers that point you to an existing plugin, or are you looking for help "inventing the wheel"? – gilly3 Commented Nov 10, 2011 at 17:37
- 5 here is jquery plugin for sticky header polarblau.github./stickySectionHeaders but it's for 'ul' list not table. This example might help you too jsfiddle/6qqPz – satrun77 Commented Nov 10, 2011 at 22:55
- @satrun77: Thanks, those actually look really interesting. Might be onto something there. – achinda99 Commented Nov 12, 2011 at 3:00
- @gilly3: I'm more than willing to invent the wheel if need be, but before I go on that endeavor, I wanted to see if it already has been done. If it has not, ideas for features/functionality are definitely wele. – achinda99 Commented Nov 12, 2011 at 3:01
1 Answer
Reset to default 15 +100A 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:
- Check the table is visible
- Get a list of all
thead
sections in the table - Reverse the list
- Find the first
thead
in the array with a top position less thanscrollTop
of thebody
element - If we found one:
- Create deep copy of the thead
- Make a container table
- Copy attributes from the original table so the styles get copied
- Position the container at
[0, originalTable.left]
- Set the width equal to the
outerWidth
of the original table - Set the width of every
td
found to the width of the matchingtd
from the original table - Add it to the DOM
- If none found, remove the existing container from the DOM if there was one
There are some other edge case details that made this even nicer too:
- Instead of (0, 0), the origin point for the fixed row was altered based upon whether the "real" header row for the
tbody
below the one with the fixed header should be pushing it away. - Ensure that previous header rows are deleted before making a new one
- Don't recreate the header row if the header you'd be making is the same as what is already there
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