// Author: Jerome Clyde C. Bulanadi jQuery.fn.scrollableFixedHeaderTable = scrollableFixedHeaderTable; sfht = {}; function scrollableFixedHeaderTable(widthpx, heightpx,headerRowSize,footerRowSize) { /* table initialization */ if (!jQuery(this).hasClass('scrollableFixedHeaderTable')) return; var $this = jQuery(this); /* fix width for tables witout width attribute */ $this.attr('width', $this.width()); if (heightpx > $this.height()) return; $this.wrap('
'); headerRowSize = headerRowSize ? headerRowSize - 1: 0; headerRowSize = Math.floor(headerRowSize < 0 ? 0 : isNaN(headerRowSize) ? 0 : headerRowSize) ; footerRowSize = footerRowSize ? footerRowSize: 0; footerRowSize = Math.floor(footerRowSize < 0 ? 0 : isNaN(footerRowSize) ? 0 : footerRowSize) ; var $parentDiv = $this.parent(); var $fixedHeaderHtml = sfht.cloneHeader($parentDiv, headerRowSize); var $srcTableHtml = $parentDiv.html(); var $fixedFooterHtml = sfht.cloneFooter($parentDiv, footerRowSize); $this.before('
'); $parentDiv.find('div:nth(0)').html($fixedHeaderHtml); $parentDiv.find('div:nth(1)').html($srcTableHtml); $parentDiv.find('div:nth(2)').html($fixedFooterHtml); var headerId = $this.attr('id') + '_header'; var $sfhtHeader = $parentDiv.find('.sfhtHeader'); var $sfhtTable = $sfhtHeader.find('table').attr('id', headerId); var footerId = $this.attr('id') + '_footer'; var $sfhtFooter = $parentDiv.find('.sfhtFooter'); var $sfhtTable2 = $sfhtFooter.find('table').attr('id', footerId); $this.remove(); var $sfhtData = $parentDiv.find('.sfhtData'); $sfhtData.height(heightpx).width(widthpx); var $mainTable = $sfhtData.find('table'); var mainTableId = $mainTable.attr('id'); /* synchronized scrolling */ $sfhtData.scroll(function() { $sfhtHeader.scrollLeft(jQuery(this).scrollLeft()); $sfhtFooter.scrollLeft(jQuery(this).scrollLeft()); }); /* adjustments */ sfht.adjustTables($sfhtTable, $mainTable, headerRowSize,footerRowSize,$sfhtTable2); sfht.adjustHeader($sfhtHeader, $sfhtData, $mainTable, headerRowSize); sfht.adjustFooter($sfhtFooter, $sfhtData, $mainTable, footerRowSize); var table_lenght = $mainTable.children().attr('rows').length; $mainTable.children().children('tr:gt(' + eval(table_lenght-footerRowSize-1) + ')').remove(); } sfht.adjustHeader = function($sfhtHeader, $sfhtData, $mainTable) { var containerWidth = $sfhtData.width(); var containerInnerWidth = $sfhtData.innerWidth(); var scrollBarSize = containerWidth - containerInnerWidth; var dataTableWidth = $mainTable.width(); if (!(jQuery.browser.mozilla || jQuery.browser.msie || jQuery.browser.opera)) { containerInnerWidth = dataTableWidth >= containerWidth ? containerWidth - 17 : containerWidth; } if (dataTableWidth >= containerInnerWidth) { $sfhtHeader.width(containerInnerWidth); } else { $sfhtHeader.width(dataTableWidth); } } sfht.adjustFooter = function($sfhtFooter, $sfhtData, $mainTable) { var containerWidth = $sfhtData.width(); var containerInnerWidth = $sfhtData.innerWidth(); var scrollBarSize = containerWidth - containerInnerWidth; var dataTableWidth = $mainTable.width(); if (!(jQuery.browser.mozilla || jQuery.browser.msie || jQuery.browser.opera)) { containerInnerWidth = dataTableWidth >= containerWidth ? containerWidth - 17 : containerWidth; } if (dataTableWidth >= containerInnerWidth) { $sfhtFooter.width(containerInnerWidth); } else { $sfhtFooter.width(dataTableWidth); } } sfht.adjustTables = function($sfhtTable, $mainTable, headerRowSize,footerRowSize,$sfhtTable2) { var tdWidthArr = new Array(); var adjTableWidth = 0; var totalWidth = 0; var idAdjWidth = sfht.getSfhtVar($mainTable.attr('id')); //var id = '#' + $mainTable.attr('id'); // IE compatibility var id = $mainTable.attr('id'); //var queryStr = id + ' tr:nth(0) td'; var idPrefix = 'table[id=' + id + '] tr:lt(' + (headerRowSize + 1) + ')'; jQuery(idPrefix).find('td, th').each(function(index) { var $this = jQuery(this); var actualWidth = parseInt($this.width()); var attrWidth = parseInt($this.attr('width')); var plusWidth = attrWidth > actualWidth ? attrWidth : actualWidth; totalWidth += plusWidth; tdWidthArr[index] = plusWidth; $this.width(plusWidth); $sfhtTable.find('td:nth(' + index + '), th:nth(' + index + ')').width(plusWidth); }); var idPrefix = 'table[id=' + id + '] tr:gt(' + (eval($mainTable.attr('rows').length-footerRowSize-1)) + ')'; jQuery(idPrefix).find('td, th').each(function(index) { var $this = jQuery(this); var actualWidth = parseInt($this.width()); var attrWidth = parseInt($this.attr('width')); var plusWidth = attrWidth > actualWidth ? attrWidth : actualWidth; totalWidth += plusWidth; tdWidthArr[index] = plusWidth; $this.width(plusWidth); $sfhtTable2.find('td:nth(' + index + '), th:nth(' + index + ')').width(plusWidth); }); adjTableWidth = totalWidth; // $sfhtTable.width(totalWidth); // $mainTable.width(totalWidth); /* Register this variable to sfht globals */ sfht[idAdjWidth] = {'lastWidth': adjTableWidth, 'tdWidths': tdWidthArr}; } sfht.getSfhtVar = function(id) { return id + 'Widths'; } sfht.getFixedHeader = function(id) { return (jQuery('table[id=' + id + '_header]')); } sfht.getFixedFooter = function(id) { return (jQuery('table[id=' + id + '_footer]')); } sfht.fillState = function (i) { if (i == 0) { return; } state = ''; for (var x = 0; x < i; x++) { state += '1'; } return state ; } sfht.loadAttributes = function(dest, source) { var attributes = jQuery(source).listAttrs(); jQuery(attributes).each(function(){ var at = this + ''; jQuery(dest).attr(at, jQuery(source).attr(at)); }); } sfht.cloneHeader = function(parentDiv, headerRowSize) { var rowIndex = headerRowSize; if (jQuery.fn.listAttrs) { var $container = jQuery("
"); var $clone = $container.find('table:eq(0)'); var tableNode = jQuery(parentDiv).children().first(); sfht.loadAttributes($clone,tableNode); sfht.loadAttributes($clone.children().first(),tableNode.children().first()); var $thead = $clone.find('thead'); for (var _i = 0; _i <= rowIndex; _i++) { var $rowHeaderNode = tableNode.children().first().children(':nth(' + _i + ')'); var $cloneRow = jQuery(''); sfht.loadAttributes($cloneRow,$rowHeaderNode); $cloneRow.html($rowHeaderNode.html()); $cloneRow.appendTo($thead); } return $container.html(); } else { var $cloned = jQuery(parentDiv).clone(); $cloned.children().first().children().children('tr:gt(' + headerRowSize + ')').remove(); return $cloned.html(); } } sfht.cloneFooter = function(parentDiv, headerRowSize) { var table_lenght = jQuery(parentDiv).children().attr('rows').length; var rowIndex = table_lenght-headerRowSize; if (jQuery.fn.listAttrs) { var $container = jQuery("
"); var $clone = $container.find('table:eq(0)'); var tableNode = jQuery(parentDiv).children().last(); sfht.loadAttributes($clone,tableNode); sfht.loadAttributes($clone.children().last(),tableNode.children().last()); var $thead = $clone.find('tfoot'); for (var _i = 0; _i <= rowIndex; _i++) { var $rowHeaderNode = tableNode.children().last().children(':nth(' + _i + ')'); var $cloneRow = jQuery(''); sfht.loadAttributes($cloneRow,$rowHeaderNode); $cloneRow.html($rowHeaderNode.html()); $cloneRow.appendTo($thead); } return $container.html(); } else { var $cloned = jQuery(parentDiv).clone(); $cloned.children().last().children().children('tr:lt(' + eval(table_lenght-headerRowSize) + ')').remove(); return $cloned.html(); } } function replaceOneChar(s,c,n){ var re = new RegExp('^(.{'+ --n +'}).(.*)$',''); return s.replace(re,'$1'+c+'$2'); };