232 lines
7.1 KiB
JavaScript
232 lines
7.1 KiB
JavaScript
(function collonadeClosure() {
|
|
'use strict';
|
|
|
|
window.utils = window.utils || {};
|
|
|
|
var HEADER_HEIGHT = 80;
|
|
var RESET_OPTIONS = [ 'scrollTo' ];
|
|
var TABLE_FILTER_FORM_CLASS = 'table-filter-form';
|
|
var ASYNC_TABLE_CONTENT_CHANGED_CLASS = 'async-table--changed';
|
|
var ASYNC_TABLE_LOADING_CLASS = 'async-table--loading';
|
|
var JS_INITIALIZED_CLASS = 'js-async-table-initialized';
|
|
|
|
window.utils.asyncTable = function(wrapper, options) {
|
|
|
|
options = options || {};
|
|
var tableIdent = options.dbtIdent;
|
|
var shortCircuitHeader = options ? options.headerDBTableShortcircuit : null;
|
|
|
|
var ths = [];
|
|
var pageLinks = [];
|
|
var pagesizeForm;
|
|
var scrollTable;
|
|
|
|
var utilInstances = [];
|
|
|
|
function init() {
|
|
var table = wrapper.querySelector('#' + tableIdent);
|
|
|
|
if (!table) {
|
|
return;
|
|
}
|
|
|
|
scrollTable = wrapper.querySelector('.scrolltable');
|
|
|
|
// 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');
|
|
|
|
// check all
|
|
utilInstances.push(window.utils.setup('checkAll', wrapper));
|
|
|
|
// showhide
|
|
utilInstances.push(window.utils.setup('showHide', wrapper));
|
|
|
|
// filter
|
|
var filterForm = wrapper.querySelector('.' + TABLE_FILTER_FORM_CLASS);
|
|
if (filterForm) {
|
|
options.updateTableFrom = updateTableFrom;
|
|
utilInstances.push(window.utils.setup('asyncTableFilter', filterForm, options));
|
|
}
|
|
|
|
// take options into account
|
|
if (options.scrollTo) {
|
|
window.scrollTo(options.scrollTo);
|
|
}
|
|
|
|
if (options.horizPos && scrollTable) {
|
|
scrollTable.scrollLeft = options.horizPos;
|
|
}
|
|
|
|
setupListeners();
|
|
wrapper.classList.add(JS_INITIALIZED_CLASS);
|
|
}
|
|
|
|
function setupListeners() {
|
|
ths.forEach(function(th) {
|
|
th.clickHandler = function(event) {
|
|
var boundClickHandler = clickHandler.bind(this);
|
|
var horizPos = (scrollTable || {}).scrollLeft;
|
|
boundClickHandler(event, { horizPos });
|
|
};
|
|
th.element.addEventListener('click', th.clickHandler);
|
|
});
|
|
|
|
pageLinks.forEach(function(link) {
|
|
link.clickHandler = function(event) {
|
|
var boundClickHandler = clickHandler.bind(this);
|
|
var tableBoundingRect = scrollTable.getBoundingClientRect();
|
|
var tableOptions = {};
|
|
if (tableBoundingRect.top < HEADER_HEIGHT) {
|
|
tableOptions.scrollTo = {
|
|
top: (scrollTable.offsetTop || 0) - HEADER_HEIGHT,
|
|
left: scrollTable.offsetLeft || 0,
|
|
behavior: 'smooth',
|
|
};
|
|
}
|
|
boundClickHandler(event, tableOptions);
|
|
}
|
|
link.element.addEventListener('click', link.clickHandler);
|
|
});
|
|
|
|
if (pagesizeForm) {
|
|
var pagesizeSelect = pagesizeForm.querySelector('[name=' + tableIdent + '-pagesize]');
|
|
pagesizeSelect.addEventListener('change', changePagesizeHandler);
|
|
}
|
|
}
|
|
|
|
function removeListeners() {
|
|
ths.forEach(function(th) {
|
|
th.element.removeEventListener('click', th.clickHandler);
|
|
});
|
|
|
|
pageLinks.forEach(function(link) {
|
|
link.element.removeEventListener('click', link.clickHandler);
|
|
});
|
|
|
|
if (pagesizeForm) {
|
|
var pagesizeSelect = pagesizeForm.querySelector('[name=' + tableIdent + '-pagesize]')
|
|
pagesizeSelect.removeEventListener('change', changePagesizeHandler);
|
|
}
|
|
}
|
|
|
|
function clickHandler(event, tableOptions) {
|
|
event.preventDefault();
|
|
var url = new URL(window.location.origin + window.location.pathname + getClickDestination(this));
|
|
updateTableFrom(url, tableOptions);
|
|
}
|
|
|
|
function getClickDestination(el) {
|
|
if (!el.querySelector('a')) {
|
|
return '';
|
|
}
|
|
return el.querySelector('a').getAttribute('href');
|
|
}
|
|
|
|
function changePagesizeHandler(event) {
|
|
var pagesizeParamKey = tableIdent + '-pagesize';
|
|
var pageParamKey = tableIdent + '-page';
|
|
var url = new URL(options.currentUrl || window.location.href);
|
|
url.searchParams.set(pagesizeParamKey, event.target.value);
|
|
url.searchParams.set(pageParamKey, 0);
|
|
updateTableFrom(url);
|
|
}
|
|
|
|
// fetches new sorted table from url with params and replaces contents of current table
|
|
function updateTableFrom(url, tableOptions, callback) {
|
|
if (!window.utils.httpClient) {
|
|
throw new Error('httpClient not found!');
|
|
}
|
|
|
|
wrapper.classList.add(ASYNC_TABLE_LOADING_CLASS);
|
|
|
|
tableOptions = tableOptions || {};
|
|
var headers = {
|
|
'Accept': 'text/html',
|
|
[shortCircuitHeader]: tableIdent
|
|
};
|
|
window.utils.httpClient.get(url, headers).then(function(response) {
|
|
if (!response.ok) {
|
|
throw new Error('Looks like there was a problem fetching ' + url.href + '. Status Code: ' + response.status);
|
|
}
|
|
return response.text();
|
|
}).then(function(data) {
|
|
tableOptions.currentUrl = url.href;
|
|
removeListeners();
|
|
updateWrapperContents(data, tableOptions);
|
|
if (callback && typeof callback === 'function') {
|
|
callback(wrapper);
|
|
}
|
|
|
|
wrapper.classList.remove(ASYNC_TABLE_LOADING_CLASS);
|
|
}).catch(function(err) {
|
|
console.error(err);
|
|
});
|
|
}
|
|
|
|
function updateWrapperContents(newHtml, tableOptions) {
|
|
tableOptions = tableOptions || {};
|
|
wrapper.innerHTML = newHtml;
|
|
wrapper.classList.remove(JS_INITIALIZED_CLASS);
|
|
wrapper.classList.add(ASYNC_TABLE_CONTENT_CHANGED_CLASS);
|
|
|
|
destroyUtils();
|
|
|
|
// merge global options and table specific options
|
|
var resetOptions = {};
|
|
Object.keys(options)
|
|
.filter(function(key) {
|
|
return !RESET_OPTIONS.includes(key);
|
|
})
|
|
.forEach(function(key) {
|
|
resetOptions[key] = options[key];
|
|
});
|
|
var combinedOptions = {};
|
|
combinedOptions = Object.keys(tableOptions)
|
|
.filter(function(key) {
|
|
return tableOptions.hasOwnProperty(key);
|
|
})
|
|
.map(function(key) {
|
|
return { key, value: tableOptions[key] }
|
|
})
|
|
.reduce(function(cumulatedOpts, opt) {
|
|
cumulatedOpts[opt.key] = opt.value;
|
|
return cumulatedOpts;
|
|
}, resetOptions);
|
|
|
|
window.utils.setup('asyncTable', wrapper, combinedOptions);
|
|
|
|
Array.from(wrapper.querySelectorAll('form')).forEach(function(form) {
|
|
utilInstances.push(window.utils.setup('form', form));
|
|
});
|
|
Array.from(wrapper.querySelectorAll('.modal')).forEach(function(modal) {
|
|
utilInstances.push(window.utils.setup('modal', modal));
|
|
});
|
|
}
|
|
|
|
function destroyUtils() {
|
|
utilInstances.forEach(function(utilInstance) {
|
|
utilInstance.destroy();
|
|
});
|
|
}
|
|
|
|
init();
|
|
|
|
return {
|
|
destroy: destroyUtils,
|
|
};
|
|
};
|
|
})();
|