Release 1.5.13
This commit is contained in:
@@ -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;
|
||||
}());
|
||||
Reference in New Issue
Block a user