Release 1.5.13

This commit is contained in:
2026-07-26 20:26:01 +01:00
parent 4afaeaafb1
commit 815c808d73
59 changed files with 1418 additions and 3042 deletions
+170
View File
@@ -0,0 +1,170 @@
(function () {
function rebindTableContainer(container) {
if (!container) {
return;
}
if (typeof window.initSortableTables === 'function') {
window.initSortableTables(container);
}
if (typeof window.initTableSearches === 'function') {
window.initTableSearches(container);
}
if (typeof window.initLocalDateTimes === 'function') {
window.initLocalDateTimes(container);
}
}
function focusSearchInput(input) {
if (!input || !input.focus) {
return;
}
input.focus();
if (typeof input.setSelectionRange === 'function') {
var valueLength = String(input.value || '').length;
try {
input.setSelectionRange(valueLength, valueLength);
} catch (_error) {
// Ignore selection failures on unsupported input types.
}
}
}
function replaceTableResults(container, responseDocument) {
if (!container || !responseDocument || !responseDocument.querySelector) {
return false;
}
var currentTable = container.querySelector('[data-table-searchable]');
var nextContainer = responseDocument.querySelector('[data-table-search-container]') || responseDocument.querySelector('.card');
var nextTable = nextContainer ? nextContainer.querySelector('[data-table-searchable]') : null;
var currentFooter = container.querySelector('.card-footer');
var nextFooter = nextContainer ? nextContainer.querySelector('.card-footer') : null;
if (!currentTable || !nextTable) {
return false;
}
var currentBody = currentTable.tBodies && currentTable.tBodies[0] ? currentTable.tBodies[0] : null;
var nextBody = nextTable.tBodies && nextTable.tBodies[0] ? nextTable.tBodies[0] : null;
if (!currentBody || !nextBody) {
return false;
}
currentBody.outerHTML = nextBody.outerHTML;
if (currentFooter && nextFooter) {
currentFooter.outerHTML = nextFooter.outerHTML;
} else if (currentFooter && !nextFooter) {
currentFooter.parentNode.removeChild(currentFooter);
} else if (!currentFooter && nextFooter) {
currentTable.parentNode.appendChild(nextFooter.cloneNode(true));
}
return true;
}
function initTableSearches(root) {
var scope = root && root.querySelectorAll ? root : document;
Array.prototype.forEach.call(scope.querySelectorAll('[data-table-search]'), function (input) {
if (input.getAttribute('data-table-search-bound') === 'true') {
return;
}
input.setAttribute('data-table-search-bound', 'true');
var searchParam = String(input.getAttribute('data-table-search-param') || 'search').trim() || 'search';
var currentUrl = new URL(window.location.href);
var pendingSearchTimer = null;
var requestSequence = 0;
var container = input.closest('[data-table-search-container]') || input.closest('.card') || null;
input.value = String(currentUrl.searchParams.get(searchParam) || '').trim();
function updateSearch() {
var query = String(input.value || '').trim();
var nextUrl = new URL(window.location.href);
if (query) {
nextUrl.searchParams.set(searchParam, query);
} else {
nextUrl.searchParams.delete(searchParam);
}
nextUrl.searchParams.delete('page');
if (nextUrl.toString() === currentUrl.toString()) {
return;
}
requestSequence += 1;
var sequenceId = requestSequence;
fetch(nextUrl.toString(), {
method: 'GET',
headers: {
'Accept': 'text/html, application/xhtml+xml',
'X-Requested-With': 'XMLHttpRequest'
},
credentials: 'same-origin',
cache: 'no-store'
}).then(function (response) {
if (!response.ok) {
throw new Error('Unable to load search results.');
}
return response.text();
}).then(function (text) {
if (sequenceId !== requestSequence) {
return;
}
var responseDocument = new DOMParser().parseFromString(text || '', 'text/html');
if (window.history && window.history.replaceState) {
window.history.replaceState({}, document.title, nextUrl.pathname + nextUrl.search + nextUrl.hash);
}
if (replaceTableResults(container, responseDocument)) {
currentUrl = nextUrl;
rebindTableContainer(container || document);
focusSearchInput(input);
}
}).catch(function () {
window.location.assign(nextUrl.toString());
});
}
function scheduleSearchUpdate() {
if (pendingSearchTimer) {
window.clearTimeout(pendingSearchTimer);
}
pendingSearchTimer = window.setTimeout(function () {
pendingSearchTimer = null;
updateSearch();
}, 300);
}
input.addEventListener('input', scheduleSearchUpdate);
input.addEventListener('search', scheduleSearchUpdate);
input.addEventListener('change', updateSearch);
input.addEventListener('keydown', function (event) {
if (event.key === 'Enter') {
event.preventDefault();
if (pendingSearchTimer) {
window.clearTimeout(pendingSearchTimer);
pendingSearchTimer = null;
}
updateSearch();
}
});
});
}
window.initTableSearches = initTableSearches;
window.replaceTableResults = replaceTableResults;
}());