Friday, February 3, 2012

Freezing table header with JQuery

When you have long table on page, with a lot of numbers, and you scroll down and header is not visible anymore, it is often difficult to track what number is which column. One nice solution to this problem is to lock and freeze table header when scrolling page.
Unfortunately there is no ready out of the box solution with JQuery for this problem. Fortunately, it is easy to implement with few methods. There are examples how to do it, but for some reason they didn't worked well in my situation (no support for resize and horizontal scroll), so I have adjusted them for my situation.

For example, you have your table named tabs.

First, you have to create invisible table that will hold frozen header.

<table cellpadding='0' cellspacing='0' id="header-fixed"  style="position: fixed; top: 0px; display:none;"></table>

Then just add this Javascript:

     <script type="text/javascript">
       var tableOffset;
       var header;
       var fixedHeader;

       function resize() {
         var totalwidth = $('#tabs').css('width');
         fixedHeader.css('width', totalwidth);
         var widths = [];
         $('#tabs thead th').each(function() {
           widths.push($(this).width());
         });
         var i=0;
         $('#header-fixed th').each(function() {
           this.width = widths[i];
           i++;
         });
       }
       function resizeAndShow() {
         var offset = $(this).scrollTop();
         if (offset >= tableOffset && fixedHeader.is(":hidden")) {
           fixedHeader.show();
           resize();
         } else if (offset < tableOffset) {
           fixedHeader.hide();
         }
         fixedHeader.css('left', $('#tabs').position().left - $(this).scrollLeft());
       };
        $(document).ready(function() {
          tableOffset = $("#tabs").offset().top;
          header = $("#tabs > thead").clone();
          fixedHeader = $("#header-fixed").append(header);

          $(window).bind("scroll", resizeAndShow);
          $(window).resize(resize);
        });
     </script>

This is it.

1 comment:

  1. Hi, need a help
    for IE and FireFox i have done fixed header and it works good but the same coding doesnt work in chrome
    for IE i have done with the help of css top:expression(this.offsetParent.scrollTop);
    and in Firefox i have done in css by mentioning the thead to display:block
    this doesnt work in chrome
    can anybody help me please
    really i am fed up and got tensed
    please do me the favour

    ReplyDelete