Fix live search on Partner Dashboard clients
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
(() => {
|
||||
"use strict";
|
||||
|
||||
const ROOT_SELECTOR = "[data-partner-client-list]";
|
||||
|
||||
function initialiseRoot(root) {
|
||||
if (!(root instanceof Element) || root.dataset.liveFilterReady === "1") {
|
||||
return;
|
||||
}
|
||||
|
||||
const search = root.querySelector("[data-client-search]");
|
||||
const status = root.querySelector("[data-client-status]");
|
||||
const clear = root.querySelector("[data-client-clear]");
|
||||
const scroll = root.querySelector("[data-client-scroll]");
|
||||
const count = root.querySelector("[data-visible-count]");
|
||||
const empty = root.querySelector("[data-no-results]");
|
||||
const rows = Array.from(root.querySelectorAll("[data-client-row]"));
|
||||
|
||||
if (!search || !status || !clear || !count) {
|
||||
return;
|
||||
}
|
||||
|
||||
root.dataset.liveFilterReady = "1";
|
||||
let debounceTimer = null;
|
||||
|
||||
function applyFilter() {
|
||||
const term = String(search.value || "").trim().toLocaleLowerCase();
|
||||
const wantedStatus = String(status.value || "").trim().toLocaleLowerCase();
|
||||
let visible = 0;
|
||||
|
||||
rows.forEach((row) => {
|
||||
const searchable = String(row.dataset.search || "").toLocaleLowerCase();
|
||||
const rowStatus = String(row.dataset.status || "").toLocaleLowerCase();
|
||||
const matchesText = !term || searchable.includes(term);
|
||||
const matchesStatus = !wantedStatus || rowStatus === wantedStatus;
|
||||
const shouldShow = matchesText && matchesStatus;
|
||||
|
||||
row.hidden = !shouldShow;
|
||||
if (shouldShow) {
|
||||
visible += 1;
|
||||
}
|
||||
});
|
||||
|
||||
count.textContent = `${visible} ${visible === 1 ? "client" : "clients"}`;
|
||||
|
||||
if (empty) {
|
||||
empty.hidden = visible !== 0;
|
||||
}
|
||||
|
||||
if (scroll) {
|
||||
scroll.scrollTop = 0;
|
||||
}
|
||||
}
|
||||
|
||||
search.addEventListener("input", () => {
|
||||
window.clearTimeout(debounceTimer);
|
||||
debounceTimer = window.setTimeout(applyFilter, 200);
|
||||
});
|
||||
|
||||
status.addEventListener("change", applyFilter);
|
||||
|
||||
clear.addEventListener("click", () => {
|
||||
window.clearTimeout(debounceTimer);
|
||||
search.value = "";
|
||||
status.value = "active";
|
||||
applyFilter();
|
||||
search.focus();
|
||||
});
|
||||
|
||||
applyFilter();
|
||||
}
|
||||
|
||||
function initialiseWithin(scope = document) {
|
||||
if (scope instanceof Element && scope.matches(ROOT_SELECTOR)) {
|
||||
initialiseRoot(scope);
|
||||
}
|
||||
|
||||
if (typeof scope.querySelectorAll === "function") {
|
||||
scope.querySelectorAll(ROOT_SELECTOR).forEach(initialiseRoot);
|
||||
}
|
||||
}
|
||||
|
||||
function start() {
|
||||
initialiseWithin(document);
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
mutation.addedNodes.forEach((node) => {
|
||||
if (node instanceof Element) {
|
||||
initialiseWithin(node);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(document.documentElement, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", start, { once: true });
|
||||
} else {
|
||||
start();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user