Scrollable Fixed Header Table – A JQuery Plugin

March 22, 2010 at 7:51 am | Posted in JQuery | 109 Comments
Tags: , , ,

This plugin allows html tables to be scrollable horizontally and vertically while headers are still visible and in tack with the columns. This plugin can be used in two modes:

  • With column select – Columns to view can be selected. The select state can be persisted in a named cookie.
  • Without column select

Live Demo


With tablesorter blue theme.

With tablesorter green theme.

Large table with 1450 rows using list-attrs plugin to improve rendering speed.

Multi-row headers.

Fixed (freeze) first column with table sorter.


SVN repository (Latest up to date version)

Use this command to anonymously check out the latest project source code:

svn checkout jquery-sfht-read-only

browse source code

view change list


Getting Started

1. Import dependencies

<script src="javascripts/jquery-1.4.2.min.js" type="text/javascript"><!--mce:0--></script>
<script src="javascripts/jquery.cookie.pack.js" type="text/javascript"><!--mce:1--></script>

<script src="javascripts/jquery.dimensions.min.js" type="text/javascript"><!--mce:2--></script>
<script src="javascripts/jquery.scrollableFixedHeaderTable.js" type="text/javascript"><!--mce:3--></script>

2. HTML Table. As of this version the following rules must be followed to make the plugin work.

  • The table should have an id attribute.
  • The table should be decorated with CSS class name. It does not work well with css id or style attribute yet.
  • The table’s class attribute should have “scrollableFixedHeader” as one of the values.

