From fe6eae18cc03caaa929fa682fd87688b6142ddd4 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Tue, 27 Feb 2018 12:21:07 -0500 Subject: [PATCH 1/7] Update stickyheader.jquery.js Reevalute the table height and position on scroll. This helps with dom changes such as showing/hiding an element or filtering a table. --- stickyheader.jquery.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/stickyheader.jquery.js b/stickyheader.jquery.js index b82272d..cf7b547 100644 --- a/stickyheader.jquery.js +++ b/stickyheader.jquery.js @@ -7,18 +7,18 @@ jQuery(document).ready(function ($) { var stickyHeader = $('
').addClass('stickyHeader hide').attr('aria-hidden', 'true'); stickyHeader.append(tableClone).find('table').append(theadClone); $(table).after(stickyHeader); - + var tableHeight = $(table).height(); var tableWidth = $(table).width() + Number($(table).css('padding-left').replace(/px/ig,"")) + Number($(table).css('padding-right').replace(/px/ig,"")) + Number($(table).css('border-left-width').replace(/px/ig,"")) + Number($(table).css('border-right-width').replace(/px/ig,"")); - + var headerCells = $(table).find('thead th'); var headerCellHeight = $(headerCells[0]).height(); - + var no_fixed_support = false; if (stickyHeader.css('position') == "absolute") { no_fixed_support = true; } - + var stickyHeaderCells = stickyHeader.find('th'); stickyHeader.css('width', tableWidth); var cellWidths = []; @@ -28,12 +28,18 @@ jQuery(document).ready(function ($) { for (var i = 0, l = headerCells.length; i < l; i++) { $(stickyHeaderCells[i]).css('width', cellWidths[i]); } - + var cutoffTop = $(table).offset().top; var cutoffBottom = tableHeight + cutoffTop - headerCellHeight; - - $(window).scroll(function() { - var currentPosition = $(window).scrollTop(); + + $(window).scroll(function() { + // Reevaluate the table height and position in case it has changed + tableHeight = $(table).height(); + cutoffTop = $(table).offset().top; + cutoffBottom = tableHeight + cutoffTop - headerCellHeight; + + var currentPosition = $(window).scrollTop(); + if (currentPosition > cutoffTop && currentPosition < cutoffBottom) { stickyHeader.removeClass('hide'); if (no_fixed_support) { From 2570a5b61e0c127b9b2cc23b3318811325e5b39a Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Wed, 28 Feb 2018 13:49:25 -0500 Subject: [PATCH 2/7] Update stickyheader.jquery.js - Move table header position and size evaluation to function - Reevaluate on page resize - Reevalute on scroll if the body height has changed --- stickyheader.jquery.js | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/stickyheader.jquery.js b/stickyheader.jquery.js index cf7b547..60f98de 100644 --- a/stickyheader.jquery.js +++ b/stickyheader.jquery.js @@ -1,16 +1,32 @@ +// https://github.com/HarlemSquirrel/stickyHeader/tree/dynamic-page-size + jQuery(document).ready(function ($) { var tables = $('table.stickyHeader'); - tables.each(function(i){ + + tables.each(function (i) { var table = tables[i]; + var bodyHeight, cutoffTop, cutoffBottom, tableHeight, tableWidth; + + function evaluateHeaderPositionAndSize() { + bodyHeight = $('body').height() + tableHeight = $(table).height(); + tableWidth = $(table).width() + + Number($(table).css('padding-left').replace(/px/ig,"")) + + Number($(table).css('padding-right').replace(/px/ig,"")) + + Number($(table).css('border-left-width').replace(/px/ig,"")) + + Number($(table).css('border-right-width').replace(/px/ig,"")); + cutoffTop = $(table).offset().top; + cutoffBottom = tableHeight + cutoffTop - headerCellHeight; + + stickyHeader.css('width', tableWidth); + } + var tableClone = $(table).clone(true).empty().removeClass('stickyHeader'); var theadClone = $(table).find('thead').clone(true); var stickyHeader = $('
').addClass('stickyHeader hide').attr('aria-hidden', 'true'); stickyHeader.append(tableClone).find('table').append(theadClone); $(table).after(stickyHeader); - var tableHeight = $(table).height(); - var tableWidth = $(table).width() + Number($(table).css('padding-left').replace(/px/ig,"")) + Number($(table).css('padding-right').replace(/px/ig,"")) + Number($(table).css('border-left-width').replace(/px/ig,"")) + Number($(table).css('border-right-width').replace(/px/ig,"")); - var headerCells = $(table).find('thead th'); var headerCellHeight = $(headerCells[0]).height(); @@ -19,8 +35,9 @@ jQuery(document).ready(function ($) { no_fixed_support = true; } + evaluateHeaderPositionAndSize() + var stickyHeaderCells = stickyHeader.find('th'); - stickyHeader.css('width', tableWidth); var cellWidths = []; for (var i = 0, l = headerCells.length; i < l; i++) { cellWidths[i] = $(headerCells[i]).width(); @@ -29,17 +46,16 @@ jQuery(document).ready(function ($) { $(stickyHeaderCells[i]).css('width', cellWidths[i]); } - var cutoffTop = $(table).offset().top; - var cutoffBottom = tableHeight + cutoffTop - headerCellHeight; + window.onresize = function () { + evaluateHeaderPositionAndSize() + } $(window).scroll(function() { - // Reevaluate the table height and position in case it has changed - tableHeight = $(table).height(); - cutoffTop = $(table).offset().top; - cutoffBottom = tableHeight + cutoffTop - headerCellHeight; + if (bodyHeight !== $('body').height()) { + evaluateHeaderPositionAndSize() + } var currentPosition = $(window).scrollTop(); - if (currentPosition > cutoffTop && currentPosition < cutoffBottom) { stickyHeader.removeClass('hide'); if (no_fixed_support) { From 76e999baca75165b3b861c1174413821a5960f13 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Thu, 1 Mar 2018 14:05:52 -0500 Subject: [PATCH 3/7] Update stickyheader.jquery.js - Fix th widths - Use spaces instead of tabs for indentation --- stickyheader.jquery.js | 103 ++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/stickyheader.jquery.js b/stickyheader.jquery.js index 60f98de..e26bbc8 100644 --- a/stickyheader.jquery.js +++ b/stickyheader.jquery.js @@ -1,70 +1,67 @@ // https://github.com/HarlemSquirrel/stickyHeader/tree/dynamic-page-size jQuery(document).ready(function ($) { - var tables = $('table.stickyHeader'); + var tables = $('table.stickyHeader'); - tables.each(function (i) { - var table = tables[i]; - var bodyHeight, cutoffTop, cutoffBottom, tableHeight, tableWidth; + tables.each(function (i) { + var table = tables[i]; + var bodyHeight, cutoffTop, cutoffBottom, tableHeight, tableWidth; - function evaluateHeaderPositionAndSize() { - bodyHeight = $('body').height() - tableHeight = $(table).height(); - tableWidth = $(table).width() + - Number($(table).css('padding-left').replace(/px/ig,"")) + - Number($(table).css('padding-right').replace(/px/ig,"")) + - Number($(table).css('border-left-width').replace(/px/ig,"")) + - Number($(table).css('border-right-width').replace(/px/ig,"")); - cutoffTop = $(table).offset().top; - cutoffBottom = tableHeight + cutoffTop - headerCellHeight; + var tableClone = $(table).clone(true).empty().removeClass('stickyHeader'); + var theadClone = $(table).find('thead').clone(true); + var stickyHeader = $('
').addClass('stickyHeader hide').attr('aria-hidden', 'true'); + stickyHeader.append(tableClone).find('table').append(theadClone); + $(table).after(stickyHeader); - stickyHeader.css('width', tableWidth); - } + var headerCells = $(table).find('thead th'); + var headerCellHeight = $(headerCells[0]).height(); - var tableClone = $(table).clone(true).empty().removeClass('stickyHeader'); - var theadClone = $(table).find('thead').clone(true); - var stickyHeader = $('
').addClass('stickyHeader hide').attr('aria-hidden', 'true'); - stickyHeader.append(tableClone).find('table').append(theadClone); - $(table).after(stickyHeader); + var no_fixed_support = false; + if (stickyHeader.css('position') == "absolute") { + no_fixed_support = true; + } + + var stickyHeaderCells = stickyHeader.find('th'); - var headerCells = $(table).find('thead th'); - var headerCellHeight = $(headerCells[0]).height(); + function evaluateHeaderPositionAndSize() { + bodyHeight = $('body').height() + tableHeight = $(table).height(); + tableWidth = $(table).width() + + Number($(table).css('padding-left').replace(/px/ig,"")) + + Number($(table).css('padding-right').replace(/px/ig,"")) + + Number($(table).css('border-left-width').replace(/px/ig,"")) + + Number($(table).css('border-right-width').replace(/px/ig,"")); + cutoffTop = $(table).offset().top; + cutoffBottom = tableHeight + cutoffTop - headerCellHeight; - var no_fixed_support = false; - if (stickyHeader.css('position') == "absolute") { - no_fixed_support = true; - } + for (var i = 0, l = headerCells.length; i < l; i++) { + stickyHeaderCells[i].style.width = headerCells[i].scrollWidth + 'px' + } - evaluateHeaderPositionAndSize() + stickyHeader.css('width', tableWidth); + } - var stickyHeaderCells = stickyHeader.find('th'); - var cellWidths = []; - for (var i = 0, l = headerCells.length; i < l; i++) { - cellWidths[i] = $(headerCells[i]).width(); - } - for (var i = 0, l = headerCells.length; i < l; i++) { - $(stickyHeaderCells[i]).css('width', cellWidths[i]); - } + evaluateHeaderPositionAndSize() window.onresize = function () { - evaluateHeaderPositionAndSize() + evaluateHeaderPositionAndSize() } - $(window).scroll(function() { - if (bodyHeight !== $('body').height()) { - evaluateHeaderPositionAndSize() - } + $(window).scroll(function() { + if (bodyHeight !== $('body').height()) { + evaluateHeaderPositionAndSize() + } - var currentPosition = $(window).scrollTop(); - if (currentPosition > cutoffTop && currentPosition < cutoffBottom) { - stickyHeader.removeClass('hide'); - if (no_fixed_support) { - stickyHeader.css('top', currentPosition + 'px'); - } - } - else { - stickyHeader.addClass('hide'); - } - }); - }); + var currentPosition = $(window).scrollTop(); + if (currentPosition > cutoffTop && currentPosition < cutoffBottom) { + stickyHeader.removeClass('hide'); + if (no_fixed_support) { + stickyHeader.css('top', currentPosition + 'px'); + } + } + else { + stickyHeader.addClass('hide'); + } + }); + }); }); From 78b37015f917d0573bf737934a9fcc1a6844c052 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Fri, 2 Mar 2018 10:48:33 -0500 Subject: [PATCH 4/7] Update stickyheader.jquery.js Account for other scripts that might set header width attr --- stickyheader.jquery.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/stickyheader.jquery.js b/stickyheader.jquery.js index e26bbc8..37eb558 100644 --- a/stickyheader.jquery.js +++ b/stickyheader.jquery.js @@ -35,7 +35,13 @@ jQuery(document).ready(function ($) { cutoffBottom = tableHeight + cutoffTop - headerCellHeight; for (var i = 0, l = headerCells.length; i < l; i++) { - stickyHeaderCells[i].style.width = headerCells[i].scrollWidth + 'px' + if (headerCells[i].style.width.length > 0) { + // This takes into account other scripts that set header width + // such as DataTables + stickyHeaderCells[i].style.width = headerCells[i].style.width + } else { + stickyHeaderCells[i].style.width = headerCells[i].scrollWidth + 'px' + } } stickyHeader.css('width', tableWidth); From 243ea05281389f14565d6e072459d43c354003fb Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Tue, 20 Mar 2018 17:33:14 -0400 Subject: [PATCH 5/7] Update stickyheader.jquery.js - Set header classes on click to account for sorting scripts etc. - Remove unneeded comment - Simplify no_fixed_support --- stickyheader.jquery.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/stickyheader.jquery.js b/stickyheader.jquery.js index 37eb558..f75af43 100644 --- a/stickyheader.jquery.js +++ b/stickyheader.jquery.js @@ -1,5 +1,3 @@ -// https://github.com/HarlemSquirrel/stickyHeader/tree/dynamic-page-size - jQuery(document).ready(function ($) { var tables = $('table.stickyHeader'); @@ -16,10 +14,7 @@ jQuery(document).ready(function ($) { var headerCells = $(table).find('thead th'); var headerCellHeight = $(headerCells[0]).height(); - var no_fixed_support = false; - if (stickyHeader.css('position') == "absolute") { - no_fixed_support = true; - } + var no_fixed_support = (stickyHeader.css('position') === 'absolute'); var stickyHeaderCells = stickyHeader.find('th'); @@ -47,12 +42,23 @@ jQuery(document).ready(function ($) { stickyHeader.css('width', tableWidth); } + function setClassNames() { + for (var i = 0; i < stickyHeader.find('th').length; i++) { + stickyHeader.find('th')[i].className = $(table).find('thead th')[i].className + } + } + evaluateHeaderPositionAndSize() window.onresize = function () { evaluateHeaderPositionAndSize() } + // Sometimes header class names change when clicked + // such as with dataTables sorting + $(table).find('th').click(setClassNames) + stickyHeader.find('th').click(setClassNames) + $(window).scroll(function() { if (bodyHeight !== $('body').height()) { evaluateHeaderPositionAndSize() From 7f481a3cbb3ba7e1a2fb990d87412d18deee4718 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Tue, 20 Mar 2018 17:36:35 -0400 Subject: [PATCH 6/7] Use camelCase in stickyheader.jquery.js --- stickyheader.jquery.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stickyheader.jquery.js b/stickyheader.jquery.js index f75af43..42e4242 100644 --- a/stickyheader.jquery.js +++ b/stickyheader.jquery.js @@ -14,7 +14,7 @@ jQuery(document).ready(function ($) { var headerCells = $(table).find('thead th'); var headerCellHeight = $(headerCells[0]).height(); - var no_fixed_support = (stickyHeader.css('position') === 'absolute'); + var noFixedSupport = (stickyHeader.css('position') === 'absolute'); var stickyHeaderCells = stickyHeader.find('th'); @@ -67,7 +67,7 @@ jQuery(document).ready(function ($) { var currentPosition = $(window).scrollTop(); if (currentPosition > cutoffTop && currentPosition < cutoffBottom) { stickyHeader.removeClass('hide'); - if (no_fixed_support) { + if (noFixedSupport) { stickyHeader.css('top', currentPosition + 'px'); } } From 3f90c211e4f86e64a05b058167066b52118448d9 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Thu, 29 Mar 2018 10:55:54 -0400 Subject: [PATCH 7/7] Update stickyheader.jquery Use a global constant with a run() function so we can call this from other scripts such as a `turbolinks:load` event. --- stickyheader.jquery.js | 124 +++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 59 deletions(-) diff --git a/stickyheader.jquery.js b/stickyheader.jquery.js index 42e4242..47569c5 100644 --- a/stickyheader.jquery.js +++ b/stickyheader.jquery.js @@ -1,79 +1,85 @@ -jQuery(document).ready(function ($) { - var tables = $('table.stickyHeader'); +const STICK_HEADER = { + run: function () { + var $tables = $('table.stickyHeader'); - tables.each(function (i) { - var table = tables[i]; - var bodyHeight, cutoffTop, cutoffBottom, tableHeight, tableWidth; + $tables.each(function (i) { + var table = $tables[i]; + var bodyHeight, cutoffTop, cutoffBottom, tableHeight, tableWidth; - var tableClone = $(table).clone(true).empty().removeClass('stickyHeader'); - var theadClone = $(table).find('thead').clone(true); - var stickyHeader = $('
').addClass('stickyHeader hide').attr('aria-hidden', 'true'); - stickyHeader.append(tableClone).find('table').append(theadClone); - $(table).after(stickyHeader); + var tableClone = $(table).clone(true).empty().removeClass('stickyHeader'); + var theadClone = $(table).find('thead').clone(true); + var stickyHeader = $('
').addClass('stickyHeader hide').attr('aria-hidden', 'true'); + stickyHeader.append(tableClone).find('table').append(theadClone); + $(table).after(stickyHeader); - var headerCells = $(table).find('thead th'); - var headerCellHeight = $(headerCells[0]).height(); + var headerCells = $(table).find('thead th'); + var headerCellHeight = $(headerCells[0]).height(); - var noFixedSupport = (stickyHeader.css('position') === 'absolute'); + var noFixedSupport = (stickyHeader.css('position') === 'absolute'); - var stickyHeaderCells = stickyHeader.find('th'); + var stickyHeaderCells = stickyHeader.find('th'); - function evaluateHeaderPositionAndSize() { - bodyHeight = $('body').height() - tableHeight = $(table).height(); - tableWidth = $(table).width() + - Number($(table).css('padding-left').replace(/px/ig,"")) + - Number($(table).css('padding-right').replace(/px/ig,"")) + - Number($(table).css('border-left-width').replace(/px/ig,"")) + - Number($(table).css('border-right-width').replace(/px/ig,"")); - cutoffTop = $(table).offset().top; - cutoffBottom = tableHeight + cutoffTop - headerCellHeight; + function evaluateHeaderPositionAndSize() { + bodyHeight = $('body').height() + tableHeight = $(table).height(); + tableWidth = $(table).width() + + Number($(table).css('padding-left').replace(/px/ig,"")) + + Number($(table).css('padding-right').replace(/px/ig,"")) + + Number($(table).css('border-left-width').replace(/px/ig,"")) + + Number($(table).css('border-right-width').replace(/px/ig,"")); + cutoffTop = $(table).offset().top; + cutoffBottom = tableHeight + cutoffTop - headerCellHeight; - for (var i = 0, l = headerCells.length; i < l; i++) { - if (headerCells[i].style.width.length > 0) { - // This takes into account other scripts that set header width - // such as DataTables - stickyHeaderCells[i].style.width = headerCells[i].style.width - } else { - stickyHeaderCells[i].style.width = headerCells[i].scrollWidth + 'px' + for (var i = 0, l = headerCells.length; i < l; i++) { + if (headerCells[i].style.width.length > 0) { + // This takes into account other scripts that set header width + // such as DataTables + stickyHeaderCells[i].style.width = headerCells[i].style.width + } else { + stickyHeaderCells[i].style.width = headerCells[i].scrollWidth + 'px' + } } - } - stickyHeader.css('width', tableWidth); - } - - function setClassNames() { - for (var i = 0; i < stickyHeader.find('th').length; i++) { - stickyHeader.find('th')[i].className = $(table).find('thead th')[i].className + stickyHeader.css('width', tableWidth); } - } - evaluateHeaderPositionAndSize() + function setClassNames() { + for (var i = 0; i < stickyHeader.find('th').length; i++) { + stickyHeader.find('th')[i].className = $(table).find('thead th')[i].className + } + } - window.onresize = function () { evaluateHeaderPositionAndSize() - } - - // Sometimes header class names change when clicked - // such as with dataTables sorting - $(table).find('th').click(setClassNames) - stickyHeader.find('th').click(setClassNames) - $(window).scroll(function() { - if (bodyHeight !== $('body').height()) { + window.onresize = function () { evaluateHeaderPositionAndSize() } - var currentPosition = $(window).scrollTop(); - if (currentPosition > cutoffTop && currentPosition < cutoffBottom) { - stickyHeader.removeClass('hide'); - if (noFixedSupport) { - stickyHeader.css('top', currentPosition + 'px'); + // Sometimes header class names change when clicked + // such as with dataTables sorting + $(table).find('th').click(setClassNames) + stickyHeader.find('th').click(setClassNames) + + $(window).scroll(function() { + if (bodyHeight !== $('body').height()) { + evaluateHeaderPositionAndSize() } - } - else { - stickyHeader.addClass('hide'); - } + + var currentPosition = $(window).scrollTop(); + if (currentPosition > cutoffTop && currentPosition < cutoffBottom) { + stickyHeader.removeClass('hide'); + if (noFixedSupport) { + stickyHeader.css('top', currentPosition + 'px'); + } + } + else { + stickyHeader.addClass('hide'); + } + }); }); - }); + } +} + +jQuery(document).ready(function ($) { + STICK_HEADER.run() });