Files
pulse-signage/src/web/public/js/table/table-search.js
T
lzstealth 98f969ca0f
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile, web, pulse-signage-web) (push) Successful in 1m47s
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile.player, player, pulse-signage-player) (push) Successful in 31s
Release v2.11.1
2026-09-04 15:43:55 +01:00

254 lines
8.5 KiB
JavaScript

(function () {
var minimumPaginationCardHeight = 20 * 16;
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);
}
syncTablePaginationCards(container);
syncTablePaginationPageClass();
}
function syncTablePaginationCards(root) {
if (!root || !root.querySelectorAll) {
return;
}
Array.prototype.forEach.call(root.querySelectorAll('[data-table-pagination-card]'), function (card) {
if (!card || !card.getBoundingClientRect) {
return;
}
var cardRect = card.getBoundingClientRect();
var bottomInset = 16;
var availableHeight = Math.max(0, window.innerHeight - cardRect.top - bottomInset);
var contentHeight = Math.max(0, card.scrollHeight || 0);
var shouldApplyMinimum = contentHeight > minimumPaginationCardHeight;
var cardHeight = Math.max(minimumPaginationCardHeight, availableHeight);
if (shouldApplyMinimum) {
card.style.setProperty('--table-pagination-card-min-height', minimumPaginationCardHeight + 'px');
} else {
card.style.removeProperty('--table-pagination-card-min-height');
}
card.style.removeProperty('--table-pagination-card-height');
card.style.setProperty('--table-pagination-card-max-height', cardHeight + 'px');
});
}
function syncTablePaginationPageClass() {
if (!document || !document.body || !document.body.classList) {
return;
}
document.body.classList.toggle('table-pagination-page', !!document.querySelector('[data-table-pagination-card]'));
}
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 pendingSearchRequests = 0;
var container = input.closest('[data-table-search-container]') || input.closest('.card') || null;
input.value = String(currentUrl.searchParams.get(searchParam) || '').trim();
var searchGroup = input.closest('.table-search-group');
if (searchGroup) {
var actionButton = searchGroup.parentNode ? searchGroup.parentNode.querySelector('.btn:not(.table-search-group .btn)') : null;
if (actionButton && actionButton.getBoundingClientRect) {
searchGroup.style.setProperty('--table-search-action-offset', (actionButton.getBoundingClientRect().width + 8) + 'px');
}
var searchToggle = searchGroup.querySelector('[data-table-search-toggle]');
if (searchToggle) {
searchToggle.addEventListener('click', function () {
focusSearchInput(input);
});
searchToggle.addEventListener('keydown', function (event) {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
focusSearchInput(input);
}
});
}
}
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;
pendingSearchRequests += 1;
if (container) {
container.setAttribute('data-table-search-loading', 'true');
}
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());
}).finally(function () {
pendingSearchRequests = Math.max(0, pendingSearchRequests - 1);
if (container && pendingSearchRequests === 0) {
container.removeAttribute('data-table-search-loading');
}
});
}
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();
}
});
});
syncTablePaginationCards(scope);
}
if (window.addEventListener) {
window.addEventListener('resize', function () {
syncTablePaginationCards(document);
});
window.addEventListener('orientationchange', function () {
syncTablePaginationCards(document);
});
}
window.initTableSearches = initTableSearches;
window.replaceTableResults = replaceTableResults;
syncTablePaginationCards(document);
syncTablePaginationPageClass();
}());