diff --git a/dist/jquery.floatThead-slim.js b/dist/jquery.floatThead-slim.js index 7e12caa..16fb6f8 100644 --- a/dist/jquery.floatThead-slim.js +++ b/dist/jquery.floatThead-slim.js @@ -53,6 +53,18 @@ var isFF = /Gecko\//.test(navigator.userAgent); var isWebkit = /WebKit\//.test(navigator.userAgent); + //safari 7 (and perhaps others) reports table width to be parent container's width if max-width is set on table. see: https://github.com/mkoryak/floatThead/issues/108 + var isTableWidthBug = function(){ + if(isWebkit) { + var $test = $('
X
'); + $("body").append($test); + var ret = ($test.find("table").width() == 0); + $test.remove(); + return ret; + } + return false; + }; + var createElements = !isFF && !ieVersion; //FF can read width from elements, but webkit cannot var $window = $(window); @@ -114,6 +126,24 @@ } return false; } + + function tableWidth($table, $fthCells, isOuter){ + // see: https://github.com/mkoryak/floatThead/issues/108 + var fn = isOuter ? "outerWidth": "width"; + if(isTableWidthBug && $table.css("max-width")){ + var w = 0; + if(isOuter) { + w += parseInt($table.css("borderLeft"), 10); + w += parseInt($table.css("borderRight"), 10); + } + for(var i=0; i < $fthCells.length; i++){ + w += $fthCells.get(i).offsetWidth; + } + return w; + } else { + return $table[fn](); + } + } $.fn.floatThead = function(map){ map = map || {}; if(!util){ //may have been included after the script? lets try to grab it again. @@ -135,6 +165,10 @@ } var mObs = null; //mutation observer lives in here if we can use it / make it + if(util.isFunction(isTableWidthBug)) { + isTableWidthBug = isTableWidthBug(); + } + if(util.isString(map)){ var command = map; var ret = this; @@ -156,8 +190,11 @@ debug("Used ["+key+"] key to init plugin, but that param is not an option for the plugin. Valid options are: "+ (util.keys($.floatThead.defaults)).join(', ')); } }); - if(opts.debug && parseFloat($.fn.jquery) <= 1.7){ - debug("jQuery version "+$.fn.jquery+" detected! This plugin supports 1.8 or better, or 1.7.x with jQuery UI 1.8.24 -> http://jqueryui.com/resources/download/jquery-ui-1.8.24.zip") + if(opts.debug){ + var v = $.fn.jquery.split("."); + if(parseInt(v[0], 10) == 1 && parseInt(v[1], 10) <= 7){ + debug("jQuery version "+$.fn.jquery+" detected! This plugin supports 1.8 or better, or 1.7.x with jQuery UI 1.8.24 -> http://jqueryui.com/resources/download/jquery-ui-1.8.24.zip") + } } this.filter(':not(.'+opts.floatTableClass+')').each(function(){ @@ -301,15 +338,15 @@ function setFloatWidth(){ - var tableWidth = $table.outerWidth(); - var width = $scrollContainer.width() || tableWidth; + var tw = tableWidth($table, $fthCells, true); + var width = $scrollContainer.width() || tw; var floatContainerWidth = $scrollContainer.css("overflow-y") != 'hidden' ? width - scrollbarOffset.vertical : width; $floatContainer.width(floatContainerWidth); if(locked){ - var percent = 100 * tableWidth / (floatContainerWidth); + var percent = 100 * tw / (floatContainerWidth); $floatTable.css('width', percent+'%'); } else { - $floatTable.outerWidth(tableWidth); + $floatTable.outerWidth(tw); } } @@ -333,7 +370,7 @@ selector = 'tr:first>'+opts.cellTag; } if(util.isNumber(selector)){ - //its actually a row count. + //its actually a row count. (undocumented, might be removed!) return selector; } $headerColumns = $header.find(selector); @@ -381,10 +418,10 @@ if(!headerFloated){ headerFloated = true; if(useAbsolutePositioning){ //#53, #56 - var tableWidth = $table.width(); + var tw = tableWidth($table, $fthCells); var wrapperWidth = $wrapper.width(); - if(tableWidth > wrapperWidth){ - $table.css('minWidth', tableWidth); + if(tw > wrapperWidth){ + $table.css('minWidth', tw); } } $table.css(layoutFixed); @@ -405,7 +442,7 @@ $table.css(layoutAuto); $floatTable.css(layoutAuto); $table.css('minWidth', originalTableMinWidth); //this looks weird, but its not a bug. Think about it!! - $table.css('minWidth', $table.width()); //#121 + $table.css('minWidth', tableWidth($table, $fthCells)); //#121 } } function changePositioning(isAbsolute){ @@ -641,7 +678,7 @@ if($scrollContainer.data().perfectScrollbar){ scrollbarOffset = {horizontal:0, vertical:0}; } else { - var sw = $scrollContainer.width(), sh = $scrollContainer.height(), th = $table.height(), tw = $table.width(); + var sw = $scrollContainer.width(), sh = $scrollContainer.height(), th = $table.height(), tw = tableWidth($table, $fthCells); var offseth = sw < tw ? scWidth : 0; var offsetv = sh < th ? scWidth : 0; scrollbarOffset.horizontal = sw - offsetv < tw ? scWidth : 0; diff --git a/dist/jquery.floatThead-slim.min.js b/dist/jquery.floatThead-slim.min.js index d204b6c..6b31762 100644 --- a/dist/jquery.floatThead-slim.min.js +++ b/dist/jquery.floatThead-slim.min.js @@ -1,3 +1,3 @@ // @preserve jQuery.floatThead 1.2.11dev - http://mkoryak.github.io/floatThead/ - Copyright (c) 2012 - 2014 Misha Koryak // @license MIT -!function(a){function b(a,b,c){if(8==h){var d=l.width(),e=f.debounce(function(){var a=l.width();d!=a&&(d=a,c())},a);l.on(b,e)}else l.on(b,f.debounce(c,a))}function c(a){window.console&&window.console&&window.console.log&&window.console.log("jQuery.floatThead: "+a)}function d(){var b=a('
');a("body").append(b);var c=b.innerWidth(),d=a("div",b).innerWidth();return b.remove(),c-d}function e(a){if(a.dataTableSettings)for(var b=0;bth:visible",zIndex:1001,debounceResizeMs:10,useAbsolutePositioning:!0,scrollingTop:0,scrollingBottom:0,scrollContainer:function(){return a([])},getSizingRow:function(a){return a.find("tbody tr:visible:first>*:visible")},floatTableClass:"floatThead-table",floatWrapperClass:"floatThead-wrapper",floatContainerClass:"floatThead-container",copyTableClass:!0,enableAria:!1,autoReflow:!1,debug:!1};var f=window._,g="undefined"!=typeof MutationObserver,h=function(){for(var a=3,b=document.createElement("b"),c=b.all||[];a=1+a,b.innerHTML="",c[0];);return a>4?a:document.documentMode}(),i=/Gecko\//.test(navigator.userAgent),j=/WebKit\//.test(navigator.userAgent),k=!i&&!h,l=a(window);a.fn.floatThead=function(i){if(i=i||{},!f&&(f=window._||a.floatThead._,!f))throw new Error("jquery.floatThead-slim.js requires underscore. You should use the non-lite version since you do not have underscore.");if(8>h)return this;k&&(document.createElement("fthtr"),document.createElement("fthtd"),document.createElement("fthfoot"));var m=null;if(f.isString(i)){var n=i,o=this;return this.filter("table").each(function(){var b=a(this).data("floatThead-attached");if(b&&f.isFunction(b[n])){var c=b[n]();"undefined"!=typeof c&&(o=c)}}),o}var p=a.extend({},a.floatThead.defaults||{},i);return a.each(i,function(b){b in a.floatThead.defaults||!p.debug||c("Used ["+b+"] key to init plugin, but that param is not an option for the plugin. Valid options are: "+f.keys(a.floatThead.defaults).join(", "))}),p.debug&&parseFloat(a.fn.jquery)<=1.7&&c("jQuery version "+a.fn.jquery+" detected! This plugin supports 1.8 or better, or 1.7.x with jQuery UI 1.8.24 -> http://jqueryui.com/resources/download/jquery-ui-1.8.24.zip"),this.filter(":not(."+p.floatTableClass+")").each(function(){function c(a){return a+".fth-"+A+".floatTHead"}function i(){var b=0;C.find("tr:visible").each(function(){b+=a(this).outerHeight(!0)}),ab.outerHeight(b),bb.outerHeight(b)}function n(){var a=B.outerWidth(),b=K.width()||a,c="hidden"!=K.css("overflow-y")?b-H.vertical:b;if(Z.width(c),Q){var d=100*a/c;U.css("width",d+"%")}else U.outerWidth(a)}function o(){E=(f.isFunction(p.scrollingTop)?p.scrollingTop(B):p.scrollingTop)||0,F=(f.isFunction(p.scrollingBottom)?p.scrollingBottom(B):p.scrollingBottom)||0}function q(){var b,c;if(X)b=W.find("col").length;else{var d;if(d=null==p.cellTag&&p.headerCellSelector?p.headerCellSelector:"tr:first>"+p.cellTag,f.isNumber(d))return d;c=C.find(d),b=0,c.each(function(){b+=parseInt(a(this).attr("colspan")||1,10)})}if(b!=J){J=b;for(var e,g=[],h=[],i=[],j=0;b>j;j++)g.push(p.enableAria&&(e=c.eq(j).text())?''+e+"":''),h.push(""),i.push("");h=h.join(""),g=g.join(""),k&&(i=i.join(""),Y.html(i),eb=Y.find("fthtd")),ab.html(g),bb=ab.find("th"),X||W.html(h),cb=W.find("col"),V.html(h),db=V.find("col")}return b}function r(){if(!G){if(G=!0,L){var a=B.width(),b=S.width();a>b&&B.css("minWidth",a)}B.css(hb),U.css(hb),U.append(C),D.before(_),i()}}function s(){G&&(G=!1,L&&B.width(jb),_.detach(),B.prepend(C),B.css(ib),U.css(ib),B.css("minWidth",kb),B.css("minWidth",B.width()))}function t(a){L!=a&&(L=a,Z.css({position:L?"absolute":"fixed"}))}function u(a,b,c,d){return k?c:d?p.getSizingRow(a,b,c):b}function v(){var a,b=q();return function(){cb=W.find("col");var c=u(B,cb,eb,h);if(c.length==b&&b>0){if(!X)for(a=0;b>a;a++)cb.eq(a).css("width","");s();var d=[];for(a=0;b>a;a++)d[a]=c.get(a).offsetWidth;for(a=0;b>a;a++)db.eq(a).width(d[a]),cb.eq(a).width(d[a]);r()}else U.append(C),B.css(ib),U.css(ib),i()}}function w(a){var b=K.css("border-"+a+"-width"),c=0;return b&&~b.indexOf("px")&&(c=parseInt(b,10)),c}function x(){var a,b=K.scrollTop(),c=0,d=N?M.outerHeight(!0):0,e=O?d:-d,f=Z.height(),g=B.offset(),h=0;if(Q){var i=K.offset();c=g.top-i.top+b,N&&O&&(c+=d),c-=w("top"),h=w("left")}else a=g.top-E-f+F+H.horizontal;var k=l.scrollTop(),m=l.scrollLeft(),n=K.scrollLeft();return b=K.scrollTop(),function(i){var o=B[0].offsetWidth<=0&&B[0].offsetHeight<=0;if(!o&&$)return $=!1,setTimeout(function(){B.trigger("reflow")},1),null;if(o&&($=!0,!L))return null;if("windowScroll"==i?(k=l.scrollTop(),m=l.scrollLeft()):"containerScroll"==i?(b=K.scrollTop(),n=K.scrollLeft()):"init"!=i&&(k=l.scrollTop(),m=l.scrollLeft(),b=K.scrollTop(),n=K.scrollLeft()),!j||!(0>k||0>m)){if(T)t("windowScrollDone"==i?!0:!1);else if("windowScrollDone"==i)return null;g=B.offset(),N&&O&&(g.top+=d);var p,q,u=B.outerHeight();if(Q&&L){if(c>=b){var v=c-b;p=v>0?v:0}else p=R?0:b;q=h}else!Q&&L?(k>a+u+e?p=u-f+e:g.top>k+E?(p=0,s()):(p=E+k-g.top+c+(O?d:0),r()),q=0):Q&&!L?(c>b||b-c>u?(p=g.top-k,s()):(p=g.top+b-k-c,r()),q=g.left+n-m):Q||L||(k>a+u+e?p=u+E-k+a+e:g.top>k+E?(p=g.top-k,r()):p=E,q=g.left-m);return{top:p,left:q}}}}function y(){var a=null,b=null,c=null;return function(d,e,f){null==d||a==d.top&&b==d.left||(Z.css({top:d.top,left:d.left}),a=d.top,b=d.left),e&&n(),f&&i();var g=K.scrollLeft();L&&c==g||(Z.scrollLeft(g),c=g)}}function z(){if(K.length)if(K.data().perfectScrollbar)H={horizontal:0,vertical:0};else{var a=K.width(),b=K.height(),c=B.height(),d=B.width(),e=d>a?I:0,f=c>b?I:0;H.horizontal=d>a-f?I:0,H.vertical=c>b-e?I:0}}var A=f.uniqueId(),B=a(this);if(B.data("floatThead-attached"))return!0;if(!B.is("table"))throw new Error('jQuery.floatThead must be run on a table element. ex: $("table").floatThead();');g=p.autoReflow&&g;var C=B.find("thead:first"),D=B.find("tbody:first");if(0==C.length)throw new Error("jQuery.floatThead must be run on a table that contains a element");var E,F,G=!1,H={vertical:0,horizontal:0},I=d(),J=0,K=p.scrollContainer(B)||a([]),L=p.useAbsolutePositioning;null==L&&(L=p.scrollContainer(B).length),L||(G=!0);var M=B.find("caption"),N=1==M.length;if(N)var O="top"===(M.css("caption-side")||M.attr("align")||"top");var P=a(''),Q=K.length>0,R=!1,S=a([]),T=9>=h&&!Q&&L,U=a(""),V=a(""),W=B.find("colgroup:first"),X=!0;0==W.length&&(W=a(""),X=!1);var Y=a(''),Z=a(''),$=!1,_=a(""),ab=a(''),bb=a([]),cb=a([]),db=a([]),eb=a([]);_.append(ab),B.prepend(W),k&&(P.append(Y),B.append(P)),U.append(V),Z.append(U),p.copyTableClass&&U.attr("class",B.attr("class")),U.attr({cellpadding:B.attr("cellpadding"),cellspacing:B.attr("cellspacing"),border:B.attr("border")});var fb=B.css("display");if(U.css({borderCollapse:B.css("borderCollapse"),border:B.css("border"),display:fb}),"none"==fb&&($=!0),U.addClass(p.floatTableClass).css("margin",0),L){var gb=function(a,b){var c=a.css("position"),d="relative"==c||"absolute"==c;if(!d||b){var e={paddingLeft:a.css("paddingLeft"),paddingRight:a.css("paddingRight")};Z.css(e),a=a.wrap("
").parent(),R=!0}return a};Q?(S=gb(K,!0),S.append(Z)):(S=gb(B),B.after(Z))}else B.after(Z);Z.css({position:L?"absolute":"fixed",marginTop:0,top:L?0:"auto",zIndex:p.zIndex}),Z.addClass(p.floatContainerClass),o();var hb={"table-layout":"fixed"},ib={"table-layout":B.css("tableLayout")||"auto"},jb=B[0].style.width||"",kb=B.css("minWidth")||"";z();var lb,mb=function(){(lb=v())()};mb();var nb=x(),ob=y();ob(nb("init"),!0);var pb=f.debounce(function(){ob(nb("windowScrollDone"),!1)},300),qb=function(){ob(nb("windowScroll"),!1),pb()},rb=function(){ob(nb("containerScroll"),!1)},sb=function(){o(),z(),mb(),nb=x(),(ob=y())(nb("resize"),!0,!0)},tb=f.debounce(function(){z(),o(),mb(),nb=x(),ob(nb("reflow"),!0)},1);if(Q?L?K.on(c("scroll"),rb):(K.on(c("scroll"),rb),l.on(c("scroll"),qb)):l.on(c("scroll"),qb),l.on(c("load"),tb),b(p.debounceResizeMs,c("resize"),sb),B.on("reflow",tb),e(B)&&B.on("filter",tb).on("sort",tb).on("page",tb),g){var ub=K.length?K[0]:B[0];m=new MutationObserver(function(a){for(var b=function(a){return a&&a[0]&&"THEAD"==a[0].nodeName},c=0;c
');a("body").append(b);var c=b.innerWidth(),d=a("div",b).innerWidth();return b.remove(),c-d}function e(a){if(a.dataTableSettings)for(var b=0;bth:visible",zIndex:1001,debounceResizeMs:10,useAbsolutePositioning:!0,scrollingTop:0,scrollingBottom:0,scrollContainer:function(){return a([])},getSizingRow:function(a){return a.find("tbody tr:visible:first>*:visible")},floatTableClass:"floatThead-table",floatWrapperClass:"floatThead-wrapper",floatContainerClass:"floatThead-container",copyTableClass:!0,enableAria:!1,autoReflow:!1,debug:!1};var g=window._,h="undefined"!=typeof MutationObserver,i=function(){for(var a=3,b=document.createElement("b"),c=b.all||[];a=1+a,b.innerHTML="",c[0];);return a>4?a:document.documentMode}(),j=/Gecko\//.test(navigator.userAgent),k=/WebKit\//.test(navigator.userAgent),l=function(){if(k){var b=a('
X
');a("body").append(b);var c=0==b.find("table").width();return b.remove(),c}return!1},m=!j&&!i,n=a(window);a.fn.floatThead=function(j){if(j=j||{},!g&&(g=window._||a.floatThead._,!g))throw new Error("jquery.floatThead-slim.js requires underscore. You should use the non-lite version since you do not have underscore.");if(8>i)return this;m&&(document.createElement("fthtr"),document.createElement("fthtd"),document.createElement("fthfoot"));var o=null;if(g.isFunction(l)&&(l=l()),g.isString(j)){var p=j,q=this;return this.filter("table").each(function(){var b=a(this).data("floatThead-attached");if(b&&g.isFunction(b[p])){var c=b[p]();"undefined"!=typeof c&&(q=c)}}),q}var r=a.extend({},a.floatThead.defaults||{},j);if(a.each(j,function(b){b in a.floatThead.defaults||!r.debug||c("Used ["+b+"] key to init plugin, but that param is not an option for the plugin. Valid options are: "+g.keys(a.floatThead.defaults).join(", "))}),r.debug){var s=a.fn.jquery.split(".");1==parseInt(s[0],10)&&parseInt(s[1],10)<=7&&c("jQuery version "+a.fn.jquery+" detected! This plugin supports 1.8 or better, or 1.7.x with jQuery UI 1.8.24 -> http://jqueryui.com/resources/download/jquery-ui-1.8.24.zip")}return this.filter(":not(."+r.floatTableClass+")").each(function(){function c(a){return a+".fth-"+B+".floatTHead"}function j(){var b=0;D.find("tr:visible").each(function(){b+=a(this).outerHeight(!0)}),bb.outerHeight(b),cb.outerHeight(b)}function l(){var a=f(C,fb,!0),b=L.width()||a,c="hidden"!=L.css("overflow-y")?b-I.vertical:b;if($.width(c),R){var d=100*a/c;V.css("width",d+"%")}else V.outerWidth(a)}function p(){F=(g.isFunction(r.scrollingTop)?r.scrollingTop(C):r.scrollingTop)||0,G=(g.isFunction(r.scrollingBottom)?r.scrollingBottom(C):r.scrollingBottom)||0}function q(){var b,c;if(Y)b=X.find("col").length;else{var d;if(d=null==r.cellTag&&r.headerCellSelector?r.headerCellSelector:"tr:first>"+r.cellTag,g.isNumber(d))return d;c=D.find(d),b=0,c.each(function(){b+=parseInt(a(this).attr("colspan")||1,10)})}if(b!=K){K=b;for(var e,f=[],h=[],i=[],j=0;b>j;j++)f.push(r.enableAria&&(e=c.eq(j).text())?''+e+"":''),h.push(""),i.push("");h=h.join(""),f=f.join(""),m&&(i=i.join(""),Z.html(i),fb=Z.find("fthtd")),bb.html(f),cb=bb.find("th"),Y||X.html(h),db=X.find("col"),W.html(h),eb=W.find("col")}return b}function s(){if(!H){if(H=!0,M){var a=f(C,fb),b=T.width();a>b&&C.css("minWidth",a)}C.css(ib),V.css(ib),V.append(D),E.before(ab),j()}}function t(){H&&(H=!1,M&&C.width(kb),ab.detach(),C.prepend(D),C.css(jb),V.css(jb),C.css("minWidth",lb),C.css("minWidth",f(C,fb)))}function u(a){M!=a&&(M=a,$.css({position:M?"absolute":"fixed"}))}function v(a,b,c,d){return m?c:d?r.getSizingRow(a,b,c):b}function w(){var a,b=q();return function(){db=X.find("col");var c=v(C,db,fb,i);if(c.length==b&&b>0){if(!Y)for(a=0;b>a;a++)db.eq(a).css("width","");t();var d=[];for(a=0;b>a;a++)d[a]=c.get(a).offsetWidth;for(a=0;b>a;a++)eb.eq(a).width(d[a]),db.eq(a).width(d[a]);s()}else V.append(D),C.css(jb),V.css(jb),j()}}function x(a){var b=L.css("border-"+a+"-width"),c=0;return b&&~b.indexOf("px")&&(c=parseInt(b,10)),c}function y(){var a,b=L.scrollTop(),c=0,d=O?N.outerHeight(!0):0,e=P?d:-d,f=$.height(),g=C.offset(),h=0;if(R){var i=L.offset();c=g.top-i.top+b,O&&P&&(c+=d),c-=x("top"),h=x("left")}else a=g.top-F-f+G+I.horizontal;var j=n.scrollTop(),l=n.scrollLeft(),m=L.scrollLeft();return b=L.scrollTop(),function(i){var o=C[0].offsetWidth<=0&&C[0].offsetHeight<=0;if(!o&&_)return _=!1,setTimeout(function(){C.trigger("reflow")},1),null;if(o&&(_=!0,!M))return null;if("windowScroll"==i?(j=n.scrollTop(),l=n.scrollLeft()):"containerScroll"==i?(b=L.scrollTop(),m=L.scrollLeft()):"init"!=i&&(j=n.scrollTop(),l=n.scrollLeft(),b=L.scrollTop(),m=L.scrollLeft()),!k||!(0>j||0>l)){if(U)u("windowScrollDone"==i?!0:!1);else if("windowScrollDone"==i)return null;g=C.offset(),O&&P&&(g.top+=d);var p,q,r=C.outerHeight();if(R&&M){if(c>=b){var v=c-b;p=v>0?v:0}else p=S?0:b;q=h}else!R&&M?(j>a+r+e?p=r-f+e:g.top>j+F?(p=0,t()):(p=F+j-g.top+c+(P?d:0),s()),q=0):R&&!M?(c>b||b-c>r?(p=g.top-j,t()):(p=g.top+b-j-c,s()),q=g.left+m-l):R||M||(j>a+r+e?p=r+F-j+a+e:g.top>j+F?(p=g.top-j,s()):p=F,q=g.left-l);return{top:p,left:q}}}}function z(){var a=null,b=null,c=null;return function(d,e,f){null==d||a==d.top&&b==d.left||($.css({top:d.top,left:d.left}),a=d.top,b=d.left),e&&l(),f&&j();var g=L.scrollLeft();M&&c==g||($.scrollLeft(g),c=g)}}function A(){if(L.length)if(L.data().perfectScrollbar)I={horizontal:0,vertical:0};else{var a=L.width(),b=L.height(),c=C.height(),d=f(C,fb),e=d>a?J:0,g=c>b?J:0;I.horizontal=d>a-g?J:0,I.vertical=c>b-e?J:0}}var B=g.uniqueId(),C=a(this);if(C.data("floatThead-attached"))return!0;if(!C.is("table"))throw new Error('jQuery.floatThead must be run on a table element. ex: $("table").floatThead();');h=r.autoReflow&&h;var D=C.find("thead:first"),E=C.find("tbody:first");if(0==D.length)throw new Error("jQuery.floatThead must be run on a table that contains a element");var F,G,H=!1,I={vertical:0,horizontal:0},J=d(),K=0,L=r.scrollContainer(C)||a([]),M=r.useAbsolutePositioning;null==M&&(M=r.scrollContainer(C).length),M||(H=!0);var N=C.find("caption"),O=1==N.length;if(O)var P="top"===(N.css("caption-side")||N.attr("align")||"top");var Q=a(''),R=L.length>0,S=!1,T=a([]),U=9>=i&&!R&&M,V=a(""),W=a(""),X=C.find("colgroup:first"),Y=!0;0==X.length&&(X=a(""),Y=!1);var Z=a(''),$=a(''),_=!1,ab=a(""),bb=a(''),cb=a([]),db=a([]),eb=a([]),fb=a([]);ab.append(bb),C.prepend(X),m&&(Q.append(Z),C.append(Q)),V.append(W),$.append(V),r.copyTableClass&&V.attr("class",C.attr("class")),V.attr({cellpadding:C.attr("cellpadding"),cellspacing:C.attr("cellspacing"),border:C.attr("border")});var gb=C.css("display");if(V.css({borderCollapse:C.css("borderCollapse"),border:C.css("border"),display:gb}),"none"==gb&&(_=!0),V.addClass(r.floatTableClass).css("margin",0),M){var hb=function(a,b){var c=a.css("position"),d="relative"==c||"absolute"==c;if(!d||b){var e={paddingLeft:a.css("paddingLeft"),paddingRight:a.css("paddingRight")};$.css(e),a=a.wrap("
").parent(),S=!0}return a};R?(T=hb(L,!0),T.append($)):(T=hb(C),C.after($))}else C.after($);$.css({position:M?"absolute":"fixed",marginTop:0,top:M?0:"auto",zIndex:r.zIndex}),$.addClass(r.floatContainerClass),p();var ib={"table-layout":"fixed"},jb={"table-layout":C.css("tableLayout")||"auto"},kb=C[0].style.width||"",lb=C.css("minWidth")||"";A();var mb,nb=function(){(mb=w())()};nb();var ob=y(),pb=z();pb(ob("init"),!0);var qb=g.debounce(function(){pb(ob("windowScrollDone"),!1)},300),rb=function(){pb(ob("windowScroll"),!1),qb()},sb=function(){pb(ob("containerScroll"),!1)},tb=function(){p(),A(),nb(),ob=y(),(pb=z())(ob("resize"),!0,!0)},ub=g.debounce(function(){A(),p(),nb(),ob=y(),pb(ob("reflow"),!0)},1);if(R?M?L.on(c("scroll"),sb):(L.on(c("scroll"),sb),n.on(c("scroll"),rb)):n.on(c("scroll"),rb),n.on(c("load"),ub),b(r.debounceResizeMs,c("resize"),tb),C.on("reflow",ub),e(C)&&C.on("filter",ub).on("sort",ub).on("page",ub),h){var vb=L.length?L[0]:C[0];o=new MutationObserver(function(a){for(var b=function(a){return a&&a[0]&&"THEAD"==a[0].nodeName},c=0;c
X
'); + $("body").append($test); + var ret = ($test.find("table").width() == 0); + $test.remove(); + return ret; + } + return false; + }; + var createElements = !isFF && !ieVersion; //FF can read width from elements, but webkit cannot var $window = $(window); @@ -114,6 +126,24 @@ } return false; } + + function tableWidth($table, $fthCells, isOuter){ + // see: https://github.com/mkoryak/floatThead/issues/108 + var fn = isOuter ? "outerWidth": "width"; + if(isTableWidthBug && $table.css("max-width")){ + var w = 0; + if(isOuter) { + w += parseInt($table.css("borderLeft"), 10); + w += parseInt($table.css("borderRight"), 10); + } + for(var i=0; i < $fthCells.length; i++){ + w += $fthCells.get(i).offsetWidth; + } + return w; + } else { + return $table[fn](); + } + } $.fn.floatThead = function(map){ map = map || {}; if(!util){ //may have been included after the script? lets try to grab it again. @@ -135,6 +165,10 @@ } var mObs = null; //mutation observer lives in here if we can use it / make it + if(util.isFunction(isTableWidthBug)) { + isTableWidthBug = isTableWidthBug(); + } + if(util.isString(map)){ var command = map; var ret = this; @@ -156,8 +190,11 @@ debug("Used ["+key+"] key to init plugin, but that param is not an option for the plugin. Valid options are: "+ (util.keys($.floatThead.defaults)).join(', ')); } }); - if(opts.debug && parseFloat($.fn.jquery) <= 1.7){ - debug("jQuery version "+$.fn.jquery+" detected! This plugin supports 1.8 or better, or 1.7.x with jQuery UI 1.8.24 -> http://jqueryui.com/resources/download/jquery-ui-1.8.24.zip") + if(opts.debug){ + var v = $.fn.jquery.split("."); + if(parseInt(v[0], 10) == 1 && parseInt(v[1], 10) <= 7){ + debug("jQuery version "+$.fn.jquery+" detected! This plugin supports 1.8 or better, or 1.7.x with jQuery UI 1.8.24 -> http://jqueryui.com/resources/download/jquery-ui-1.8.24.zip") + } } this.filter(':not(.'+opts.floatTableClass+')').each(function(){ @@ -301,15 +338,15 @@ function setFloatWidth(){ - var tableWidth = $table.outerWidth(); - var width = $scrollContainer.width() || tableWidth; + var tw = tableWidth($table, $fthCells, true); + var width = $scrollContainer.width() || tw; var floatContainerWidth = $scrollContainer.css("overflow-y") != 'hidden' ? width - scrollbarOffset.vertical : width; $floatContainer.width(floatContainerWidth); if(locked){ - var percent = 100 * tableWidth / (floatContainerWidth); + var percent = 100 * tw / (floatContainerWidth); $floatTable.css('width', percent+'%'); } else { - $floatTable.outerWidth(tableWidth); + $floatTable.outerWidth(tw); } } @@ -333,7 +370,7 @@ selector = 'tr:first>'+opts.cellTag; } if(util.isNumber(selector)){ - //its actually a row count. + //its actually a row count. (undocumented, might be removed!) return selector; } $headerColumns = $header.find(selector); @@ -381,10 +418,10 @@ if(!headerFloated){ headerFloated = true; if(useAbsolutePositioning){ //#53, #56 - var tableWidth = $table.width(); + var tw = tableWidth($table, $fthCells); var wrapperWidth = $wrapper.width(); - if(tableWidth > wrapperWidth){ - $table.css('minWidth', tableWidth); + if(tw > wrapperWidth){ + $table.css('minWidth', tw); } } $table.css(layoutFixed); @@ -405,7 +442,7 @@ $table.css(layoutAuto); $floatTable.css(layoutAuto); $table.css('minWidth', originalTableMinWidth); //this looks weird, but its not a bug. Think about it!! - $table.css('minWidth', $table.width()); //#121 + $table.css('minWidth', tableWidth($table, $fthCells)); //#121 } } function changePositioning(isAbsolute){ @@ -641,7 +678,7 @@ if($scrollContainer.data().perfectScrollbar){ scrollbarOffset = {horizontal:0, vertical:0}; } else { - var sw = $scrollContainer.width(), sh = $scrollContainer.height(), th = $table.height(), tw = $table.width(); + var sw = $scrollContainer.width(), sh = $scrollContainer.height(), th = $table.height(), tw = tableWidth($table, $fthCells); var offseth = sw < tw ? scWidth : 0; var offsetv = sh < th ? scWidth : 0; scrollbarOffset.horizontal = sw - offsetv < tw ? scWidth : 0; diff --git a/dist/jquery.floatThead.min.js b/dist/jquery.floatThead.min.js index 0d7d1c9..adbd62c 100644 --- a/dist/jquery.floatThead.min.js +++ b/dist/jquery.floatThead.min.js @@ -1,3 +1,3 @@ // @preserve jQuery.floatThead 1.2.11dev - http://mkoryak.github.io/floatThead/ - Copyright (c) 2012 - 2014 Misha Koryak // @license MIT -!function(a){function b(a,b,c){if(8==h){var d=l.width(),e=f.debounce(function(){var a=l.width();d!=a&&(d=a,c())},a);l.on(b,e)}else l.on(b,f.debounce(c,a))}function c(a){window.console&&window.console&&window.console.log&&window.console.log("jQuery.floatThead: "+a)}function d(){var b=a('
');a("body").append(b);var c=b.innerWidth(),d=a("div",b).innerWidth();return b.remove(),c-d}function e(a){if(a.dataTableSettings)for(var b=0;bth:visible",zIndex:1001,debounceResizeMs:10,useAbsolutePositioning:!0,scrollingTop:0,scrollingBottom:0,scrollContainer:function(){return a([])},getSizingRow:function(a){return a.find("tbody tr:visible:first>*:visible")},floatTableClass:"floatThead-table",floatWrapperClass:"floatThead-wrapper",floatContainerClass:"floatThead-container",copyTableClass:!0,enableAria:!1,autoReflow:!1,debug:!1};var f=window._,g="undefined"!=typeof MutationObserver,h=function(){for(var a=3,b=document.createElement("b"),c=b.all||[];a=1+a,b.innerHTML="",c[0];);return a>4?a:document.documentMode}(),i=/Gecko\//.test(navigator.userAgent),j=/WebKit\//.test(navigator.userAgent),k=!i&&!h,l=a(window);a.fn.floatThead=function(i){if(i=i||{},!f&&(f=window._||a.floatThead._,!f))throw new Error("jquery.floatThead-slim.js requires underscore. You should use the non-lite version since you do not have underscore.");if(8>h)return this;k&&(document.createElement("fthtr"),document.createElement("fthtd"),document.createElement("fthfoot"));var m=null;if(f.isString(i)){var n=i,o=this;return this.filter("table").each(function(){var b=a(this).data("floatThead-attached");if(b&&f.isFunction(b[n])){var c=b[n]();"undefined"!=typeof c&&(o=c)}}),o}var p=a.extend({},a.floatThead.defaults||{},i);return a.each(i,function(b){b in a.floatThead.defaults||!p.debug||c("Used ["+b+"] key to init plugin, but that param is not an option for the plugin. Valid options are: "+f.keys(a.floatThead.defaults).join(", "))}),p.debug&&parseFloat(a.fn.jquery)<=1.7&&c("jQuery version "+a.fn.jquery+" detected! This plugin supports 1.8 or better, or 1.7.x with jQuery UI 1.8.24 -> http://jqueryui.com/resources/download/jquery-ui-1.8.24.zip"),this.filter(":not(."+p.floatTableClass+")").each(function(){function c(a){return a+".fth-"+A+".floatTHead"}function i(){var b=0;C.find("tr:visible").each(function(){b+=a(this).outerHeight(!0)}),ab.outerHeight(b),bb.outerHeight(b)}function n(){var a=B.outerWidth(),b=K.width()||a,c="hidden"!=K.css("overflow-y")?b-H.vertical:b;if(Z.width(c),Q){var d=100*a/c;U.css("width",d+"%")}else U.outerWidth(a)}function o(){E=(f.isFunction(p.scrollingTop)?p.scrollingTop(B):p.scrollingTop)||0,F=(f.isFunction(p.scrollingBottom)?p.scrollingBottom(B):p.scrollingBottom)||0}function q(){var b,c;if(X)b=W.find("col").length;else{var d;if(d=null==p.cellTag&&p.headerCellSelector?p.headerCellSelector:"tr:first>"+p.cellTag,f.isNumber(d))return d;c=C.find(d),b=0,c.each(function(){b+=parseInt(a(this).attr("colspan")||1,10)})}if(b!=J){J=b;for(var e,g=[],h=[],i=[],j=0;b>j;j++)g.push(p.enableAria&&(e=c.eq(j).text())?''+e+"":''),h.push(""),i.push("");h=h.join(""),g=g.join(""),k&&(i=i.join(""),Y.html(i),eb=Y.find("fthtd")),ab.html(g),bb=ab.find("th"),X||W.html(h),cb=W.find("col"),V.html(h),db=V.find("col")}return b}function r(){if(!G){if(G=!0,L){var a=B.width(),b=S.width();a>b&&B.css("minWidth",a)}B.css(hb),U.css(hb),U.append(C),D.before(_),i()}}function s(){G&&(G=!1,L&&B.width(jb),_.detach(),B.prepend(C),B.css(ib),U.css(ib),B.css("minWidth",kb),B.css("minWidth",B.width()))}function t(a){L!=a&&(L=a,Z.css({position:L?"absolute":"fixed"}))}function u(a,b,c,d){return k?c:d?p.getSizingRow(a,b,c):b}function v(){var a,b=q();return function(){cb=W.find("col");var c=u(B,cb,eb,h);if(c.length==b&&b>0){if(!X)for(a=0;b>a;a++)cb.eq(a).css("width","");s();var d=[];for(a=0;b>a;a++)d[a]=c.get(a).offsetWidth;for(a=0;b>a;a++)db.eq(a).width(d[a]),cb.eq(a).width(d[a]);r()}else U.append(C),B.css(ib),U.css(ib),i()}}function w(a){var b=K.css("border-"+a+"-width"),c=0;return b&&~b.indexOf("px")&&(c=parseInt(b,10)),c}function x(){var a,b=K.scrollTop(),c=0,d=N?M.outerHeight(!0):0,e=O?d:-d,f=Z.height(),g=B.offset(),h=0;if(Q){var i=K.offset();c=g.top-i.top+b,N&&O&&(c+=d),c-=w("top"),h=w("left")}else a=g.top-E-f+F+H.horizontal;var k=l.scrollTop(),m=l.scrollLeft(),n=K.scrollLeft();return b=K.scrollTop(),function(i){var o=B[0].offsetWidth<=0&&B[0].offsetHeight<=0;if(!o&&$)return $=!1,setTimeout(function(){B.trigger("reflow")},1),null;if(o&&($=!0,!L))return null;if("windowScroll"==i?(k=l.scrollTop(),m=l.scrollLeft()):"containerScroll"==i?(b=K.scrollTop(),n=K.scrollLeft()):"init"!=i&&(k=l.scrollTop(),m=l.scrollLeft(),b=K.scrollTop(),n=K.scrollLeft()),!j||!(0>k||0>m)){if(T)t("windowScrollDone"==i?!0:!1);else if("windowScrollDone"==i)return null;g=B.offset(),N&&O&&(g.top+=d);var p,q,u=B.outerHeight();if(Q&&L){if(c>=b){var v=c-b;p=v>0?v:0}else p=R?0:b;q=h}else!Q&&L?(k>a+u+e?p=u-f+e:g.top>k+E?(p=0,s()):(p=E+k-g.top+c+(O?d:0),r()),q=0):Q&&!L?(c>b||b-c>u?(p=g.top-k,s()):(p=g.top+b-k-c,r()),q=g.left+n-m):Q||L||(k>a+u+e?p=u+E-k+a+e:g.top>k+E?(p=g.top-k,r()):p=E,q=g.left-m);return{top:p,left:q}}}}function y(){var a=null,b=null,c=null;return function(d,e,f){null==d||a==d.top&&b==d.left||(Z.css({top:d.top,left:d.left}),a=d.top,b=d.left),e&&n(),f&&i();var g=K.scrollLeft();L&&c==g||(Z.scrollLeft(g),c=g)}}function z(){if(K.length)if(K.data().perfectScrollbar)H={horizontal:0,vertical:0};else{var a=K.width(),b=K.height(),c=B.height(),d=B.width(),e=d>a?I:0,f=c>b?I:0;H.horizontal=d>a-f?I:0,H.vertical=c>b-e?I:0}}var A=f.uniqueId(),B=a(this);if(B.data("floatThead-attached"))return!0;if(!B.is("table"))throw new Error('jQuery.floatThead must be run on a table element. ex: $("table").floatThead();');g=p.autoReflow&&g;var C=B.find("thead:first"),D=B.find("tbody:first");if(0==C.length)throw new Error("jQuery.floatThead must be run on a table that contains a element");var E,F,G=!1,H={vertical:0,horizontal:0},I=d(),J=0,K=p.scrollContainer(B)||a([]),L=p.useAbsolutePositioning;null==L&&(L=p.scrollContainer(B).length),L||(G=!0);var M=B.find("caption"),N=1==M.length;if(N)var O="top"===(M.css("caption-side")||M.attr("align")||"top");var P=a(''),Q=K.length>0,R=!1,S=a([]),T=9>=h&&!Q&&L,U=a(""),V=a(""),W=B.find("colgroup:first"),X=!0;0==W.length&&(W=a(""),X=!1);var Y=a(''),Z=a(''),$=!1,_=a(""),ab=a(''),bb=a([]),cb=a([]),db=a([]),eb=a([]);_.append(ab),B.prepend(W),k&&(P.append(Y),B.append(P)),U.append(V),Z.append(U),p.copyTableClass&&U.attr("class",B.attr("class")),U.attr({cellpadding:B.attr("cellpadding"),cellspacing:B.attr("cellspacing"),border:B.attr("border")});var fb=B.css("display");if(U.css({borderCollapse:B.css("borderCollapse"),border:B.css("border"),display:fb}),"none"==fb&&($=!0),U.addClass(p.floatTableClass).css("margin",0),L){var gb=function(a,b){var c=a.css("position"),d="relative"==c||"absolute"==c;if(!d||b){var e={paddingLeft:a.css("paddingLeft"),paddingRight:a.css("paddingRight")};Z.css(e),a=a.wrap("
").parent(),R=!0}return a};Q?(S=gb(K,!0),S.append(Z)):(S=gb(B),B.after(Z))}else B.after(Z);Z.css({position:L?"absolute":"fixed",marginTop:0,top:L?0:"auto",zIndex:p.zIndex}),Z.addClass(p.floatContainerClass),o();var hb={"table-layout":"fixed"},ib={"table-layout":B.css("tableLayout")||"auto"},jb=B[0].style.width||"",kb=B.css("minWidth")||"";z();var lb,mb=function(){(lb=v())()};mb();var nb=x(),ob=y();ob(nb("init"),!0);var pb=f.debounce(function(){ob(nb("windowScrollDone"),!1)},300),qb=function(){ob(nb("windowScroll"),!1),pb()},rb=function(){ob(nb("containerScroll"),!1)},sb=function(){o(),z(),mb(),nb=x(),(ob=y())(nb("resize"),!0,!0)},tb=f.debounce(function(){z(),o(),mb(),nb=x(),ob(nb("reflow"),!0)},1);if(Q?L?K.on(c("scroll"),rb):(K.on(c("scroll"),rb),l.on(c("scroll"),qb)):l.on(c("scroll"),qb),l.on(c("load"),tb),b(p.debounceResizeMs,c("resize"),sb),B.on("reflow",tb),e(B)&&B.on("filter",tb).on("sort",tb).on("page",tb),g){var ub=K.length?K[0]:B[0];m=new MutationObserver(function(a){for(var b=function(a){return a&&a[0]&&"THEAD"==a[0].nodeName},c=0;cj?d=setTimeout(i,b-j):(d=null,c||(h=a.apply(f,e)))},j=c&&!d;return d||(d=setTimeout(i,b)),j&&(h=a.apply(f,e)),h}},b}()}(jQuery); \ No newline at end of file +!function(a){function b(a,b,c){if(8==i){var d=n.width(),e=g.debounce(function(){var a=n.width();d!=a&&(d=a,c())},a);n.on(b,e)}else n.on(b,g.debounce(c,a))}function c(a){window.console&&window.console&&window.console.log&&window.console.log("jQuery.floatThead: "+a)}function d(){var b=a('
');a("body").append(b);var c=b.innerWidth(),d=a("div",b).innerWidth();return b.remove(),c-d}function e(a){if(a.dataTableSettings)for(var b=0;bth:visible",zIndex:1001,debounceResizeMs:10,useAbsolutePositioning:!0,scrollingTop:0,scrollingBottom:0,scrollContainer:function(){return a([])},getSizingRow:function(a){return a.find("tbody tr:visible:first>*:visible")},floatTableClass:"floatThead-table",floatWrapperClass:"floatThead-wrapper",floatContainerClass:"floatThead-container",copyTableClass:!0,enableAria:!1,autoReflow:!1,debug:!1};var g=window._,h="undefined"!=typeof MutationObserver,i=function(){for(var a=3,b=document.createElement("b"),c=b.all||[];a=1+a,b.innerHTML="",c[0];);return a>4?a:document.documentMode}(),j=/Gecko\//.test(navigator.userAgent),k=/WebKit\//.test(navigator.userAgent),l=function(){if(k){var b=a('
X
');a("body").append(b);var c=0==b.find("table").width();return b.remove(),c}return!1},m=!j&&!i,n=a(window);a.fn.floatThead=function(j){if(j=j||{},!g&&(g=window._||a.floatThead._,!g))throw new Error("jquery.floatThead-slim.js requires underscore. You should use the non-lite version since you do not have underscore.");if(8>i)return this;m&&(document.createElement("fthtr"),document.createElement("fthtd"),document.createElement("fthfoot"));var o=null;if(g.isFunction(l)&&(l=l()),g.isString(j)){var p=j,q=this;return this.filter("table").each(function(){var b=a(this).data("floatThead-attached");if(b&&g.isFunction(b[p])){var c=b[p]();"undefined"!=typeof c&&(q=c)}}),q}var r=a.extend({},a.floatThead.defaults||{},j);if(a.each(j,function(b){b in a.floatThead.defaults||!r.debug||c("Used ["+b+"] key to init plugin, but that param is not an option for the plugin. Valid options are: "+g.keys(a.floatThead.defaults).join(", "))}),r.debug){var s=a.fn.jquery.split(".");1==parseInt(s[0],10)&&parseInt(s[1],10)<=7&&c("jQuery version "+a.fn.jquery+" detected! This plugin supports 1.8 or better, or 1.7.x with jQuery UI 1.8.24 -> http://jqueryui.com/resources/download/jquery-ui-1.8.24.zip")}return this.filter(":not(."+r.floatTableClass+")").each(function(){function c(a){return a+".fth-"+B+".floatTHead"}function j(){var b=0;D.find("tr:visible").each(function(){b+=a(this).outerHeight(!0)}),bb.outerHeight(b),cb.outerHeight(b)}function l(){var a=f(C,fb,!0),b=L.width()||a,c="hidden"!=L.css("overflow-y")?b-I.vertical:b;if($.width(c),R){var d=100*a/c;V.css("width",d+"%")}else V.outerWidth(a)}function p(){F=(g.isFunction(r.scrollingTop)?r.scrollingTop(C):r.scrollingTop)||0,G=(g.isFunction(r.scrollingBottom)?r.scrollingBottom(C):r.scrollingBottom)||0}function q(){var b,c;if(Y)b=X.find("col").length;else{var d;if(d=null==r.cellTag&&r.headerCellSelector?r.headerCellSelector:"tr:first>"+r.cellTag,g.isNumber(d))return d;c=D.find(d),b=0,c.each(function(){b+=parseInt(a(this).attr("colspan")||1,10)})}if(b!=K){K=b;for(var e,f=[],h=[],i=[],j=0;b>j;j++)f.push(r.enableAria&&(e=c.eq(j).text())?''+e+"":''),h.push(""),i.push("");h=h.join(""),f=f.join(""),m&&(i=i.join(""),Z.html(i),fb=Z.find("fthtd")),bb.html(f),cb=bb.find("th"),Y||X.html(h),db=X.find("col"),W.html(h),eb=W.find("col")}return b}function s(){if(!H){if(H=!0,M){var a=f(C,fb),b=T.width();a>b&&C.css("minWidth",a)}C.css(ib),V.css(ib),V.append(D),E.before(ab),j()}}function t(){H&&(H=!1,M&&C.width(kb),ab.detach(),C.prepend(D),C.css(jb),V.css(jb),C.css("minWidth",lb),C.css("minWidth",f(C,fb)))}function u(a){M!=a&&(M=a,$.css({position:M?"absolute":"fixed"}))}function v(a,b,c,d){return m?c:d?r.getSizingRow(a,b,c):b}function w(){var a,b=q();return function(){db=X.find("col");var c=v(C,db,fb,i);if(c.length==b&&b>0){if(!Y)for(a=0;b>a;a++)db.eq(a).css("width","");t();var d=[];for(a=0;b>a;a++)d[a]=c.get(a).offsetWidth;for(a=0;b>a;a++)eb.eq(a).width(d[a]),db.eq(a).width(d[a]);s()}else V.append(D),C.css(jb),V.css(jb),j()}}function x(a){var b=L.css("border-"+a+"-width"),c=0;return b&&~b.indexOf("px")&&(c=parseInt(b,10)),c}function y(){var a,b=L.scrollTop(),c=0,d=O?N.outerHeight(!0):0,e=P?d:-d,f=$.height(),g=C.offset(),h=0;if(R){var i=L.offset();c=g.top-i.top+b,O&&P&&(c+=d),c-=x("top"),h=x("left")}else a=g.top-F-f+G+I.horizontal;var j=n.scrollTop(),l=n.scrollLeft(),m=L.scrollLeft();return b=L.scrollTop(),function(i){var o=C[0].offsetWidth<=0&&C[0].offsetHeight<=0;if(!o&&_)return _=!1,setTimeout(function(){C.trigger("reflow")},1),null;if(o&&(_=!0,!M))return null;if("windowScroll"==i?(j=n.scrollTop(),l=n.scrollLeft()):"containerScroll"==i?(b=L.scrollTop(),m=L.scrollLeft()):"init"!=i&&(j=n.scrollTop(),l=n.scrollLeft(),b=L.scrollTop(),m=L.scrollLeft()),!k||!(0>j||0>l)){if(U)u("windowScrollDone"==i?!0:!1);else if("windowScrollDone"==i)return null;g=C.offset(),O&&P&&(g.top+=d);var p,q,r=C.outerHeight();if(R&&M){if(c>=b){var v=c-b;p=v>0?v:0}else p=S?0:b;q=h}else!R&&M?(j>a+r+e?p=r-f+e:g.top>j+F?(p=0,t()):(p=F+j-g.top+c+(P?d:0),s()),q=0):R&&!M?(c>b||b-c>r?(p=g.top-j,t()):(p=g.top+b-j-c,s()),q=g.left+m-l):R||M||(j>a+r+e?p=r+F-j+a+e:g.top>j+F?(p=g.top-j,s()):p=F,q=g.left-l);return{top:p,left:q}}}}function z(){var a=null,b=null,c=null;return function(d,e,f){null==d||a==d.top&&b==d.left||($.css({top:d.top,left:d.left}),a=d.top,b=d.left),e&&l(),f&&j();var g=L.scrollLeft();M&&c==g||($.scrollLeft(g),c=g)}}function A(){if(L.length)if(L.data().perfectScrollbar)I={horizontal:0,vertical:0};else{var a=L.width(),b=L.height(),c=C.height(),d=f(C,fb),e=d>a?J:0,g=c>b?J:0;I.horizontal=d>a-g?J:0,I.vertical=c>b-e?J:0}}var B=g.uniqueId(),C=a(this);if(C.data("floatThead-attached"))return!0;if(!C.is("table"))throw new Error('jQuery.floatThead must be run on a table element. ex: $("table").floatThead();');h=r.autoReflow&&h;var D=C.find("thead:first"),E=C.find("tbody:first");if(0==D.length)throw new Error("jQuery.floatThead must be run on a table that contains a element");var F,G,H=!1,I={vertical:0,horizontal:0},J=d(),K=0,L=r.scrollContainer(C)||a([]),M=r.useAbsolutePositioning;null==M&&(M=r.scrollContainer(C).length),M||(H=!0);var N=C.find("caption"),O=1==N.length;if(O)var P="top"===(N.css("caption-side")||N.attr("align")||"top");var Q=a(''),R=L.length>0,S=!1,T=a([]),U=9>=i&&!R&&M,V=a(""),W=a(""),X=C.find("colgroup:first"),Y=!0;0==X.length&&(X=a(""),Y=!1);var Z=a(''),$=a(''),_=!1,ab=a(""),bb=a(''),cb=a([]),db=a([]),eb=a([]),fb=a([]);ab.append(bb),C.prepend(X),m&&(Q.append(Z),C.append(Q)),V.append(W),$.append(V),r.copyTableClass&&V.attr("class",C.attr("class")),V.attr({cellpadding:C.attr("cellpadding"),cellspacing:C.attr("cellspacing"),border:C.attr("border")});var gb=C.css("display");if(V.css({borderCollapse:C.css("borderCollapse"),border:C.css("border"),display:gb}),"none"==gb&&(_=!0),V.addClass(r.floatTableClass).css("margin",0),M){var hb=function(a,b){var c=a.css("position"),d="relative"==c||"absolute"==c;if(!d||b){var e={paddingLeft:a.css("paddingLeft"),paddingRight:a.css("paddingRight")};$.css(e),a=a.wrap("
").parent(),S=!0}return a};R?(T=hb(L,!0),T.append($)):(T=hb(C),C.after($))}else C.after($);$.css({position:M?"absolute":"fixed",marginTop:0,top:M?0:"auto",zIndex:r.zIndex}),$.addClass(r.floatContainerClass),p();var ib={"table-layout":"fixed"},jb={"table-layout":C.css("tableLayout")||"auto"},kb=C[0].style.width||"",lb=C.css("minWidth")||"";A();var mb,nb=function(){(mb=w())()};nb();var ob=y(),pb=z();pb(ob("init"),!0);var qb=g.debounce(function(){pb(ob("windowScrollDone"),!1)},300),rb=function(){pb(ob("windowScroll"),!1),qb()},sb=function(){pb(ob("containerScroll"),!1)},tb=function(){p(),A(),nb(),ob=y(),(pb=z())(ob("resize"),!0,!0)},ub=g.debounce(function(){A(),p(),nb(),ob=y(),pb(ob("reflow"),!0)},1);if(R?M?L.on(c("scroll"),sb):(L.on(c("scroll"),sb),n.on(c("scroll"),rb)):n.on(c("scroll"),rb),n.on(c("load"),ub),b(r.debounceResizeMs,c("resize"),tb),C.on("reflow",ub),e(C)&&C.on("filter",ub).on("sort",ub).on("page",ub),h){var vb=L.length?L[0]:C[0];o=new MutationObserver(function(a){for(var b=function(a){return a&&a[0]&&"THEAD"==a[0].nodeName},c=0;cj?d=setTimeout(i,b-j):(d=null,c||(h=a.apply(f,e)))},j=c&&!d;return d||(d=setTimeout(i,b)),j&&(h=a.apply(f,e)),h}},b}()}(jQuery); \ No newline at end of file diff --git a/jquery.floatThead.js b/jquery.floatThead.js index 7e12caa..16fb6f8 100644 --- a/jquery.floatThead.js +++ b/jquery.floatThead.js @@ -53,6 +53,18 @@ var isFF = /Gecko\//.test(navigator.userAgent); var isWebkit = /WebKit\//.test(navigator.userAgent); + //safari 7 (and perhaps others) reports table width to be parent container's width if max-width is set on table. see: https://github.com/mkoryak/floatThead/issues/108 + var isTableWidthBug = function(){ + if(isWebkit) { + var $test = $('
X
'); + $("body").append($test); + var ret = ($test.find("table").width() == 0); + $test.remove(); + return ret; + } + return false; + }; + var createElements = !isFF && !ieVersion; //FF can read width from elements, but webkit cannot var $window = $(window); @@ -114,6 +126,24 @@ } return false; } + + function tableWidth($table, $fthCells, isOuter){ + // see: https://github.com/mkoryak/floatThead/issues/108 + var fn = isOuter ? "outerWidth": "width"; + if(isTableWidthBug && $table.css("max-width")){ + var w = 0; + if(isOuter) { + w += parseInt($table.css("borderLeft"), 10); + w += parseInt($table.css("borderRight"), 10); + } + for(var i=0; i < $fthCells.length; i++){ + w += $fthCells.get(i).offsetWidth; + } + return w; + } else { + return $table[fn](); + } + } $.fn.floatThead = function(map){ map = map || {}; if(!util){ //may have been included after the script? lets try to grab it again. @@ -135,6 +165,10 @@ } var mObs = null; //mutation observer lives in here if we can use it / make it + if(util.isFunction(isTableWidthBug)) { + isTableWidthBug = isTableWidthBug(); + } + if(util.isString(map)){ var command = map; var ret = this; @@ -156,8 +190,11 @@ debug("Used ["+key+"] key to init plugin, but that param is not an option for the plugin. Valid options are: "+ (util.keys($.floatThead.defaults)).join(', ')); } }); - if(opts.debug && parseFloat($.fn.jquery) <= 1.7){ - debug("jQuery version "+$.fn.jquery+" detected! This plugin supports 1.8 or better, or 1.7.x with jQuery UI 1.8.24 -> http://jqueryui.com/resources/download/jquery-ui-1.8.24.zip") + if(opts.debug){ + var v = $.fn.jquery.split("."); + if(parseInt(v[0], 10) == 1 && parseInt(v[1], 10) <= 7){ + debug("jQuery version "+$.fn.jquery+" detected! This plugin supports 1.8 or better, or 1.7.x with jQuery UI 1.8.24 -> http://jqueryui.com/resources/download/jquery-ui-1.8.24.zip") + } } this.filter(':not(.'+opts.floatTableClass+')').each(function(){ @@ -301,15 +338,15 @@ function setFloatWidth(){ - var tableWidth = $table.outerWidth(); - var width = $scrollContainer.width() || tableWidth; + var tw = tableWidth($table, $fthCells, true); + var width = $scrollContainer.width() || tw; var floatContainerWidth = $scrollContainer.css("overflow-y") != 'hidden' ? width - scrollbarOffset.vertical : width; $floatContainer.width(floatContainerWidth); if(locked){ - var percent = 100 * tableWidth / (floatContainerWidth); + var percent = 100 * tw / (floatContainerWidth); $floatTable.css('width', percent+'%'); } else { - $floatTable.outerWidth(tableWidth); + $floatTable.outerWidth(tw); } } @@ -333,7 +370,7 @@ selector = 'tr:first>'+opts.cellTag; } if(util.isNumber(selector)){ - //its actually a row count. + //its actually a row count. (undocumented, might be removed!) return selector; } $headerColumns = $header.find(selector); @@ -381,10 +418,10 @@ if(!headerFloated){ headerFloated = true; if(useAbsolutePositioning){ //#53, #56 - var tableWidth = $table.width(); + var tw = tableWidth($table, $fthCells); var wrapperWidth = $wrapper.width(); - if(tableWidth > wrapperWidth){ - $table.css('minWidth', tableWidth); + if(tw > wrapperWidth){ + $table.css('minWidth', tw); } } $table.css(layoutFixed); @@ -405,7 +442,7 @@ $table.css(layoutAuto); $floatTable.css(layoutAuto); $table.css('minWidth', originalTableMinWidth); //this looks weird, but its not a bug. Think about it!! - $table.css('minWidth', $table.width()); //#121 + $table.css('minWidth', tableWidth($table, $fthCells)); //#121 } } function changePositioning(isAbsolute){ @@ -641,7 +678,7 @@ if($scrollContainer.data().perfectScrollbar){ scrollbarOffset = {horizontal:0, vertical:0}; } else { - var sw = $scrollContainer.width(), sh = $scrollContainer.height(), th = $table.height(), tw = $table.width(); + var sw = $scrollContainer.width(), sh = $scrollContainer.height(), th = $table.height(), tw = tableWidth($table, $fthCells); var offseth = sw < tw ? scWidth : 0; var offsetv = sh < th ? scWidth : 0; scrollbarOffset.horizontal = sw - offsetv < tw ? scWidth : 0;