Making Scrollable Tables with fixed headers
********** Please click here for an update script with additional functionalities like multiple header freezing, column freezing and multiple tables ***********
It’s been tested on the following browsers all running on Windows XP.
- Firefox 2.0
- Firefox 3.5
- Google Chrome
The big table
Here is an example of a table we are going to introduce the scrolling functionality. Well, it is not really big, just big enough to test our functionality 🙂
Solution 1: Simple CSS only scrolling without fixing headers
With the help of a bit of CSS, we can implement a simple scroller. Enclose the table element within a div container with an overflow value of auto and a fixed height. Something like
<table …. />
You can see the demo at http://jaimonblog.appspot.com/datascroller/simpleScroller.html
Solution 2: Scrolling with fixed headers using table cloning
You can see a working demo at http://jaimonblog.appspot.com/datascroller/fixedHeaderFullClone.html
Download fxheader1.js and include it in your project as explained on the implementation section
How does it work?
- First we put a scrollable div container around the table element as in our first solution.
- create a div element
- clone the table element using cloneNode(true)
- added the cloned table to this div
- replace the table element with this div
- Create a container on top of the table to place the headers.
- Attach scrollHeader function to the table container div’s onscroll event, so that we can align the heading when the table is scrolled horizontally.
- We then clone the table and place it in the header container. Container height is set, so that only the header row is visible.
- We then set a negative margin top on the original table to hide the actual header.
- Attach fxheader function to window onresize event, so it works when window get resized.
Solution 3: Scrolling with fixed headers using fast table cloning
You can see a working demo at http://jaimonblog.appspot.com/datascroller/fixedHeaderFastClone.html
Download fxheader2.js and include it in your project as explained on the implementation section to get started.
Solution 2 will give you very accurate column widths at the expense of doing a full table cloning. If you have a table with lots of rows, this can take a while. If your rows have elements with unique IDs, you will have to change it on the cloned node to avoid ID collision. Although it will work, it will lead to a sluggish user experience on pages with really large tables.
In solution 3, we are doing a fast clone without any child elements. Then we add the first row to it and set individual column width separately based on the offsetWidth property of each cell. You’ll have to offset cell margin/padding when setting the width. In our example, I deduct 3 from offsetWidth and that works fine for our table in all browsers I’ve tested.
Everything else is similar to solution 2.
Solution 4: Adding scrolling to table generated by ADF Faces 10g with fixed header (With and without pagination support) and automatic height stretching
Although in theory it is similar to solution 3, I had to make a few changes to make it work for a table generated by ADF Faces. The problem is ADF Faces creates three HTML tables for each af:table element. First and third tables are created for pagination support. It doesn’t create an ID for the actual data table itself, so we need to access it as a childNode of the container element. If pagination is there, we need to place this above our fixed header. Since we have the scrolling functionality, I thought the second pagination controls below the data table is not necessary, and I’m removing it from the page.
When cloning table data here, we have to update ID field of each element to avoid ID collision. We also have to set the correct selected index value for pagination selector combo box. Another functionality I’ve implemented here is the ability to auto stretch the table content to fit the page. You should pass in the ID of your last container component to make it work. Please see adjustHeight function in fxheader.js for more details.
As with the second and third solutions, you could add the following line to your JSPX page to get this working.
<afh:script source="fxheader.js" />
<afh:script text="fxheaderInit('testTable','footerContent');" partialTriggers="testTable" />
Where testTable is the ID of your af:table element and footerContent is the ID of your last container component for stretching. Partial Triggers are required here if used with pagination.
You can download a fully functioning JDeveloper project from http://jaimonblog.appspot.com/datascroller/ADF10gScroller.zip
Please note that it is created with JDeveloper version 10.1.3.3. If you are using 11g, then fixed header functionality is already part of it. (Although there are a few issues with it at the time of writing this. One such issue is discussed here http://forums.oracle.com/forums/message.jspa?messageID=4032492#4032492)
As I’m not able to provide a demo link, you can see some screen shots of this solution here,
84 Comments »
- Check digit calculator for barcodes and credit cards
- An Excel Addin to work with Unicode CSV files
- SimpleImageInfo – A Java class to get image size without loading the whole data
- Making Scrollable Tables with fixed headers – Updated
- Migrating 10g JSF Web project with ADF Faces components in jspx pages to 11g Facelets pages using Rich components
- Monitoring Log4J messages on a browser via server push
- Making Scrollable Tables with fixed headers
- C# FTP Client Library