One of my client wanted to display financial reports data with better accessibility and printing usability. He asked me to retain table header fixed on the top while scrolling financial reports.  He also wanted to have MS Access VBA style multicolumn drop-down component for large customer database. In this post I am writing about that fixed table header component which I have coded in jQuery.

By default, If you print any HTML table…

  • the <TH> row get printed on top of every pages that contains the table.
  • <TFOOT> row get printed on every page’s footer.
  • <THEAD> row get printed on every page’s header.

For printing we have chosen fixed width fonts i.e. Courier New.

Demo tutorial page: Demo for jQuery stickyTable plugin

Download: jQuery stickyTable plugin zip file

Initializing jQuery stickyTable plugin

$(document).ready(function(){
	$('#report_table').stickyTable();
});

Above function binds StickyTable plugin to supplied table.

jQuery.stickyTable.js plugin source

(function($){
$.fn.stickyTable = function() {
  if ($(this).length == 0) {
    throw new Error('jQuery.stickyTable ERRORnnAttribute id="'+ $(this).selector.replace("#","") +'" NOT FOUND in your webpage.');
    return;
  }

  function equilize_width() {
    var ths = $('#report_table')[0].rows[0].cells;
    var thd = $('#stickyfixed')[0].rows[0].cells;
    for(var j=0; j < ths.length; j++) {
      $(thd[j]).width($(ths[j]).width()-1);
    }
    $('#stickyfixed').width($('#report_table').width()+4);
  }

  $(this).parent().append("<div id='stickyfixed_container' class='hide'><table id='stickyfixed' class='report_table' border='1'></table>&ly;/div>");

  $('#report_table tr:first').clone().appendTo('#stickyfixed');
  equilize_width();
  var cutoffTop      = $('#report_table').offset().top;
  var cutoffBottom  = $('#report_table').height(); + cutoffTop - $($('#report_table')[0].rows[0].cells[0]).height();
  var no_fixed_support = false;
  if ($('#stickyfixed').css('position') == "absolute") {
    // IE 6 hack
    no_fixed_support = true;
  }
  $('#report_table tr').hover(function() {
      $(this).addClass("highlight");
    },function() {
      $(this).removeClass("highlight");
  });

  //Handling windows resize
  $(window).resize(function(){
    equilize_width();
  });

  $(window).scroll(function(){
    var currentPosition = $(document).scrollTop();
      if (currentPosition > cutoffTop && currentPosition < cutoffBottom) {
        $('#stickyfixed_container').show();
          if (no_fixed_support == true) {
            // IE 6 hack
            document.getElementById('stickyfixed').style.top = parseInt(currentPosition) + "px";
          }
      } else {
    $('#stickyfixed_container').hide();
   }
  });
  return $(this);
 };
})(jQuery);

SCREEN.CSS

/* CSS for screen */
body,*{font-family:Tahoma}
h1{padding:0px;margin:5px;font-size:22px}
h1{padding:0px;margin:5px;font-size:22px}
#header{padding:10px;font-size:24pt;font-weight:bold;font-family:Arial,sans-serif;border-bottom:1px solid #DDD;text-align:left;margin:0px}
#report *{font-family:Tahoma;font-size:8pt}
table.report_table{border-collapse:collapse;border-spacing: 2px;border:2px solid #FFF;width:100%;overflow:scroll;background-color:#FFF;font-size:10pt;}
table.report_table th{padding:5px;background-color:#3B5998;color:#FFF}
table.report_table tr td{padding:5px;background-color:#F3F3F3;border:1px solid #FFF;}
table.report_table tr.highlight td{padding:5px;background-color:#B0D4F7;color:#000;}
table#stickyfixed{z-index:10;position:fixed;_position:absolute;top:0;font-size:10pt;}
table#stickyfixed th{}
.hide{display:none;}

PRINT.CSS

/* CSS for print */
body,*{font-family:Courier New;font-size:11px}
h1{display:none;font-family:Times New Roman;padding:0px;margin:5px;font-size:18px}
#report *{font-family:Courier New}
table.report_table tr th{font-size:14pt}
table.report_table tr td h3{font-size:12pt}
table.report_table td{overflow:hidden;white-space:nowrap;}
#member_links{display:none}
table#report_form{display:none;}
table#stickyfixed{display:none;}