Merge branch 'scrollbehavior' into 'master'

Fixes to scroll behavior when dynamically changing table contents

Closes #108

See merge request !137
This commit is contained in:
Felix Hamann 2019-02-09 19:15:40 +01:00
commit e28a441c73

View File

@ -3,14 +3,15 @@
window.utils = window.utils || {}; window.utils = window.utils || {};
window.utils.asyncTable = function(wrapper) { window.utils.asyncTable = function(wrapper, options) {
var tableIdent = #{String dbtIdent}; var tableIdent = #{String dbtIdent};
var shortCircuitHeader = #{String (toPathPiece HeaderDBTableShortcircuit)}; var shortCircuitHeader = #{String (toPathPiece HeaderDBTableShortcircuit)};
var ths = []; var ths = [];
var pagination; var pageLinks = [];
var pagesizeForm; var pagesizeForm;
var scrollTable;
function init() { function init() {
var table = wrapper.querySelector('#' + tableIdent); var table = wrapper.querySelector('#' + tableIdent);
@ -18,54 +19,80 @@
return; return;
} }
ths = Array.from(table.querySelectorAll('th.sortable')); scrollTable = wrapper.querySelector('.scrolltable');
pagination = wrapper.querySelector('#' + tableIdent + '-pagination');
// sortable table headers
ths = Array.from(table.querySelectorAll('th.sortable')).map(function(th) {
return { element: th };
});
// pagination links
var pagination = wrapper.querySelector('#' + tableIdent + '-pagination');
if (pagination) {
pageLinks = Array.from(pagination.querySelectorAll('.page-link')).map(function(link) {
return { element: link };
});
}
// pagesize form
pagesizeForm = wrapper.querySelector('#' + tableIdent + '-pagesize-form'); pagesizeForm = wrapper.querySelector('#' + tableIdent + '-pagesize-form');
// take options into account
if (options && options.scrollToTop) {
window.scrollTo(0, 0);
}
if (options && options.horizPos && scrollTable) {
scrollTable.scrollLeft = options.horizPos;
}
setupListeners(); setupListeners();
wrapper.classList.add('js-initialized'); wrapper.classList.add('js-initialized');
} }
function setupListeners() { function setupListeners() {
ths.forEach(function(th) { ths.forEach(function(th) {
th.addEventListener('click', clickHandler); th.clickHandler = function(event) {
var boundClickHandler = clickHandler.bind(this);
var horizPos = (scrollTable || {}).scrollLeft;
boundClickHandler(event, { horizPos });
};
th.element.addEventListener('click', th.clickHandler);
}); });
if (pagination) { pageLinks.forEach(function(link) {
var pageLinks = Array.from(pagination.querySelectorAll('.page-link')); link.clickHandler = function(event) {
pageLinks.forEach(function(p) { var boundClickHandler = clickHandler.bind(this);
p.addEventListener('click', clickHandler); boundClickHandler(event, { scrollToTop: true });
}); }
} link.element.addEventListener('click', link.clickHandler);
});
if (pagesizeForm) { if (pagesizeForm) {
var pagesizeSelect = pagesizeForm.querySelector('[name=' + tableIdent + '-pagesize]') var pagesizeSelect = pagesizeForm.querySelector('[name=' + tableIdent + '-pagesize]')
pagesizeSelect.addEventListener('change', changeHandler); pagesizeSelect.addEventListener('change', changePagesizeHandler);
} }
} }
function removeListeners() { function removeListeners() {
ths.forEach(function(th) { ths.forEach(function(th) {
th.removeEventListener('click', clickHandler); th.element.removeEventListener('click', th.clickHandler);
}); });
if (pagination) { pageLinks.forEach(function(link) {
var pageLinks = Array.from(pagination.querySelectorAll('.page-link')); link.element.removeEventListener('click', link.clickHandler);
pageLinks.forEach(function(p) { });
p.removeEventListener('click', clickHandler);
});
}
if (pagesizeForm) { if (pagesizeForm) {
var pagesizeSelect = pagesizeForm.querySelector('[name=' + tableIdent + '-pagesize]') var pagesizeSelect = pagesizeForm.querySelector('[name=' + tableIdent + '-pagesize]')
pagesizeSelect.removeEventListener('change', changeHandler); pagesizeSelect.removeEventListener('change', changePagesizeHandler);
} }
} }
function clickHandler(event) { function clickHandler(event, options) {
event.preventDefault(); event.preventDefault();
var url = new URL(window.location.origin + window.location.pathname + getClickDestination(this)); var url = new URL(window.location.origin + window.location.pathname + getClickDestination(this));
updateTableFrom(url); updateTableFrom(url, options);
} }
function getClickDestination(el) { function getClickDestination(el) {
@ -75,7 +102,7 @@
return el.querySelector('a').getAttribute('href'); return el.querySelector('a').getAttribute('href');
} }
function changeHandler(event) { function changePagesizeHandler(event) {
var currentTableUrl = wrapper.dataset.currentUrl || window.location.href; var currentTableUrl = wrapper.dataset.currentUrl || window.location.href;
var url = getUrlWithUpdatedPagesize(currentTableUrl, event.target.value); var url = getUrlWithUpdatedPagesize(currentTableUrl, event.target.value);
url = getUrlWithResetPagenumber(url); url = getUrlWithResetPagenumber(url);
@ -96,12 +123,12 @@
return url.replace(/-page=\d+/, '-page=0'); return url.replace(/-page=\d+/, '-page=0');
} }
function updateWrapperContents(newHtml) { function updateWrapperContents(newHtml, options) {
wrapper.innerHTML = newHtml; wrapper.innerHTML = newHtml;
wrapper.classList.remove("js-initialized"); wrapper.classList.remove("js-initialized");
// setup the wrapper and its components to behave async again // setup the wrapper and its components to behave async again
window.utils.asyncTable(wrapper); window.utils.asyncTable(wrapper, options);
// make sure to hide any new submit buttons // make sure to hide any new submit buttons
document.dispatchEvent(new CustomEvent('setup', { document.dispatchEvent(new CustomEvent('setup', {
@ -113,7 +140,7 @@
} }
// fetches new sorted table from url with params and replaces contents of current table // fetches new sorted table from url with params and replaces contents of current table
function updateTableFrom(url) { function updateTableFrom(url, options) {
fetch(url, { fetch(url, {
credentials: 'same-origin', credentials: 'same-origin',
@ -129,7 +156,7 @@
}).then(function(data) { }).then(function(data) {
wrapper.dataset.currentUrl = url; wrapper.dataset.currentUrl = url;
removeListeners(); removeListeners();
updateWrapperContents(data); updateWrapperContents(data, options);
}).catch(function(err) { }).catch(function(err) {
console.error(err); console.error(err);
}); });