Here’s the sample table. The highlighted line applies the rule above.

	.myTable {
		background-color: BLACK;

	.myTable td {
		background-color: WHITE;

  .myTable .header td {
    font-weight: bold;
    background-color: #CCCCCC;
<table id="table1" class="myTable scrollableFixedHeaderTable" cellspacing="1" width="600px">
<tr class="header">
<td>cell (1, 1)</td>
<td>cell (2, 1)</td>
<td>cell (3, 1)</td>
<td>cell (4, 1)</td>
<td>cell (1, 2)</td>
<td>cell (2, 2)</td>
<td>cell (3, 2)</td>
<td>cell (4, 2)</td>
<td>cell (1, 3)</td>
<td>cell (2, 3)</td>
<td>cell (3, 3)</td>
<td>cell (4, 3)</td>
<td>cell (1, 4)</td>
<td>cell (2, 4)</td>
<td>cell (3, 4)</td>
<td>cell (4, 4)</td>
<td>cell (1, 5)</td>
<td>cell (2, 5)</td>
<td>cell (3, 5)</td>
<td>cell (4, 5)</td>

3. Call the plugin function.



With column select . Selected columns remained after page reload.

$(tableID).scrollableFixedHeaderTable(widthpx, heightpx, showSelect, cookie);

With column select. All columns are restored after page reload.

$(tableID).scrollableFixedHeaderTable(widthpx, heightpx, showSelect);

Without column select

$(tableID).scrollableFixedHeaderTable(widthpx, heightpx);

Multirow headers

$(tableID).scrollableFixedHeaderTable(widthpx, heightpx, null, null, rowCount);


  • tableID – ID of the table to transform
  • widthpx – width in pixels of the transformed table
  • heightpx – height in pixels of the transformed table
  • showSelect – When true, shows a blue arrow on top
  • cookie – cookie where the selected state of the column select will be stored.
  • rowCount – number of header rows

Multi-row Headers

Reference from #comment-83.

Using column select only works if there are no rowspans and colspans as there is no easy way to map the header’s tr tag index to the group of tr tags in the data that is why I placed null on the column select parameters.

$(tableID).scrollableFixedHeaderTable(widthpx, heightpx, null, null, rowCount);

The row count parameters determines the number of rows from the top to be used as a header.

While version 1.0.2 is not released yet, you can download the latest source from the trunk.

Get the latest trunk source jquery.scrollableFixedHeaderTable.js

Here’s the live demo.

Improve Table Transformation Speed

By default, the plugin extracts the header using the easy way:


That line of code creates a copy of the source table then reduces that copy to headers only. This may be good for small tables but not for very big tables. see #comment-62.

For speed improvement, get the latest plugin version, and list-attrs plugin.

Here are the links



Add the a Document type to your page to force IE 8 to render in standards mode.



Add the listAttributes plugin to your scripts.

<script type="text/javascript" src="javascripts/jquery-list-attributes.js"></script>

You may clear your cache of the of sfht plug in.

That’s all! The latest sfht plugin will use grab only the header when the listAttrs plugin is detected.

Here’s a live demo with a table containing 1450 rows. The page transforms the table after the document loads in a short time.

Integrating with JQuery Tablesorter

You can view live the the demo here:

blue theme.

green theme.

or offline with the sfth_1.0.1 release. sfht_sortable_blue.html and sfth_sortable_green.html

Tablesorter is great jQuery plugin for sorting data with a click on the header. Integration with this plugin have a few changes, however.

1. The table should have in this tag order:


Yes, th for header and td for data.

2. Remove the width, border and padding from table.tablesorter class from the selected table sorter theme. This ensures compatibility with browser box models. This example is from themes\blue\styles.css of the tablesorter package.

table.tablesorter {
  background-color: #CDCDCD;
  /* margin:10px 0pt 15px; */
  font-size: 8pt;
  /* width: 100%; */
  text-align: left;

The modifications are ready, you can add this imports from table sorter.

<link href="css/themes/blue/style.css" rel="stylesheet"  type="text/css" />
<script type="text/javascript" src="javascripts/jquery.tablesorter.js"></script>

Now, for the initializing script.

    $('#myTable1').scrollableFixedHeaderTable(800, 200, true, 'mycookie');
    $('#myTable1').tablesorter().bind('sortEnd', function(){
        var $cloneTH = $('.sfhtHeader thead th');
        var $trueTH = $('.sfhtData thead th');
            $(this).attr('class', $($trueTH[index]).attr('class'));

    /* synchronize sortable and scrollable */
    $('.sfhtHeader thead th').each(function(index){
        var $cloneTH = $(this);
        var $trueTH = $($('.sfhtData thead th')[index]);
        $cloneTH.attr('class', $trueTH.attr('class'));

If your are using the green theme. Use spaces as padding for the headers. The script below adds 10 spaces to each header.

  var $this = $(this);
  var spaced = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
  + $(this).html();

The multisort feature, using shift key, does not work by clicking on the floating header.

It may be possible by means of programmatic multisorting instead of using the original click event.



RSS feed for comments on this post. TrackBack URI

  1. nice collect it to

  2. […] Scrollable Fixed Header Table : This plugin allows html tables to be scrollable horizontally and vertically while headers are […]

  3. Nice Article. Great Job.

  4. What a great resource!

  5. not valid in IE 8.0.7600

    • It seems that IE does not like css class that starts with underscore. The css class names from the live demo were ._div, and ._myTable. A quick fix was to remove the underscore so the class names are .div and .myTable respectively. I’ve updated the live demo. You may clear your browser cache to view the fresh content.

  6. Hi, I like this plugin, but when I try to add padding to the TDs, the header is messed up, do you know how could I fix this ?
    Thanks in advance.

    • You can start by removing or commenting lines 10 to 13 of scrollableFixedHeaderTable.css

      .sfhtTable table tr, .sfhtTable tr td {
      padding: 0;
      margin: 0;

      The result may not be pixel perfect but can be tweaked with more css and jquery dimension methods. I’ve added this fix to the svn repository.

  7. I shouldn’t be surprizing so hard at that.

  8. really nice n helpful.

  9. Hey, great blog…I haven’t figured out how to add your site in my rss reader but I will soon 🙂

  10. Although, I got the same number of header fields as in each data fields in the data row. But my header column cells’ width don’t match the width of its respective column data. I tried to force the width in the header tag, but seems no effect. Anybody know how to adjust each header column width so that it will match each filed in the bottom data width automatically?


  11. Love the Plug in. This is really great work, simple, fast, all the things a lazy programmer loves. I am having One problem. It is not respecting my column widths set in the header. I am using the latest from SVN. I have a fairly large table. The first couple columns in the header have no text and it seems like the width is auto. Any help would be very much appreciated. Below is an example of the header. I am using IE7. The project is an project and the table is built dynamically.

    Col 1
    Col 2
    Col 3
    Col 4
    Col 5

    • Looks like a problem with IE’s box model. The work around here is to add css margin for each child element in a row when the box model is not W3C.


      if (!$.support.boxModel) {
      $(‘.sfhtTable’).find(‘th, td’).css(‘padding’,’8′);


  12. Hi, first to all, congrutulations for this plugin, I have a question, my table has 16 columns and only check the firts 11 columns, how can I do to select all the columns when load the plugin?

    • Thanks for comment.

      To select all columns on page reload, use the function with 3 arguments.

      $(tableID).scrollableFixedHeaderTable(widthpx, heightpx, showSelect)

      The cookie name here is absent so the plugin will not load the select state from the cookie.

      • Thanks very much.

  13. Hi Boss,

    Its a great job. I am developing a grid using this component and its very helpful to me, But now am stuck with sorting. I have tried to integrate “jquery.tablesorter.js” but its not working with “jquery.scrollableFixedHeaderTable.js”. Could you help me on this issue? I want to sort the table with “jquery.tablesorter.js” once I have achived I can share the same with you. Please respond at the earliest.

    Thanks and Regards
    Kerala Web Designer

  14. i think that was great.
    but i still found a little bit that you missed up, width of header is different with the data, just little in the end.

    • Yeah it’s still getting a little messed up when integrating the column select boxes with tablesorter plugin after de/reselecting columns.
      It has something to do the tablesorter theme’s borders and paddings.

      You can make your own tablesorter theme like this simplified one

      table.tablesorter thead tr .header {
      background-image: url(bg.gif);
      background-repeat: no-repeat;
      background-position: center right;
      cursor: pointer;
      table.tablesorter thead tr .headerSortUp {
      background-image: url(asc.gif);
      table.tablesorter thead tr .headerSortDown {
      background-image: url(desc.gif);
      table.tablesorter thead tr .headerSortDown,
      table.tablesorter thead tr .headerSortUp {
      background-color: #8dbdd8;

      This css has no borders and paddings that reduces the effect of messing up the widths. You can safely add padding-top and padding-bottom.
      The rest are adjusting your th and td widths to accomodate the header text and the background image.
      Hope this helps.

  15. i was run from IE 8.0.6001.18702
    little bug

    • Oh that’s weird. The header’s floating over the vertical scrollbar. The floating header width was also miscomputed to be shorter the table width. Nice one ?:) We use the same IE 8 version but that screen shot was not similar to mine.

      Try clearing the cache and reload the page. Hope this helps.

  16. Great tablesorter and scrollable table combo! You even got an simple theme, just what I’m looking for.

    Thanks dude!

  17. Hi, I use FF3.6.6. When I use your example, the cell header background and the arrows doesn’t refresh correctly. When I click on a header column, the sorting is processed but the background of cell header is not refreshed. If you click again, the cell is repainted but the behaviour is not perfect. Any Idea??
    thanx for your help, Leon
    PS: I have the same problem on IE…

    • There was something wrong with the original startup script. It did not sync headers properly and it sync only the clicked header. The tablesorter’s bind(‘sortEnd’, callback) where callback syncs all headers did the trick. Here’s the new startup script. The blog content and live demo will be updated.

      $('#myTable1').scrollableFixedHeaderTable(800, 200, true, 'mycookie');
      $('#myTable1').tablesorter().bind('sortEnd', function(){
      var $cloneTH = $('.sfhtHeader thead th');
      var $trueTH = $('.sfhtData thead th');
      $(this).attr('class', $($trueTH[index]).attr('class'));

      /* synchronize sortable and scrollable */
      $('.sfhtHeader thead th').each(function(index){
      var $cloneTH = $(this);
      var $trueTH = $($('.sfhtData thead th')[index]);
      $cloneTH.attr('class', $trueTH.attr('class'));

  18. Hi, great plugin.

    but I got an error because I had div in my header’s th.

    I corrected the problem by modify the following lines

    like this

    • The plugin’s still getting improved and reduced.
      Thanks for the contribution. This will make the plugin more generic. I’ll merge this code with the next release with your name on it.

  19. Love the ease of use.

    One problem…LINKS from within the table don’t work. Any ideas?

  20. This blog keeps me busy. Thanks all.

  21. Thanx a lot Jerome. Now the compliance between scrolling and the sorting is perfect. I’ll definitly use it on the website i’m working on.
    Sincerely, Leon

  22. Hi. Seems to work reasonably well. Can get it to work as I want on FF/Safari/Chrome but have a problem running on IE8 in IE7 compatibility mode (though also happens in IE8 & IE6 modes) – the top arrow of the scroll bar is hidden behind the header row as the header row extends fully to the right-hand side of the enclosing box. This also screws up the horizontal scrolling column alignment as the header row is then wider than the data.

  23. Hm, just loaded it to the customer’s website and find I have the same problem with FF now. The data is different and the columns are therefore different widths. I’m not going to set fixed column widths because that’s always been one of the beauties of tables – the browser does the formatting for you so it fits.

    Anyway, can send you the page source if you want to look at it.

    • It seems the vertical scrollbar width was miscalculated by the stock dimensions api.
      Please make sure that the path to jquery dimensions is present.
      <script type="text/javascript" src="{path to jquery dimensions}“></script>

      Hope this helps.


  24. Hi,

    i’ve got it running with tablesorter plugin (including links), but what i find is that it gets VERY slow in rendering with larger amounts of data (like 20s for a 1mb table)…

    Is that a known problem?


    • Yes. The scrollablefixedheader’s floating header transformation is weak against large number of rows. It takes time to transform in-memory copy of the source table before rendering the header and clearing the rest of it. The column takes time to hide/show the selected columns as it loops to all the columns in the row.

      For a 1mb table, which is a little to big for an ideal web page, JQuery’s $(document).ready(function(){…}) will take longer to wait for the document to be ready before executing the ready scripts.

      I’m already working for a fix to speed up the transformation of scrollableFixedHeader table by using an extract method where the key is for JQuery to extract the tag and the list of attributes instead of the entire node.

      You may ask the author of tablesorter about the loading problem for large tables.

      I suggest reducing the size of your table to improve load times and performance.

      • Hi,
        ok, thx for the info.

        1. I am not using the column chooser
        2. The # of columns is small, its just a lot of rows
        3. The table itself with tablesorter only loads ok (and sorts more or less ok too). Its only the problem that sfh is blocking the page – is there a way to execute js nonblocking?
        4. Without haveing given it much thought – why do you need to copy the source table at all and cant just copy the header?
        I thought you’d just grab the header, make a copy and hover the copied header on the absolute position of the original header;)

        Thanks anyway for it,

      • Grabbing just the header is not as easy as it looks. JQuery 1.4.2 still does not have the function to do so (or perhaps I’ve overlooked something). JQuery’s method returns an array of nodes where each node includes its children. I was trying to emulate FireBug’s console.log(node) to display the tag and attributes only and use the result string to create an element to be used as a header.
        The method I was still working on was (1) get the tag name, (2) and copy all the attributes. JQuery does not have a listAttributes() function similar to dojo’s so I was wondering on creating my own or checking out the jquery-list-attributes plugin. There was in improvement in extracting the headers. It had problem with IE 8 where you should force the page to render in strict or standards mode. These fixes will be added soon on the plugin’s svn repo.

    • The latest version includes speed improvement. This may solve the issue with the 1mb table.

      • Hi,

        the performance is not really better… maybe slightly but still rather slow

        And another questions – in ie6 my fixed header is not in the correct position – instead its moved by half the width to the right – it works ok in ie8/ff


        var curW=$(‘#ttable’).outerWidth(true);
        var he=(screen.height * 0.7);
        if (he < 400)
        $('#ttable').scrollableFixedHeaderTable(curW, he);
        //fix for ie
        if (!$.support.boxModel) {
        $('.sfhtTable').find('th, td').css('padding','8');

        Any idea?

        Thanks a lot,

      • Get the latest source from the trunk. It should be faster.

      • Just to let you know, the culprit was a stray text-align:center in a css file – strange it aligned the whole header though.

        And the latest code with the custom list-attributes is way faster now – thanks 🙂

  25. I have an issue, and this seems to be across all the jquery floating header plugins.

    Say for the table header we have sub headings how would we do this with your script? Or is this impossible to do so?

    • I see, most header table plug ins queried all the rows in the target table including rows from a sub table in a header.
      The original line looks like this.
      which gets all the tr elements including the ones in your subtable.

      Querying just the children fixed the problem with the replaced line.
      $clone.children().first().find('theader, tbody').first().children('tr:gt(0)').remove();

      The sub header issue is now fixed at the latest trunk version.

      Using the large table fix seems to solve the problem too, but it had issues with IE doc types.

  26. Hi. Great tool! I would like to have a row highlighted when I click on it, but the onclick event doesn’t seem to be able to change style or bgcolor. Any hints? thanks

    • This code toggles row highlight when clicked. You might want to fill in gaps when ctrl or shift key is pressed.

      .highlight {
      background-color: yellow;
      var $row = $(this);
      if (event.ctrlKey) {
      // code when ctrl key is held
      else if (event.shiftKey) {
      // code when shift key is held
      } else {
      if (!$row.hasClass('highlight')) {
      } else {
      $row.parent().children(':not(:nth(' + index + '))').removeClass('highlight');

      You may try other plugins like jquery colorize.

  27. hi,

    First thanks for this wonderfull job.

    I wonder if ther is a way to have fixed bottom like fixed header? I need to fix the last rowl of the table coz there are the total of the columns.



  28. Hi,

    It’s nice code. But i found one bug in this code. when you split header TD in table, it will show two header rows and one row is fixed and other one will move. Any idea??

    • The current implementation targets only the first header. On your case splitting the header shows only the first row header to be floating. However, it is still possible to have multi-row headers to be fixed and scrollable with a little code modification. It only works without the list-attributes plugin. Do not include the list-attributes plugin yet if you want multirow headers. Integration with list-attributes is on-going. So, Here you go.

      You can get the r13 of scrollalbeFixedHeaderTable.js from

      Go to line 263 of scrollableFixedHeaderTable.js
      $clone.children().first().find('theader, tbody').first().children('tr:gt(0)').remove();

      Change the highlighted number to the number of header rows (zero-based). If you wan two header rows you can modify the line to
      $clone.children().first().find('theader, tbody').first().children('tr:gt(1)').remove();

      Refresh your page and see the results. You may clear your cache if the browser still gets the old plugin.
      You can stay tuned for the next trunk commits for that out-of-the-box feature.
      Hope this helps.

    • Added multirow headers to feature list. You can check out the latest source for that out of the box feature. See Mulitrow headers section of this blog

  29. Hi,
    This is a good plugin and almost works perfect. But there is an issue when you use it insite a jquery tabs. For some reasons it sets the width of “th” to zeros.

    I had to use a fixed table-layout and use a fixed width in all columns and manually re-set the width of the first row after calling scrollableFixedHeaderTable to make it to work?

    Any help would highly be appreciated.


    Behnam Divsalar

    • You can programmatically set the computed width of your table if width is not specified with this script.

      $(‘#_myTable’).attr(‘width’, $(this).width());

      Then call the scrollableFixedHeaderTable before tabs.

      I guess that in your case, calling tabs first fitted the table into the tab area. After calling, The floating header’s width is the fitted width while the width of the table is the parameter width.

      I’ve already included the fix on the repository. You might as well download the latest source jquery.scrollableFixedHeaderTable.js

      • Thanks for the quick reply. I cannot call scrollableFixedHeader before tabs because the table content is requested by ajax when the tabs are clicked.
        Because of the page size, I had to bring the page content partially when the tabs select is fired. When I received the table content in success handler, call scrollableFixedHeader then replace it with a busy image in selected tab and finally reset the width .

  30. I had the same problem with the width of the header (using Mulitrow headers), fix it by putting a new table inside each head and the width is perfect fit.

  31. This is nice plugin. Thanks for share this with the world.
    I have multiple tables with tablesorter. it works fine on firefox. I have an issue with IE 8,

    $(“.sfhtHeader thead th”).each(function(index){
    var $cloneTH = $(this);
    var $trueTH = $($(“.sfhtData thead th”)[index]);
    $cloneTH.attr(“class”, $trueTH.attr(“class”));
    $(this).attr(“class”, $trueTH.attr(“class”));
    the ‘index’ variable is always 0 on IE. Please help me. It considers just first th and goes on to the second table first th. It doesn’t iterate through all the th of first table.


  32. Hello Jerome,

    Thanks for the cool plugin. I have been unable to make this work properly in my app. I tried adding to an app that already used tablesorter, but once I worked the display kinks out, I found that no matter what column I clicked, the sort would be on the last column.

    This may have something to do with it….I’m using XML/XSLT to build the page dynamically prior to initiating tablesorter and sFHT. If I insert the built HTML into a static page, all works fine. Any thoughts?

    • Hey Jerome…I fixed that problem. Had some style conflicts. Now everything is great except as I approach the right side of the table when there is horizontal scrolling. The last few pixels of movement have the header sliding less than the table detail. At the rightmost point of scroll the column alignment between headers and detail is slightly off. Working on that now.

      • LOL!
        Finally got that one fixed Now I’ve noticed that no matter which column is clicked, the sorting is done on the last column. ARGHH!!!

  33. i have included latest script and list-attributes. But the speed still seems to be very slow for 1000 rows. Any advise.

  34. Thanks for the work on this plugin; very useful. Any plans to add the ability to stick a footer to the bottom of the table in ? Also, an ability to freeze horizontal rows would be awesome!

    • Sorry, should have known html would get stripped out of my last comment. I was referring to placing the footer info in the “tfoot” tag.

  35. This looks fantastic, but I can’t get it to work. I’m seeing my headers duplicated. Looking at the html, it looks like you generate a table where the first row is the headers and the second row is my complete table, still with the headers.
    And I’m not getting the scrolling happening. I’ve looked at all the examples and can’t figure out what’s wrong.

  36. Great Artical. Thanks a lot

  37. Hi,

    Nice Work. Your code works fine in Chrome.

    I have also implemented similar functionality using CSS and JavaScript.
    Scrollable Table

    Please let me know if You have any suggestions for me 🙂


  38. Thanks for your work. It is a nice plugin.

    I am facing several problems now. Maybe someone can help me.
    The problem occurs in between IE7 (maybe also IE6) and IE8.

    1) In IE7 if the overflow occurs in the shftbody div, the fixed header is not correctly alligned with the shftbody. Is there a way to align it?

    2) If I started with a empty table and use javascript to append rows to the tbody by means of append …, then if overflows occurs the following happens.

    – In IE7 the top of the scrollbar is covered by the fixed header.
    Is there a way to make the whole scrollbar visible?

    – In IE8 the header is not alligned anymore, but the scrollbar is visible. Is there a way to allign it with the cells in the body?

    Thanks in advance.

    Kin Shing Choy

  39. Hello. I have tried the codes and it’s work! thanks alot!.
    May I ask, can this codes use with JQuery Dialog ( ?

    I’ve tried but failed. The table is still can be sortable with fixed header, but the dialog is not functioning when a user click one of the row in table. Can someone help?

  40. First off, thank you for the excellent plugin, and more specifically, the great integration with the TableSorter plugin.

    A few things I can’t seem to resolve – can these tables be variable width? I would assume so since the Dimensions plugin is being used, but nothing I’ve found so far seems to indicate it can use a percentage or variable width versus a fixed pixel value.

    Secondly (and this may be more for the TableSorter plugin creator than yourself) – I’ve tried adding some of TableSorter’s features like widgets (specifically the zebra striping) and it works, but it breaks the sorting (the first click sorts, but then on subsequent clicks the sort fails). Putting the attributes in like default sort column and removing sorting from certain columns works by using inline metadata (detailed on the TableSorter plugin page), but I didn’t find anything about Zebra Striping. Any advice/help you could provide to point me in the right direction is appreciated.

    • The table cannot be variable in width using percent. The plugin injects the computed width in pixel in table transformation and the floating header on the first row. It may be possible to have variable length using the javascript onresize() function on the table’s parent node and retransform the table again.

      The tablesorter integration only works with one sorting as you cannot use a shift+click on the headers. The scrollable headers simply call the click() function of the table sorter’s header the it covers. The tablesorter header clicks does not detect if the caller has shift, or control keys pressed because the function does not take any arguments.

      In order to have subsequent sorting, the tablesorter’s code header click() function should be customized to take arguments if a shift key is pressed. Then the code body of the function too should be modified.

  41. I have upgraded the jQuery to 1.4.3 and this plugin fails on a table with more than 200 rows.
    I am getting javascript popup:

    “Stop running this script?”
    A script on this page is causing Internet Explorer to run slowly. If it continues to run, your computer might become unresponsive.

    • Have you tried with list-attrs plugin. It fixed some issues with thousands rows with jquery 1.4.2. Looks like I’ll bump this plugin support Jquery 1.4.3.

      • First of all, good plugin, a nice job.
        In IE7 I have tried to fix the problem , but i couldnt, using the list-attrs plugin, and I am getting javascript popup:

        “Stop running this script?”…..etcetera.
        There is a problem too, when you display a table with inner table in any of tds….but using the selector table:first when the main table you pass to function adjustTable, you fix the problem….

  42. First of all great work! Thank you very much for this plug-in specially list-attrs plugin for large tables.

    Now I am trying to create a table with fixed header and column with storable functionality. But some how it is not working for me. So could you please let me know if you have and plug-in for fixed header & column (only 1st column) with sorting?

    This would be really helpful for me and thanks in advance for your help on this.

    • What do you mean storable? You can use cookie to store a state and reload the state on page load.

      • Sorry.. my bad! I mean Sortable.

      • Sorry.. my bad! I mean Sortable.

        Hi.. hope you understand my requirement clearly. Once again I am mentioning my requirement. I need a table with fixed header and the 1st column of the table will also be fixed. Moreover I need the table should be sortable by column headings.

      • Hi jeromebulanadi! Any updates on this?

      • oh yeah! You needed is a freeze column similar to spreadsheets. I’ll try coding my solution and get back to you. You may try some jquery freeze column plugins.

      • here you go.
        Just look at the section on the solution. It’s kind of dirty and unoptimized yet. The fixed column can be a future add-on to this plugin.

      • Thanks a ton jeromebulanadi.

  43. Just downloaded. I am gonna try it

  44. Nice plugin. I’m testing it on my setup integrated with tablesorter. One thing I’ve noticed is that it’s not compatible with jQuery.noConflict() which is a must on a site I’m thinking of using this on.

    I’ve gotten around that by changing the “$” references in your script to “jQuery” and it works that way but just as a usability suggestion, it may be nice to make this plugin compatible with noConflict.


  45. Hi,
    Great work. This is the solution i was searching for the past two months.
    I implemented this solution in my application. I want alternate colors for table rows. On loading the table for the first time, alternate color is coming. If i sort a column, alternate colors got messed up.Colors are not changed.My other issue is i want sorting for only 2 columns.could you please give me some idea on how to achieve these?

  46. Hi Jerome,

    Nice Plugin. I was searching for this for past two months. I implemented this solution in my application.I got fixed header for my application. works great in all browsers. But i have some issues.First one i assigned alternate colors to table rows. When i load the table colors are coming. If i sort columns, alternate color is lost. Other problem is sorting. I do not want sorting for all columns. Could you please help me to resolve this issue?


    • You need to use a zebra widget from table sorter for the alternate color.
      Use the headers configuration to disable selected columns.

      Here’s my example for my sortable green.

      Zebra widgets use even and odd classes for tr elements on a sorted table.

      .even td {background-color: #CCCCCC;}
      .odd td {background-color: #FFFFFF}

      You can define the configuration map for tablesorter to add a zebra widget and headers config

      var configMap = {
      widgets: ['zebra'],
      /* headers 2 to 10 (0-based) are disabled for sorting */
      headers: {
      2: {sorter: false},
      3: {sorter: false},
      4: {sorter: false},
      5: {sorter: false},
      6: {sorter: false},
      7: {sorter: false},
      8: {sorter: false},
      9: {sorter: false},
      10: {sorter: false}

      Use the configuration as an argument to initialize table sorter

      $('#myTable1').scrollableFixedHeaderTable(800, 200, true, 'mycookie');
      $('#myTable1').tablesorter(configMap).bind('sortEnd', function(){
      var $cloneTH = $('.sfhtHeader thead th');
      var $trueTH = $('.sfhtData thead th');
      $(this).attr('class', $($trueTH[index]).attr('class'));

      • Thank you very much.It worked for me.. thanks.

      • Hi Jerome,

        I am facing another issue in my table. I implemented drag and drop using jquery. Previously it was working. After implementing your plugin, its not working. Do you have any idea? could you please help me out?


      • Hi Bhuvana,

        It’s a common bug when mixing many jquery plugins together, but there’s always a workaround.

        Did you implement the drag and drop inside the table? If so, the table tranformation of my plugin and the tablesorter must have messed up with the drag and drop. My plugin transforms the table by wrapping divs for the original table and the fixed header. The tablesorter transforms the table by modifying the headers and adding extra classes in the tr tags, then rearranges the tr tags on sort. Some events bind before the transformation may be lost or relocated somewhere on the page after the transformation. You may see some error messages on the console of your firebug or IE developer tools which can be helpful in tracking the bugs.

        For your solution, You may try applying your drag and drap after the scrollableFixedHeader and tableSorter plugin. This has always worked for me when mixing jquery plugins together. Some what in this sequence:

        $(document).ready(function() {

        scrollableFixedHeader(); tableSorter(); dragDrop();


        Regards, Jerome

  47. Can you please help me with Freeze first Column and fixed Header for ASP.NET grid control .

    • I can help if I know the generated html of that grid control. I have poor background so I’m not sure what html does your grid control generate.

  48. Hi Jerome,

    Thanks for your quick reply. It helped me a lot. Now I got another issue. I have calendar components in one column in my table. Without invoking the function
    $(‘#myTable1’).scrollableFixedHeaderTable(945, 399);
    Calendar object is working. But there is no scroll in the table. Table is displayed without scroll.But sort is working. If i include that line,calendar object is not working. I am not getting errors also.but fixed header with scroll is working well.

    My datepicker component is like below

    <input type="text" name="displayDate" size="26" class="datePick" id="startDate” value=””/>

    To invoke calendar, used the following script

    changeMonth: true,
    changeYear: true,
    showOn: “button”,
    buttonImage: “images/cal.gif”,
    buttonImageOnly: true,
    showButtonPanel: true,
    minDate: new Date(1950,11,31),
    maxDate: new Date(9999,11,31)

    could you please help me to resolve this issue?

    • Hi Bhuvaneswari,

      I did not encounter much problem combining drag and drop, fixed headers, zebra tablsorter with selected columns, and date picker. Most of the problems where just css conflicts which can be fixed by tweaking css files, and sequence of plugins executed.

      Here’s the sequence I did. scrollableFixedHeader tableSorter drag and drop datepicker

      you can see the attached file for the demo.

      I will checkout your last attachment to see what went wrong.

      Regards, Jerome Bulanadi

  49. hi Jerome, I really like this plugin but is it possible to freeze at least 4 column instead of just one and still make them sort? I’ve been looking for that everywhere but couldn’t find any and this plugin is more close what I’m looking for


  50. hi Jerome,

    Thanks for the great plugin.

    I am wondering whether I can disable hiding the first few columns of a table (instead of allowing users to hide/show ALL the columns of a table). I’d searched through your blogs, however I could’t find any clue on it. I am looking forward for your reply. Thanks a lot.


    • You can hide or disable the checkboxes using jquery selector, after the table transformation. The selector for column select is $(‘yourTableID_columnSelect’).
      In this Example, the selector selects the first 3 check boxes. The next chained function hides or disables the selected checkboxes. Hope this helps.

      /* hide the checkboxes */
      $(‘#_myTable1_columnSelect input:checkbox:lt(3)’).hide();

      /* or disable the checkboxes */
      //$(‘#_myTable1_columnSelect input:checkbox:lt(3)’).attr(‘disabled’,’disabled’);

      • Thanks a lot.

  51. Hi Jerome

    Awesome component, I’m running into a problem that might be some work around for that, you’ll see, the thing is i don’t know the width of “MyTable” at the very first time I’m creating the columns in the backend, waiting for the document to be ready and then applying the component,

    Then for example if I have only like 4 columns everything gets mess up if I set up the width for the table to handle 10 columns and also the other way,

    any suggestions ?

    thanks in advance,

  52. I do something like this where map is the parent element and it grabs the width from that.(this is also using both this and table sorter so YMMV) also some extra stuff at the end that is probably useless for you but it’s something for you to play with.

    Hopefully this is useful to you

    jQuery("#resultsTable").scrollableFixedHeaderTable(jQuery("#map").width()-5, 200);
    jQuery("#resultsTable").tablesorter({widgets: ["zebra"],
    headers: {
    0: {sorter: false}, 1: {sorter: false}
    }).bind("sortEnd", function(){
    var $cloneTH = jQuery(".sfhtHeader thead th");
    var $trueTH = jQuery(".sfhtData thead th");
    jQuery(this).attr("class", jQuery($trueTH[index]).attr("class"));

    /* synchronize sortable and scrollable */
    jQuery(".sfhtHeader thead th").each(function(index){
    var $cloneTH = jQuery(this);
    var $trueTH = jQuery(jQuery(".sfhtData thead th")[index]);
    $cloneTH.attr("class", $trueTH.attr("class"));
    if (jQuery("#searchName").val() == "") {
    jQuery("#searchName").val("New Search");
    jQuery.cookie("last_search",jQuery("#searchForm").serialize(),{expires: 1000});

  53. Dear Jerome,

    Thanks for the great plugin.

    I am wondering whether I can set the width of all the columns of a table to a specific value when calling your plugin?

    I tired to set the width of the table header columns and table data columns, and it seems the parameters were overridden.

    Any parameters settings that allow me to do? Thanks a lot.


  54. Great Plugin! One question i am using it with tablesorter plugin and wanted to add keyboard support. I see that when i use the keydown it triggers the following

    $sfhtData.scroll(function() {

    How can i get the key, row or cell user was on and pass it to my custom function ?

  55. Thank you. Great plugin.

  56. Thanks this is a great plugin, i was breaking my head for this. Got sucess..

  57. Hi, there is an error in the instructions – #2 under Getting Started.

    “The table’s class attribute should have “scrollableFixedHeader” as one of the values.”

    The class should be “scrollableFixedHeaderTable”. The example has it correct, but the mistake in the directions let me to a couple wasted hours.

  58. It is a very nice plugin, thank you and I’ll give a donation if possible. It works very well in Firefox and Chrome, and for small tables in IE.

    It does have a performance problem with large tables and Internet Explorer (8), can be seen with the big demo here. It takes more than 10 seconds to render.

    I’m trying to find out how to fix that performance problem, and will post back here if I can. I’m cutting and dicing the code in a binary search to find the slow bit, at the moment! (it’s easier and usually quicker than thinking about it!)

    I suppose there is some quadratic complexity going on, the jquery searches have to hunt through the whole DOM in IE or whatever.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create a free website or blog at
Entries and comments feeds.

%d bloggers like this: