feat: make pagesize changes load async

This commit is contained in:
Felix Hamann 2019-01-28 22:52:46 +01:00
parent 19d46eb216
commit 6486120536
4 changed files with 128 additions and 89 deletions

View File

@ -9,7 +9,7 @@ $else
_{MsgRowCount rowCount} _{MsgRowCount rowCount}
$# Since the current pagesize is always a member of pagesizeOptions we don't need to check `pageCount > 1` $# Since the current pagesize is always a member of pagesizeOptions we don't need to check `pageCount > 1`
$if toEnum (fromIntegral rowCount) > minimum (pagesizeOptions referencePagesize) $if toEnum (fromIntegral rowCount) > minimum (pagesizeOptions referencePagesize)
<form .pagesize method=GET enctype=#{pagesizeEnc} action=#{rawAction}> <form .pagesize ##{wIdent "pagesize-form"} method=GET enctype=#{pagesizeEnc} action=#{rawAction}>
^{pagesizeWdgt} ^{pagesizeWdgt}
$if pageCount > 1 $if pageCount > 1

View File

@ -1,94 +1,148 @@
(function collonadeClosure() { (function collonadeClosure() {
'use strict'; 'use strict';
document.addEventListener('setup', function DOMContentLoaded(e) { window.utils = window.utils || {};
console.log('dbtable', e); window.utils.asyncTable = function(wrapper) {
if (e.detail.module && e.detail.module !== 'dbtable') var tableIdent = #{String dbtIdent};
return; var shortCircuitHeader = #{String (toPathPiece HeaderDBTableShortcircuit)};
function setupAsync(wrapper) { var ths = [];
var pagination;
var pagesizeForm;
var table = wrapper.querySelector('#' + #{String dbtIdent}); function init() {
if (!table) var table = wrapper.querySelector('#' + tableIdent);
if (!table) {
return; return;
}
var ths = Array.from(table.querySelectorAll('th.sortable')); ths = Array.from(table.querySelectorAll('th.sortable'));
var pagination = wrapper.querySelector('#' + #{String dbtIdent} + '-pagination'); pagination = wrapper.querySelector('#' + tableIdent + '-pagination');
pagesizeForm = wrapper.querySelector('#' + tableIdent + '-pagesize-form');
setupListeners();
wrapper.classList.add('js-initialized');
}
function setupListeners() {
ths.forEach(function(th) { ths.forEach(function(th) {
th.addEventListener('click', clickHandler); th.addEventListener('click', clickHandler);
}); });
if (pagination) { if (pagination) {
Array.from(pagination.querySelectorAll('.page-link')) var pageLinks = Array.from(pagination.querySelectorAll('.page-link'));
.forEach(function(p) { pageLinks.forEach(function(p) {
p.addEventListener('click', clickHandler); p.addEventListener('click', clickHandler);
});
}
function clickHandler(event) {
event.preventDefault();
var url = new URL(window.location.origin + window.location.pathname + getClickDestination(this));
updateTableFrom(url);
}
function getClickDestination(el) {
console.log(el);
if (!el.querySelector('a')) {
return false;
}
return el.querySelector('a').getAttribute('href');
}
// fetches new sorted table from url with params and replaces contents of current table
function updateTableFrom(url) {
fetch(url, {
credentials: 'same-origin',
headers: {
'Accept': 'text/html',
#{String (toPathPiece HeaderDBTableShortcircuit)}: #{String dbtIdent}
}
}).then(function(response) {
if (!response.ok) {
throw ('Looks like there was a problem fetching ' + url.toString() + '. Status Code: ' + response.status);
}
return response.text();
}).then(function(data) {
// remove listeners
ths.forEach(function(th) {
th.removeEventListener('click', clickHandler);
});
// replace contents of table body
wrapper.innerHTML = data;
// set up async functionality again
wrapper.classList.remove("js-initialized");
document.dispatchEvent(new CustomEvent('setup', {
detail: { scope: wrapper },
bubbles: true,
cancelable: true
}));
// table.querySelector('tbody').innerHTML = data;
}).catch(function(err) {
console.error(err);
}); });
} }
wrapper.classList.add("js-initialized"); if (pagesizeForm) {
var pagesizeSelect = pagesizeForm.querySelector('[name=' + tableIdent + '-pagesize]')
pagesizeSelect.addEventListener('change', changeHandler);
}
} }
var selector = '#' + #{String $ dbtIdent} + '-table-wrapper:not(.js-initialized)'; function removeListeners() {
var wrapperEl = e.detail.scope.querySelector(selector); ths.forEach(function(th) {
if (wrapperEl) th.removeEventListener('click', clickHandler);
setupAsync(wrapperEl); });
else if (e.detail.scope.matches(selector))
setupAsync(e.detail.scope); if (pagination) {
}); var pageLinks = Array.from(pagination.querySelectorAll('.page-link'));
pageLinks.forEach(function(p) {
p.removeEventListener('click', clickHandler);
});
}
if (pagesizeForm) {
var pagesizeSelect = pagesizeForm.querySelector('[name=' + tableIdent + '-pagesize]')
pagesizeSelect.removeEventListener('change', changeHandler);
}
}
function clickHandler(event) {
event.preventDefault();
var url = new URL(window.location.origin + window.location.pathname + getClickDestination(this));
updateTableFrom(url);
}
function getClickDestination(el) {
if (!el.querySelector('a')) {
return '';
}
return el.querySelector('a').getAttribute('href');
}
function changeHandler(event) {
var currentTableUrl = wrapper.dataset.currentUrl || window.location.href;
var url = getUrlWithUpdatedPagesize(currentTableUrl, event.target.value);
url = getUrlWithResetPagenumber(url);
updateTableFrom(url);
}
function getUrlWithUpdatedPagesize(url, pagesize) {
if (url.indexOf('pagesize') >= 0) {
return url.replace(/pagesize=(\d+)/, 'pagesize=' + pagesize);
} else if (url.indexOf('?') >= 0) {
return url += '&' + tableIdent + '-pagesize=' + pagesize;
}
return url += '?' + tableIdent + '-pagesize=' + pagesize;
}
function getUrlWithResetPagenumber(url) {
return url.replace(/-page=\d+/, '-page=0');
}
function updateWrapperContents(newHtml) {
wrapper.innerHTML = newHtml;
wrapper.classList.remove("js-initialized");
// setup the wrapper and its components to behave async again
window.utils.asyncTable(wrapper);
// make sure to hide any new submit buttons
document.dispatchEvent(new CustomEvent('setup', {
detail: {
scope: wrapper,
module: 'autoSubmit'
}
}));
}
// fetches new sorted table from url with params and replaces contents of current table
function updateTableFrom(url) {
fetch(url, {
credentials: 'same-origin',
headers: {
'Accept': 'text/html',
[shortCircuitHeader]: tableIdent
}
}).then(function(response) {
if (!response.ok) {
throw new Error('Looks like there was a problem fetching ' + url + '. Status Code: ' + response.status);
}
return response.text();
}).then(function(data) {
wrapper.dataset.currentUrl = url;
removeListeners();
updateWrapperContents(data);
}).catch(function(err) {
console.error(err);
});
}
init();
};
})(); })();
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
document.dispatchEvent(new CustomEvent('setup', { detail: { scope: document.body, module: 'dbtable' }, bubbles: true, cancelable: true })); var selector = '#' + #{String $ dbtIdent} + '-table-wrapper:not(.js-initialized)';
var wrapper = document.querySelector(selector);
if (wrapper) {
window.utils.asyncTable(wrapper);
}
}); });

View File

@ -17,16 +17,7 @@
}; };
})(); })();
document.addEventListener('setup', function(e) {
if (e.detail.module && e.detail.module !== 'asidenav')
return;
var asidenavEl = e.detail.scope.querySelector('.main__aside');
window.utils.aside(asidenavEl);
});
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
document.dispatchEvent(new CustomEvent('setup', { detail: { scope: document.body, module: 'asidenav' }, bubbles: true, cancelable: true })) var asidenavEl = document.querySelector('.main__aside');
window.utils.aside(asidenavEl);
}); });

View File

@ -55,8 +55,6 @@
function addEventListeners() { function addEventListeners() {
fields.forEach(function(field) { fields.forEach(function(field) {
console.log('interactiveFieldset', 'addEventListeners', field);
field.condEl.addEventListener('input', updateFields) field.condEl.addEventListener('input', updateFields)
}); });
} }
@ -72,8 +70,6 @@ document.addEventListener('setup', function(e) {
if (e.detail.module && e.detail.module !== 'showHide') if (e.detail.module && e.detail.module !== 'showHide')
return; return;
console.log('form setup', e.detail.scope);
var forms = e.detail.scope.querySelectorAll('form'); var forms = e.detail.scope.querySelectorAll('form');
Array.from(forms).forEach(function(form) { Array.from(forms).forEach(function(form) {
// auto reactiveButton submit-buttons with required fields // auto reactiveButton submit-buttons with required fields
@ -114,8 +110,6 @@ document.addEventListener('setup', function(e) {
var target = ancestor || elem; var target = ancestor || elem;
target.classList.add('hidden'); target.classList.add('hidden');
} else if (elem.form) {
elem.addEventListener('change', function () { elem.form.submit() })
} }
elem.classList.add('js-initialized'); elem.classList.add('js-initialized');