diff --git a/demo/test.html b/demo/test.html
index f5856db..6b701d6 100644
--- a/demo/test.html
+++ b/demo/test.html
@@ -186,7 +186,10 @@
- Browser |
+ Browser |
+ This is merged column |
+
+
Visits |
Pages/Visit |
Avg. Time on Site |
diff --git a/jquery.fixedheadertable.js b/jquery.fixedheadertable.js
index 1d052d8..a6b4fc5 100644
--- a/jquery.fixedheadertable.js
+++ b/jquery.fixedheadertable.js
@@ -561,26 +561,16 @@
tbody: {},
tfoot: {},
border: 0
- },
- borderCollapse = 1;
+ };
- if (settings.borderCollapse == true) {
- borderCollapse = 2;
- }
+ tableProp.border = ($obj.find('th:first-child').outerWidth() - $obj.find('th:first-child').innerWidth())
+ / settings.borderCollapse ? 2 : 1;
- tableProp.border = ($obj.find('th:first-child').outerWidth() - $obj.find('th:first-child').innerWidth()) / borderCollapse;
+ tableProp.thead = helpers._getColumnsWidth($obj.find('thead').children('tr'));
- $obj.find('thead tr:first-child > *').each(function(index) {
- tableProp.thead[index] = $(this).width() + tableProp.border;
- });
+ tableProp.tfoot = helpers._getColumnsWidth($obj.find('tfoot').children('tr'));
- $obj.find('tfoot tr:first-child > *').each(function(index) {
- tableProp.tfoot[index] = $(this).width() + tableProp.border;
- });
-
- $obj.find('tbody tr:first-child > *').each(function(index) {
- tableProp.tbody[index] = $(this).width() + tableProp.border;
- });
+ tableProp.tbody = helpers._getColumnsWidth($obj.find('tbody').children('tr'));
return tableProp;
},
@@ -590,32 +580,200 @@
* Fix widths of each cell in the first row of obj.
*/
_setupClone: function($obj, cellArray) {
- var $self = $obj,
- selector = ($self.find('thead').length) ?
- 'thead tr:first-child > *' :
- ($self.find('tfoot').length) ?
- 'tfoot tr:first-child > *' :
- 'tbody tr:first-child > *',
- $cell;
-
- $self.find(selector).each(function(index) {
- $cell = ($(this).find('div.fht-cell').length) ? $(this).find('div.fht-cell') : $('').appendTo($(this));
-
- $cell.css({
- 'width': parseInt(cellArray[index], 10)
+ var selector = ($obj.find('thead').length)
+ ? 'thead tr'
+ : ($obj.find('tfoot').length)
+ ? 'tfoot tr'
+ : 'tbody tr';
+
+ helpers._trCellIterator(
+ $obj.find(selector),
+ {
+ cell: function(context) {
+ if (typeof cellArray[context.colIndex] !== 'undefined'
+ && cellArray[context.colIndex].colspan == context.colspan
+ ) {
+
+ var $cell = ($(this).find('div.fht-cell').length)
+ ? $(this).find('div.fht-cell')
+ : $('').appendTo($(this));
+
+ $cell.css({
+ 'width': parseInt(cellArray[context.colIndex].width, 10)
+ });
+
+ /*
+ * Fixed Header and Footer should extend the full width
+ * to align with the scrollbar of the body
+ */
+ if (!$(this).closest('.fht-tbody').length && $(this).is(':last-child')
+ && !$(this).closest('.fht-fixed-column').length
+ ) {
+ var padding = Math.max((($(this).innerWidth() - $(this).width()) / 2), settings.scrollbarOffset);
+ $(this).css({
+ 'padding-right': parseInt($(this).css('padding-right')) + padding + 'px'
+ });
+ }
+ }
+ }
+ }
+ );
+ },
+
+ /*
+ * return object
+ * Iterates over cells within given set of rows
+ * Using:
+ * _trCellIterator(
+ * $('#table tr'),
+ * {
+ * beforeRow: function(context){
+ * context.rowCount++;
+ * //return true; // breaks row iteration
+ * },
+ * cell: function(context){
+ * context.cellCount += context.colspan;
+ * //return true; // breaks current row cell iteration
+ * },
+ * afterRow: function(context){
+ * if (context.rowCount > 2) {
+ * return true; // breaks row iteration
+ * }
+ * },
+ * },
+ * {
+ * rowCount: 0,
+ * cellCount: 0
+ * }
+ * );
+ */
+ _trCellIterator: function($trs, callbacks, context) {
+ var rowspanData = {};
+
+ if (typeof callbacks === "undefined") {
+ callbacks = {};
+ }
+ if (typeof context === "undefined") {
+ context = {};
+ }
+
+ $trs.each(function(rowIndex) {
+ var colspanShift = 0,
+ rowspanShift = 0,
+ ret;
+
+ context.rowIndex = rowIndex;
+
+ if (typeof callbacks.beforeRow === 'function') {
+ if (ret = callbacks.beforeRow.call(this, context)) {
+ return false; // break
+ }
+ }
+
+ $(this).children().each(function(colIndex) {
+ var colspan = parseInt($(this).attr('colspan')) || 1,
+ rowspan = parseInt($(this).attr('rowspan')) || 1;
+
+ while (typeof rowspanData[colIndex + rowspanShift] !== "undefined"
+ && rowspanData[colIndex + rowspanShift].rowspan > 1
+ ) {
+ rowspanData[colIndex + rowspanShift].rowspan--;
+ rowspanShift += rowspanData[colIndex].colspan;
+ }
+
+ colIndex += (colspanShift + rowspanShift);
+
+ colspanShift += colspan - 1;
+ if (rowspan > 1) {
+ rowspanData[colIndex] = {
+ rowspan: rowspan,
+ colspan: colspan
+ };
+ }
+
+ context.colIndex = colIndex;
+ context.colspan = colspan;
+ context.rowspan = rowspan;
+
+ if (typeof callbacks.cell === 'function') {
+ if (ret = callbacks.cell.call(this, context)) {
+ return false; // break
+ }
+ }
});
- /*
- * Fixed Header and Footer should extend the full width
- * to align with the scrollbar of the body
- */
- if (!$(this).closest('.fht-tbody').length && $(this).is(':last-child') && !$(this).closest('.fht-fixed-column').length) {
- var padding = Math.max((($(this).innerWidth() - $(this).width()) / 2), settings.scrollbarOffset);
- $(this).css({
- 'padding-right': parseInt($(this).css('padding-right')) + padding + 'px'
- });
+ if (typeof callbacks.afterRow === 'function') {
+ if (ret = callbacks.afterRow.call(this, context)) {
+ return false; // break
+ }
}
});
+
+ return context;
+ },
+
+ /**
+ * return int
+ * Calculates columns count within given set of rows
+ */
+ _getColumnsCount: function($trs) {
+ var ret = helpers._trCellIterator(
+ $trs,
+ {
+ cell: function(context) {
+ context.count += context.colspan;
+ },
+ afterRow: function(context) {
+ if (context.count > 1 || context.rowspan == 1) {
+ return true;
+ }
+ }
+ },
+ {
+ count: 0
+ }
+ );
+
+ return ret.count;
+ },
+
+ /*
+ * return object
+ * Calculates columns width within given set of rows
+ */
+ _getColumnsWidth: function($trs) {
+ var ret = helpers._trCellIterator(
+ $trs,
+ {
+ cell: function(context) {
+ if (typeof context.result[context.colIndex] === 'undefined'
+ || context.result[context.colIndex].colspan > 1) {
+ var border = parseFloat($(this).outerWidth() - $(this).innerWidth())
+ / (settings.borderCollapse ? 2 : 1);
+ context.result[context.colIndex] = {
+ width: $(this).width() + border,
+ colspan: context.colspan
+ };
+
+ if (context.colspan == 1) {
+ context.definedWidthCount++;
+ }
+ }
+ },
+ afterRow: function(context) {
+ if (context.definedWidthCount == context.columnsCount) {
+ return true; // break
+ }
+ }
+ },
+ {
+ result: {},
+ definedWidthCount: 0,
+ columnsCount: helpers._getColumnsCount($trs)
+ }
+ );
+
+ return ret.result;
},
/*
diff --git a/jquery.fixedheadertable.min.js b/jquery.fixedheadertable.min.js
index 6c8a9ef..11132c4 100644
--- a/jquery.fixedheadertable.min.js
+++ b/jquery.fixedheadertable.min.js
@@ -16,5 +16,5 @@
*
*
* all CSS sizing (width,height) is done in pixels (px)
- */(function(c){c.fn.fixedHeaderTable=function(m){var u={width:"100%",height:"100%",themeClass:"fht-default",borderCollapse:!0,fixedColumns:0,fixedColumn:!1,sortable:!1,autoShow:!0,footer:!1,cloneHeadToFoot:!1,autoResize:!1,create:null},b={},n={init:function(a){b=c.extend({},u,a);return this.each(function(){var a=c(this);h._isTable(a)?(n.setup.apply(this,Array.prototype.slice.call(arguments,1)),c.isFunction(b.create)&&b.create.call(this)):c.error("Invalid table mark-up")})},setup:function(){var a=c(this), d=a.find("thead"),e=a.find("tfoot"),g=0,f,k,p;b.originalTable=c(this).clone();b.includePadding=h._isPaddingIncludedWithWidth();b.scrollbarOffset=h._getScrollbarWidth();b.themeClassName=b.themeClass;f=-1'));f=a.closest(".fht-table-wrapper");!0==b.fixedColumn&&0>=b.fixedColumns&&(b.fixedColumns= 1);0'),c('').prependTo(f),k=f.find(".fht-fixed-body"));f.css({width:b.width,height:b.height}).addClass(b.themeClassName);a.hasClass("fht-table-init")||a.wrap('');p=a.closest(".fht-tbody");var l=h._getTableProps(a);h._setupClone(p,l.tbody);a.hasClass("fht-table-init")?k=f.find("div.fht-thead"):(k=0').prependTo(k): c('').prependTo(f),k.find("table.fht-table").addClass(b.originalTable.attr("class")).attr("style",b.originalTable.attr("style")),d.clone().appendTo(k.find("table")));h._setupClone(k,l.thead);a.css({"margin-top":-k.outerHeight(!0)});!0==b.footer&&(h._setupTableFooter(a,this,l),e.length||(e=f.find("div.fht-tfoot table")),g=e.outerHeight(!0));d=f.height()-d.outerHeight(!0)-g-l.border;p.css({height:d});a.addClass("fht-table-init");"undefined"!== typeof b.altClass&&n.altRows.apply(this);0'),p=c('');a=c(''); var g=g.width(),l=f.find(".fht-tbody").height()-b.scrollbarOffset,q,t,r,s;k.find("table.fht-table").addClass(b.originalTable.attr("class"));p.find("table.fht-table").addClass(b.originalTable.attr("class"));a.find("table.fht-table").addClass(b.originalTable.attr("class"));q=f.find(".fht-thead thead tr > *:lt("+b.fixedColumns+")");r=b.fixedColumns*e.border;q.each(function(){r+=c(this).outerWidth(!0)});h._fixHeightWithCss(q,e);h._fixWidthWithCss(q,e);var m=[];q.each(function(){m.push(c(this).width())}); t=f.find("tbody tr > *:not(:nth-child(n+"+(b.fixedColumns+1)+"))").each(function(a){h._fixHeightWithCss(c(this),e);h._fixWidthWithCss(c(this),e,m[a%b.fixedColumns])});k.appendTo(d).find("tr").append(q.clone());p.appendTo(d).css({"margin-top":-1,height:l+e.border});t.each(function(a){0==a%b.fixedColumns&&(s=c("
").appendTo(p.find("tbody")),b.altClass&&c(this).parent().hasClass(b.altClass)&&s.addClass(b.altClass));c(this).clone().appendTo(s)});d.css({height:0,width:r});var n=d.find(".fht-tbody .fht-table").height()- d.find(".fht-tbody").height();d.find(".fht-tbody .fht-table").bind("mousewheel",function(a,d,b,e){if(0!=e)return a=parseInt(c(this).css("marginTop"),10)+(0 *:lt("+b.fixedColumns+")"),h._fixHeightWithCss(k,e),a.appendTo(d).find("tr").append(k.clone()),d=a.find("table").innerWidth(),a.css({top:b.scrollbarOffset, width:d})},_setupTableFooter:function(a,d,e){d=a.closest(".fht-table-wrapper");var g=a.find("tfoot");a=d.find("div.fht-tfoot");a.length||(a=0
'),c,e;a.addClass(b.originalTable.attr("class"));a.appendTo("body");c=a.find("td").height();a.find("td").css("height",a.find("tr").height());e=a.find("td").height();a.remove();return c!=e?!0:!1},_getScrollbarWidth:function(){var a=0;if(!a)if(/msie/.test(navigator.userAgent.toLowerCase())){var b=d('').css({position:"absolute", top:-1E3,left:-1E3}).appendTo("body"),e=d('').css({position:"absolute",top:-1E3,left:-1E3}).appendTo("body"),a=b.width()-e.width()+2;b.add(e).remove()}else b=d("").css({width:100,height:100,overflow:"auto",position:"absolute",top:-1E3,left:-1E3}).prependTo("body").append("").find("div").css({width:"100%",height:200}),a=100-b.width(),b.parent().remove();return a}};if(n[l])return n[l].apply(this,Array.prototype.slice.call(arguments, 1));if("object"!==typeof l&&l)d.error('Method "'+l+'" does not exist in fixedHeaderTable plugin!');else return n.init.apply(this,arguments)}})(jQuery);