From c86362805d59ee0edf3246f56a9ca9246cd57d17 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Mon, 9 Jul 2018 11:15:09 -0700 Subject: [PATCH 1/7] add ability to pass an optional jquery element to use as a wrapper for tables that need horizontal scrolling --- js/jquery.stickytableheaders.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/js/jquery.stickytableheaders.js b/js/jquery.stickytableheaders.js index 4d742f1..4b6e2bf 100644 --- a/js/jquery.stickytableheaders.js +++ b/js/jquery.stickytableheaders.js @@ -15,7 +15,8 @@ objWindow: window, scrollableArea: window, cacheHeaderHeight: false, - zIndex: 3 + zIndex: 3, + horizontalWrapper }; function Plugin (el, options) { @@ -162,7 +163,7 @@ } if (scrolledPastTop && notScrolledPastBottom) { - newLeft = offset.left - scrollLeft + base.options.leftOffset; + newLeft = !base.options.horizontalWrapper ? offset.left - scrollLeft + base.options.leftOffset : base.options.horizontalWrapper.offset().left - scrollLeft + base.options.leftOffset; base.$originalHeader.css({ 'position': 'fixed', 'margin-top': base.options.marginTop, From 6b5433f8a40bc2796c41986a1a7f1ac75b363c81 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Mon, 9 Jul 2018 12:03:24 -0700 Subject: [PATCH 2/7] get width from optional wrapper element if included --- js/jquery.stickytableheaders.js | 9 ++++++--- readme.md | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/js/jquery.stickytableheaders.js b/js/jquery.stickytableheaders.js index 4b6e2bf..ad3783c 100644 --- a/js/jquery.stickytableheaders.js +++ b/js/jquery.stickytableheaders.js @@ -163,7 +163,8 @@ } if (scrolledPastTop && notScrolledPastBottom) { - newLeft = !base.options.horizontalWrapper ? offset.left - scrollLeft + base.options.leftOffset : base.options.horizontalWrapper.offset().left - scrollLeft + base.options.leftOffset; + const $horizontalWrapper = base.options.horizontalWrapper && !(base.options.horizontalWrapper instanceof jQuery) ? $(base.options.horizontalWrapper) : base.options.horizontalWrapper; + newLeft = !$horizontalWrapper ? offset.left - scrollLeft + base.options.leftOffset : $horizontalWrapper.offset().left - scrollLeft + base.options.leftOffset; base.$originalHeader.css({ 'position': 'fixed', 'margin-top': base.options.marginTop, @@ -220,8 +221,10 @@ var cellWidths = base.getWidth(base.$clonedHeaderCells); base.setWidth(cellWidths, base.$clonedHeaderCells, base.$originalHeaderCells); - // Copy row width from whole table - base.$originalHeader.css('width', base.$clonedHeader.width()); + // Copy row width from whole table or from the optional wrapper element + const $horizontalWrapper = base.options.horizontalWrapper && !(base.options.horizontalWrapper instanceof jQuery) ? $(base.options.horizontalWrapper) : base.options.horizontalWrapper; + const newWidth = $horizontalWrapper ? $horizontalWrapper.width() : base.$clonedHeader.width(); + base.$originalHeader.css('width', newWidth); // If we're caching the height, we need to update the cached value when the width changes if (base.options.cacheHeaderHeight) { diff --git a/readme.md b/readme.md index 4cc0725..e1be817 100644 --- a/readme.md +++ b/readme.md @@ -74,6 +74,9 @@ Default value: `false` $('table').stickyTableHeaders({cacheHeaderHeight: true}); ``` +####`horizontalWrapper` +A DOM element or jQuery object. An optional element used to function as a wrapper to allow horizontal scrolling of tables with widths wider than the screen. + #### z-index The plugin uses z-index to make the thead overlay the body. You can override the z-index value by passing in a `zIndex` option: From 3a987453a0746e5a2fae25342f6b1f09957c081b Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Mon, 9 Jul 2018 12:09:19 -0700 Subject: [PATCH 3/7] fix missing value for horizontalWrapper when options are initialized --- js/jquery.stickytableheaders.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/jquery.stickytableheaders.js b/js/jquery.stickytableheaders.js index ad3783c..5271ec3 100644 --- a/js/jquery.stickytableheaders.js +++ b/js/jquery.stickytableheaders.js @@ -16,7 +16,7 @@ scrollableArea: window, cacheHeaderHeight: false, zIndex: 3, - horizontalWrapper + horizontalWrapper: null }; function Plugin (el, options) { From f9f957b83bf9b6314b3d4d4c1dad444fae9af312 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Mon, 9 Jul 2018 14:14:16 -0700 Subject: [PATCH 4/7] update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index e1be817..74669e9 100644 --- a/readme.md +++ b/readme.md @@ -74,7 +74,7 @@ Default value: `false` $('table').stickyTableHeaders({cacheHeaderHeight: true}); ``` -####`horizontalWrapper` +#### horizontalWrapper A DOM element or jQuery object. An optional element used to function as a wrapper to allow horizontal scrolling of tables with widths wider than the screen. #### z-index From cb21badde0599d9af080f9f719f9a7bef627eee6 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Mon, 9 Jul 2018 16:46:24 -0700 Subject: [PATCH 5/7] remove es6 syntax --- js/jquery.stickytableheaders.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/jquery.stickytableheaders.js b/js/jquery.stickytableheaders.js index 5271ec3..cf61a8c 100644 --- a/js/jquery.stickytableheaders.js +++ b/js/jquery.stickytableheaders.js @@ -163,7 +163,7 @@ } if (scrolledPastTop && notScrolledPastBottom) { - const $horizontalWrapper = base.options.horizontalWrapper && !(base.options.horizontalWrapper instanceof jQuery) ? $(base.options.horizontalWrapper) : base.options.horizontalWrapper; + var $horizontalWrapper = base.options.horizontalWrapper && !(base.options.horizontalWrapper instanceof jQuery) ? $(base.options.horizontalWrapper) : base.options.horizontalWrapper; newLeft = !$horizontalWrapper ? offset.left - scrollLeft + base.options.leftOffset : $horizontalWrapper.offset().left - scrollLeft + base.options.leftOffset; base.$originalHeader.css({ 'position': 'fixed', @@ -222,8 +222,8 @@ base.setWidth(cellWidths, base.$clonedHeaderCells, base.$originalHeaderCells); // Copy row width from whole table or from the optional wrapper element - const $horizontalWrapper = base.options.horizontalWrapper && !(base.options.horizontalWrapper instanceof jQuery) ? $(base.options.horizontalWrapper) : base.options.horizontalWrapper; - const newWidth = $horizontalWrapper ? $horizontalWrapper.width() : base.$clonedHeader.width(); + var $horizontalWrapper = base.options.horizontalWrapper && !(base.options.horizontalWrapper instanceof jQuery) ? $(base.options.horizontalWrapper) : base.options.horizontalWrapper; + var newWidth = $horizontalWrapper ? $horizontalWrapper.width() : base.$clonedHeader.width(); base.$originalHeader.css('width', newWidth); // If we're caching the height, we need to update the cached value when the width changes From 283ef200a028f71a919c4726c3fa0d05be195217 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Mon, 9 Jul 2018 16:46:53 -0700 Subject: [PATCH 6/7] create uglified version --- js/jquery.stickytableheaders.min.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/jquery.stickytableheaders.min.js b/js/jquery.stickytableheaders.min.js index 6579c01..ecf216a 100644 --- a/js/jquery.stickytableheaders.min.js +++ b/js/jquery.stickytableheaders.min.js @@ -1,6 +1,6 @@ /*! - * StickyTableHeaders 0.1.24 (2018-01-14 23:29) + * StickyTableHeaders 0.1.24 (2018-07-09 16:45) * MIT licensed * Copyright (C) Jonas Mosbech - https://github.com/jmosbech/StickyTableHeaders */ -!function(e,i,t){"use strict";var o="stickyTableHeaders",n=0,d={fixedOffset:0,leftOffset:0,marginTop:0,objDocument:document,objHead:"head",objWindow:i,scrollableArea:i,cacheHeaderHeight:!1,zIndex:3};e.fn[o]=function(t){return this.each(function(){var l=e.data(this,"plugin_"+o);l?"string"==typeof t?l[t].apply(l):l.updateOptions(t):"destroy"!==t&&e.data(this,"plugin_"+o,new function(t,l){var a=this;a.$el=e(t),a.el=t,a.id=n++,a.$el.bind("destroyed",e.proxy(a.teardown,a)),a.$clonedHeader=null,a.$originalHeader=null,a.cachedHeaderHeight=null,a.isSticky=!1,a.hasBeenSticky=!1,a.leftOffset=null,a.topOffset=null,a.init=function(){a.setOptions(l),a.$el.each(function(){var i=e(this);i.css("padding",0),a.$originalHeader=e("thead:first",this),a.$clonedHeader=a.$originalHeader.clone(),i.trigger("clonedHeader."+o,[a.$clonedHeader]),a.$clonedHeader.addClass("tableFloatingHeader"),a.$clonedHeader.css({display:"none",opacity:0}),a.$originalHeader.addClass("tableFloatingHeaderOriginal"),a.$originalHeader.after(a.$clonedHeader),a.$printStyle=e(''),a.$head.append(a.$printStyle)}),a.$clonedHeader.find("input, select").attr("disabled",!0),a.updateWidth(),a.toggleHeaders(),a.bind()},a.destroy=function(){a.$el.unbind("destroyed",a.teardown),a.teardown()},a.teardown=function(){a.isSticky&&a.$originalHeader.css("position","static"),e.removeData(a.el,"plugin_"+o),a.unbind(),a.$clonedHeader.remove(),a.$originalHeader.removeClass("tableFloatingHeaderOriginal"),a.$originalHeader.css("visibility","visible"),a.$printStyle.remove(),a.el=null,a.$el=null},a.bind=function(){a.$scrollableArea.on("scroll."+o,a.toggleHeaders),a.isWindowScrolling||(a.$window.on("scroll."+o+a.id,a.setPositionValues),a.$window.on("resize."+o+a.id,a.toggleHeaders)),a.$scrollableArea.on("resize."+o,a.toggleHeaders),a.$scrollableArea.on("resize."+o,a.updateWidth)},a.unbind=function(){a.$scrollableArea.off("."+o,a.toggleHeaders),a.isWindowScrolling||(a.$window.off("."+o+a.id,a.setPositionValues),a.$window.off("."+o+a.id,a.toggleHeaders)),a.$scrollableArea.off("."+o,a.updateWidth)},a.debounce=function(e,i){var t=null;return function(){var o=this,n=arguments;clearTimeout(t),t=setTimeout(function(){e.apply(o,n)},i)}},a.toggleHeaders=a.debounce(function(){a.$el&&a.$el.each(function(){var i,t,n,d=e(this),l=a.isWindowScrolling?isNaN(a.options.fixedOffset)?a.options.fixedOffset.outerHeight():a.options.fixedOffset:a.$scrollableArea.offset().top+(isNaN(a.options.fixedOffset)?0:a.options.fixedOffset),s=d.offset(),r=a.$scrollableArea.scrollTop()+l,c=a.$scrollableArea.scrollLeft(),f=a.isWindowScrolling?r>s.top:l>s.top;f&&(t=a.options.cacheHeaderHeight?a.cachedHeaderHeight:a.$clonedHeader.height(),n=(a.isWindowScrolling?r:0)a.$document.height()||i<0||i+a.$window.width()>a.$document.width()||a.$originalHeader.css({top:a.topOffset-(a.isWindowScrolling?0:e),left:a.leftOffset-(a.isWindowScrolling?0:i)})},0),a.updateWidth=a.debounce(function(){if(a.isSticky){a.$originalHeaderCells||(a.$originalHeaderCells=e("th,td",a.$originalHeader)),a.$clonedHeaderCells||(a.$clonedHeaderCells=e("th,td",a.$clonedHeader));var i=a.getWidth(a.$clonedHeaderCells);a.setWidth(i,a.$clonedHeaderCells,a.$originalHeaderCells),a.$originalHeader.css("width",a.$clonedHeader.width()),a.options.cacheHeaderHeight&&(a.cachedHeaderHeight=a.$clonedHeader.height())}},0),a.getWidth=function(t){var o=[];return t.each(function(t){var n,d=e(this);if("border-box"===d.css("box-sizing")){var l=d[0].getBoundingClientRect();n=l.width?l.width:l.right-l.left}else if("collapse"===e("th",a.$originalHeader).css("border-collapse"))if(i.getComputedStyle)n=parseFloat(i.getComputedStyle(this,null).width);else{var s=parseFloat(d.css("padding-left")),r=parseFloat(d.css("padding-right")),c=parseFloat(d.css("border-width"));n=d.outerWidth()-s-r-c}else n=d.width();o[t]=n}),o},a.setWidth=function(e,i,t){i.each(function(i){var o=e[i];t.eq(i).css({"min-width":o,"max-width":o})})},a.resetWidth=function(i,t){i.each(function(i){var o=e(this);t.eq(i).css({"min-width":o.css("min-width"),"max-width":o.css("max-width")})})},a.setOptions=function(i){a.options=e.extend({},d,i),a.$window=e(a.options.objWindow),a.$head=e(a.options.objHead),a.$document=e(a.options.objDocument),a.$scrollableArea=e(a.options.scrollableArea),a.isWindowScrolling=a.$scrollableArea[0]===a.$window[0]},a.updateOptions=function(e){a.setOptions(e),a.unbind(),a.bind(),a.updateWidth(),a.toggleHeaders()},a.init()}(this,t))})}}(jQuery,window); \ No newline at end of file +!function(p,r,e){"use strict";var f="stickyTableHeaders",t=0,o={fixedOffset:0,leftOffset:0,marginTop:0,objDocument:document,objHead:"head",objWindow:r,scrollableArea:r,cacheHeaderHeight:!1,zIndex:3,horizontalWrapper:null};function n(e,i){var c=this;c.$el=p(e),c.el=e,c.id=t++,c.$el.bind("destroyed",p.proxy(c.teardown,c)),c.$clonedHeader=null,c.$originalHeader=null,c.cachedHeaderHeight=null,c.isSticky=!1,c.hasBeenSticky=!1,c.leftOffset=null,c.topOffset=null,c.init=function(){c.setOptions(i),c.$el.each(function(){var e=p(this);e.css("padding",0),c.$originalHeader=p("thead:first",this),c.$clonedHeader=c.$originalHeader.clone(),e.trigger("clonedHeader."+f,[c.$clonedHeader]),c.$clonedHeader.addClass("tableFloatingHeader"),c.$clonedHeader.css({display:"none",opacity:0}),c.$originalHeader.addClass("tableFloatingHeaderOriginal"),c.$originalHeader.after(c.$clonedHeader),c.$printStyle=p(''),c.$head.append(c.$printStyle)}),c.$clonedHeader.find("input, select").attr("disabled",!0),c.updateWidth(),c.toggleHeaders(),c.bind()},c.destroy=function(){c.$el.unbind("destroyed",c.teardown),c.teardown()},c.teardown=function(){c.isSticky&&c.$originalHeader.css("position","static"),p.removeData(c.el,"plugin_"+f),c.unbind(),c.$clonedHeader.remove(),c.$originalHeader.removeClass("tableFloatingHeaderOriginal"),c.$originalHeader.css("visibility","visible"),c.$printStyle.remove(),c.el=null,c.$el=null},c.bind=function(){c.$scrollableArea.on("scroll."+f,c.toggleHeaders),c.isWindowScrolling||(c.$window.on("scroll."+f+c.id,c.setPositionValues),c.$window.on("resize."+f+c.id,c.toggleHeaders)),c.$scrollableArea.on("resize."+f,c.toggleHeaders),c.$scrollableArea.on("resize."+f,c.updateWidth)},c.unbind=function(){c.$scrollableArea.off("."+f,c.toggleHeaders),c.isWindowScrolling||(c.$window.off("."+f+c.id,c.setPositionValues),c.$window.off("."+f+c.id,c.toggleHeaders)),c.$scrollableArea.off("."+f,c.updateWidth)},c.debounce=function(t,o){var n=null;return function(){var e=this,i=arguments;clearTimeout(n),n=setTimeout(function(){t.apply(e,i)},o)}},c.toggleHeaders=c.debounce(function(){c.$el&&c.$el.each(function(){var e,i,t,o=p(this),n=c.isWindowScrolling?isNaN(c.options.fixedOffset)?c.options.fixedOffset.outerHeight():c.options.fixedOffset:c.$scrollableArea.offset().top+(isNaN(c.options.fixedOffset)?0:c.options.fixedOffset),a=o.offset(),l=c.$scrollableArea.scrollTop()+n,s=c.$scrollableArea.scrollLeft(),r=c.isWindowScrolling?l>a.top:n>a.top;if(r&&(i=c.options.cacheHeaderHeight?c.cachedHeaderHeight:c.$clonedHeader.height(),t=(c.isWindowScrolling?l:0)c.$document.height()||i<0||i+c.$window.width()>c.$document.width()||c.$originalHeader.css({top:c.topOffset-(c.isWindowScrolling?0:e),left:c.leftOffset-(c.isWindowScrolling?0:i)})},0),c.updateWidth=c.debounce(function(){if(c.isSticky){c.$originalHeaderCells||(c.$originalHeaderCells=p("th,td",c.$originalHeader)),c.$clonedHeaderCells||(c.$clonedHeaderCells=p("th,td",c.$clonedHeader));var e=c.getWidth(c.$clonedHeaderCells);c.setWidth(e,c.$clonedHeaderCells,c.$originalHeaderCells);var i=!c.options.horizontalWrapper||c.options.horizontalWrapper instanceof jQuery?c.options.horizontalWrapper:p(c.options.horizontalWrapper),t=i?i.width():c.$clonedHeader.width();c.$originalHeader.css("width",t),c.options.cacheHeaderHeight&&(c.cachedHeaderHeight=c.$clonedHeader.height())}},0),c.getWidth=function(e){var s=[];return e.each(function(e){var i,t=p(this);if("border-box"===t.css("box-sizing")){var o=t[0].getBoundingClientRect();i=o.width?o.width:o.right-o.left}else{if("collapse"===p("th",c.$originalHeader).css("border-collapse"))if(r.getComputedStyle)i=parseFloat(r.getComputedStyle(this,null).width);else{var n=parseFloat(t.css("padding-left")),a=parseFloat(t.css("padding-right")),l=parseFloat(t.css("border-width"));i=t.outerWidth()-n-a-l}else i=t.width()}s[e]=i}),s},c.setWidth=function(t,e,o){e.each(function(e){var i=t[e];o.eq(e).css({"min-width":i,"max-width":i})})},c.resetWidth=function(e,t){e.each(function(e){var i=p(this);t.eq(e).css({"min-width":i.css("min-width"),"max-width":i.css("max-width")})})},c.setOptions=function(e){c.options=p.extend({},o,e),c.$window=p(c.options.objWindow),c.$head=p(c.options.objHead),c.$document=p(c.options.objDocument),c.$scrollableArea=p(c.options.scrollableArea),c.isWindowScrolling=c.$scrollableArea[0]===c.$window[0]},c.updateOptions=function(e){c.setOptions(e),c.unbind(),c.bind(),c.updateWidth(),c.toggleHeaders()},c.init()}p.fn[f]=function(i){return this.each(function(){var e=p.data(this,"plugin_"+f);e?"string"==typeof i?e[i].apply(e):e.updateOptions(i):"destroy"!==i&&p.data(this,"plugin_"+f,new n(this,i))})}}(jQuery,window); \ No newline at end of file From 59bed9b0743171445cc3c88cea0adc30ee894e88 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Mon, 9 Jul 2018 16:51:50 -0700 Subject: [PATCH 7/7] update readme.md --- readme.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readme.md b/readme.md index 74669e9..3555c35 100644 --- a/readme.md +++ b/readme.md @@ -77,6 +77,10 @@ $('table').stickyTableHeaders({cacheHeaderHeight: true}); #### horizontalWrapper A DOM element or jQuery object. An optional element used to function as a wrapper to allow horizontal scrolling of tables with widths wider than the screen. +```js +$('table').stickyTableHeaders({horizontalWrapper:$('.horizontal-scroll-area')}); +``` + #### z-index The plugin uses z-index to make the thead overlay the body. You can override the z-index value by passing in a `zIndex` option: