MediaWiki:Datatables.js: Difference between revisions
From PC Gaming Shelter
No edit summary |
No edit summary |
||
| Line 1: | Line 1: | ||
var selectors = [ | var selectors = [ | ||
"#games > table" | |||
]; | ]; | ||
var found = false; | var found = false; | ||
for (var i = 0; i < selectors.length; i++) { | for (var i = 0; i < selectors.length; i++) { | ||
if (document.querySelector(selectors[i])) { | |||
found = true; | |||
break; | |||
} | |||
} | } | ||
| Line 14: | Line 14: | ||
if (found === true) { | if (found === true) { | ||
/* Load CSS. */ | |||
const dtsource = | |||
"https://cdn.datatables.net/v/dt/moment-2.29.4/dt-2.3.7/b-3.2.6/b-colvis-3.2.6/b-html5-3.2.6/b-print-3.2.6/cc-1.2.0/date-1.6.3/fh-4.0.5/r-3.0.8/sc-2.4.3/sb-1.8.4/sp-2.3.5/sl-3.1.3/sr-1.4.3/datatables.min.css"; | |||
if (!document.querySelector('link[href*="datatables.min.css"]')) { | |||
$("<link/>", { rel: "stylesheet", href: dtsource }).appendTo("head"); | |||
} | |||
if (!document.querySelector("#datatable-styles")) { | |||
$("<style/>", { | |||
id: "datatable-styles", | |||
text: ` | |||
table.dataTable > tbody > tr > td { | table.dataTable > tbody > tr > td { | ||
padding-top: 0.25rem; | padding-top: 0.25rem; | ||
| Line 78: | Line 78: | ||
.dtsp-paneButton.clearButton:not(:disabled) { | .dtsp-paneButton.clearButton:not(:disabled) { | ||
color: var(--bs-danger, #dc3545); | color: var(--bs-danger, #dc3545); | ||
} | |||
.dt-filter-toggle { | |||
align-items: center; | |||
background: var(--bs-primary, #0d6efd); | |||
border: 0; | |||
border-radius: 0.375rem; | |||
color: #fff; | |||
display: inline-flex; | |||
font-weight: 600; | |||
gap: 0.375rem; | |||
line-height: 1.25; | |||
margin-bottom: 0.75rem; | |||
padding: 0.5rem 0.75rem; | |||
} | |||
.dt-filter-toggle:focus { | |||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); | |||
outline: 0; | |||
} | |||
.dt-filter-toggle::before { | |||
content: "\\2630"; | |||
font-size: 1rem; | |||
line-height: 1; | |||
} | |||
.dt-filter-backdrop { | |||
background: rgba(0, 0, 0, 0.35); | |||
inset: 0; | |||
opacity: 0; | |||
pointer-events: none; | |||
position: fixed; | |||
transition: opacity 180ms ease; | |||
z-index: 1040; | |||
} | |||
.dt-filter-backdrop.is-open { | |||
opacity: 1; | |||
pointer-events: auto; | |||
} | |||
.dt-filter-panel { | |||
background: var(--bs-body-bg, #fff); | |||
box-shadow: 0.5rem 0 1.5rem rgba(0, 0, 0, 0.18); | |||
display: flex; | |||
flex-direction: column; | |||
height: 100vh; | |||
left: 0; | |||
max-width: min(92vw, 24rem); | |||
overflow: hidden; | |||
position: fixed; | |||
top: 0; | |||
transform: translateX(-100%); | |||
transition: transform 220ms ease; | |||
width: 24rem; | |||
z-index: 1050; | |||
} | |||
.dt-filter-panel.is-open { | |||
transform: translateX(0); | |||
} | |||
.dt-filter-panel__header { | |||
align-items: center; | |||
border-bottom: 1px solid var(--bs-border-color, #dee2e6); | |||
display: flex; | |||
flex: 0 0 auto; | |||
justify-content: space-between; | |||
padding: 0.75rem 1rem; | |||
} | |||
.dt-filter-panel__title { | |||
font-size: 1rem; | |||
font-weight: 600; | |||
margin: 0; | |||
} | |||
.dt-filter-panel__close { | |||
background: transparent; | |||
border: 0; | |||
color: inherit; | |||
font-size: 1.75rem; | |||
line-height: 1; | |||
padding: 0.125rem 0.375rem; | |||
} | |||
.dt-filter-panel__body { | |||
flex: 1 1 auto; | |||
overflow: auto; | |||
padding: 0.75rem; | |||
} | |||
.dt-filter-panel__body .dtsp-panesContainer { | |||
margin: 0 !important; | |||
} | |||
.dt-filter-panel__body .dtsp-searchPanes { | |||
display: block !important; | |||
} | |||
.dt-filter-panel__body .dtsp-searchPane { | |||
margin-bottom: 0.75rem !important; | |||
width: 100% !important; | |||
} | |||
body.dt-filter-panel-open { | |||
overflow: hidden; | |||
} | } | ||
`, | `, | ||
}).appendTo("head"); | |||
} | |||
$("#games > table").addClass("dt-loading").attr("aria-busy", "true"); | |||
/* Load JavaScript. */ | |||
$.when( | |||
mw.loader.getScript( | |||
"https://cdn.datatables.net/v/dt/moment-2.29.4/dt-2.3.7/b-3.2.6/b-colvis-3.2.6/b-html5-3.2.6/b-print-3.2.6/cc-1.2.0/date-1.6.3/fh-4.0.5/r-3.0.8/sc-2.4.3/sb-1.8.4/sp-2.3.5/sl-3.1.3/sr-1.4.3/datatables.min.js", | |||
), | |||
).then( | |||
() => { | |||
window.datatablesLoaded = true; | |||
initDataTable(); | |||
}, | |||
(e) => mw.log.error(e.message), | |||
); | |||
} | } | ||
| Line 102: | Line 210: | ||
function initDataTable() { | function initDataTable() { | ||
function getDataTableColumnCount(table) { | |||
var headerRow = | |||
table.tHead && table.tHead.rows.length | |||
? table.tHead.rows[table.tHead.rows.length - 1] | |||
: | : null; | ||
if (headerRow) { | |||
return headerRow.cells.length; | |||
} | |||
return table.rows.length ? table.rows[0].cells.length : 0; | |||
} | |||
if ( | function normaliseDataTableRows(table, expectedColumnCount) { | ||
$("tbody tr", table).each(function () { | |||
var row = this; | |||
var cellCount = row.cells.length; | |||
if (cellCount === 1 && row.cells[0].colSpan > 1) { | |||
return; | |||
} | |||
while (cellCount < expectedColumnCount) { | |||
row.appendChild(document.createElement("td")); | |||
cellCount++; | |||
} | |||
}); | |||
} | } | ||
function waitForTableToSettle(table, callback) { | |||
var settleTimer; | |||
var timeoutTimer; | |||
var observer; | |||
var settled = false; | |||
function finish() { | |||
if (settled) return; | |||
settled = true; | |||
clearTimeout(settleTimer); | |||
clearTimeout(timeoutTimer); | |||
if (observer) { | |||
observer.disconnect(); | |||
} | |||
callback(); | |||
} | |||
function scheduleFinish() { | |||
clearTimeout(settleTimer); | |||
settleTimer = setTimeout(finish, 500); | |||
} | |||
if (window.MutationObserver) { | |||
observer = new MutationObserver(scheduleFinish); | |||
observer.observe(table.tBodies[0] || table, { | |||
childList: true, | |||
subtree: true, | |||
}); | |||
} | |||
timeoutTimer = setTimeout(finish, 30000); | |||
scheduleFinish(); | |||
} | |||
function getAcceptsValues(html) { | |||
return (html || "") | |||
.split(/<br\s*\/?>/i) | |||
.map((value) => value.trim()) | |||
.filter(Boolean); | |||
} | } | ||
function | function getTableData(table, columnCount) { | ||
return Array.from(table.tBodies[0] ? table.tBodies[0].rows : []) | |||
.filter((row) => !(row.cells.length === 1 && row.cells[0].colSpan > 1)) | |||
.map((row) => { | |||
var data = Array.from(row.cells, (cell) => cell.innerHTML.trim()); | |||
while (data.length < columnCount) { | |||
data.push(""); | |||
} | |||
return data.slice(0, columnCount); | |||
}); | |||
} | } | ||
function buildTableLayout(table, titles) { | |||
var headerRow = document.createElement("tr"); | |||
var tableHead = document.createElement("thead"); | |||
titles.forEach((title) => { | |||
var headerCell = document.createElement("th"); | |||
headerCell.textContent = title; | |||
headerRow.appendChild(headerCell); | |||
}); | |||
table.replaceChildren(tableHead, document.createElement("tbody")); | |||
tableHead.appendChild(headerRow); | |||
} | } | ||
function suppressSearchPaneBorders(container) { | |||
if (!container) { | |||
return; | |||
} | |||
function removeBorderClass() { | |||
container.querySelectorAll(".dtsp-bordered").forEach(function (element) { | |||
element.classList.remove("dtsp-bordered"); | |||
}); | |||
} | |||
removeBorderClass(); | |||
new MutationObserver(removeBorderClass).observe(container, { | |||
attributes: true, | |||
attributeFilter: ["class"], | |||
childList: true, | |||
subtree: true, | |||
}); | |||
} | |||
function openFellowshipLinksInNewTab(dataTable) { | |||
dataTable | |||
.column(0) | |||
.nodes() | |||
.toArray() | |||
.forEach(function (cell) { | |||
cell.querySelectorAll("a").forEach(function (link) { | |||
link.target = "_blank"; | |||
}); | |||
}); | |||
} | |||
function setupFilterOffCanvas(dataTable, table) { | |||
var wrapper = table.closest(".dt-container") || table.parentNode; | |||
var panes = wrapper ? wrapper.querySelector(".dtsp-panesContainer") : null; | |||
var | |||
if (!wrapper || !panes || wrapper.querySelector(".dt-filter-toggle")) { | |||
return; | |||
} | } | ||
var toggle = document.createElement("button"); | |||
var panel = document.createElement("aside"); | |||
var backdrop = document.createElement("div"); | |||
var header = document.createElement("div"); | |||
var title = document.createElement("h2"); | |||
var close = document.createElement("button"); | |||
var body = document.createElement("div"); | |||
var lastFocusedElement = null; | |||
toggle.type = "button"; | |||
toggle.className = "dt-filter-toggle"; | |||
toggle.textContent = "Filters"; | |||
toggle.setAttribute("aria-controls", "dt-filter-panel"); | |||
toggle.setAttribute("aria-expanded", "false"); | |||
panel.id = "dt-filter-panel"; | |||
panel.className = "dt-filter-panel"; | |||
panel.setAttribute("aria-hidden", "true"); | |||
panel.setAttribute("aria-label", "Data filters"); | |||
backdrop.className = "dt-filter-backdrop"; | |||
header.className = "dt-filter-panel__header"; | |||
title.className = "dt-filter-panel__title"; | |||
title.textContent = "Filters"; | |||
close.type = "button"; | |||
close.className = "dt-filter-panel__close"; | |||
close.setAttribute("aria-label", "Close filters"); | |||
close.innerHTML = "×"; | |||
body.className = "dt-filter-panel__body"; | |||
header.append(title, close); | |||
body.appendChild(panes); | |||
panel.append(header, body); | |||
wrapper.insertBefore(toggle, wrapper.firstChild); | |||
document.body.append(backdrop, panel); | |||
function openPanel() { | |||
lastFocusedElement = document.activeElement; | |||
panel.classList.add("is-open"); | |||
backdrop.classList.add("is-open"); | |||
document.body.classList.add("dt-filter-panel-open"); | |||
panel.setAttribute("aria-hidden", "false"); | |||
toggle.setAttribute("aria-expanded", "true"); | |||
close.focus(); | |||
dataTable.columns.adjust(); | |||
} | |||
function closePanel() { | |||
panel.classList.remove("is-open"); | |||
backdrop.classList.remove("is-open"); | |||
document.body.classList.remove("dt-filter-panel-open"); | |||
panel.setAttribute("aria-hidden", "true"); | |||
toggle.setAttribute("aria-expanded", "false"); | |||
if (lastFocusedElement && document.contains(lastFocusedElement)) { | |||
lastFocusedElement.focus(); | |||
} | |||
dataTable.columns.adjust(); | |||
} | |||
toggle.addEventListener("click", openPanel); | |||
close.addEventListener("click", closePanel); | |||
backdrop.addEventListener("click", closePanel); | |||
document.addEventListener("keydown", function (event) { | |||
if (event.key === "Escape" && panel.classList.contains("is-open")) { | |||
closePanel(); | |||
} | |||
}); | }); | ||
} | |||
$(".dataTable") | |||
.each(function () { | |||
var table = this; | |||
waitForTableToSettle(table, function () { | |||
if ($.fn.dataTable.isDataTable(table)) { | |||
return; | |||
} | |||
normaliseDataTableRows(table, getDataTableColumnCount(table)); | |||
$(table).DataTable({ | |||
dom: "f", | |||
retrieve: true, | |||
order: [[0, "asc"]], | |||
pageLength: 1000, | |||
}); | |||
}); | |||
}); | }); | ||
// ----- GAMES ------ | // ----- GAMES ------ | ||
$("#games > table").each(function () { | $("#games > table").each(function () { | ||
var table = this; | |||
waitForTableToSettle(table, function () { | |||
if ($.fn.dataTable.isDataTable(table)) { | |||
return; | |||
} | |||
var titles = [ | |||
"Game", "Developer", "Publisher", "Genre", "Platform", "Mode", "Released" | |||
]; | |||
var data = getTableData(table, titles.length); | |||
buildTableLayout(table, titles); | |||
var dataTable = new DataTable(table, { | |||
columns: [ | |||
{ | |||
title: "Game", | |||
render: function (data, type) { | |||
if (type === "display") { | |||
return ( | |||
'<span style="display: list-item; margin-left: 1.25rem; white-space: nowrap">' + | |||
data + | |||
"</span>" | |||
); | |||
} | |||
return data; | |||
}, | |||
searchPanes: { | |||
show: false, | |||
}, | |||
}, | |||
{ | |||
title: "Developer", | |||
visible: true, | |||
searchPanes: { | |||
show: true, | |||
}, | |||
}, | |||
{ | |||
title: "Publisher", | |||
visible: true, | |||
searchPanes: { | |||
show: true, | |||
}, | |||
}, | |||
{ | |||
title: "Genre", | |||
visible: true, | |||
searchPanes: { | |||
show: true, | |||
}, | |||
}, | |||
{ | |||
title: "Platform", | |||
visible: true, | |||
searchPanes: { | |||
show: true, | |||
}, | |||
}, | |||
{ | |||
title: "Mode", | |||
visible: true, | |||
render: { | |||
display: function (data) { | |||
return data; | |||
}, | |||
sp: function (data) { | |||
return getAcceptsValues(data); | |||
}, | |||
}, | |||
searchPanes: { | |||
show: true, | |||
orthogonal: "sp", | |||
}, | |||
}, | |||
{ | |||
title: "Released", | |||
visible: true, | |||
searchPanes: { | |||
show: true, | |||
}, | |||
}, | |||
], | |||
layout: { | |||
topStart: null, | |||
topEnd: null, | |||
top2: { | |||
searchPanes: { | |||
cascadePanes: true, | |||
initCollapsed: true, | |||
columns: [1, 2, 3, 4, 5], | |||
}, | |||
}, | |||
top1: { | |||
search: { | |||
className: "mx-0 w-100", | |||
}, | |||
}, | |||
}, | |||
order: [[0, "asc"]], | |||
paging: false, | |||
searchDelay: 400, | |||
}); | |||
var lastGlobalSearch = dataTable.search(); | |||
var paneIndexes = [1, 2, 3, 4, 5]; | |||
dataTable.on("draw.dt", function () { | |||
var globalSearch = dataTable.search(); | |||
openFellowshipLinksInNewTab(dataTable); | |||
if (globalSearch === lastGlobalSearch) { | |||
return; | |||
} | |||
lastGlobalSearch = globalSearch; | |||
paneIndexes.forEach(function (paneIndex) { | |||
dataTable.searchPanes.rebuildPane(paneIndex, true); | |||
}); | |||
}); | |||
dataTable.rows.add(data).draw(); | |||
$(".dataTable") | |||
.removeClass("dt-loading") | |||
.removeAttr("aria-busy") | |||
.show(); | |||
dataTable.searchPanes.rebuildPane(); | |||
setupFilterOffCanvas(dataTable, table); | |||
suppressSearchPaneBorders(document.querySelector(".dt-filter-panel")); | |||
dataTable.columns.adjust().draw(false); | |||
}); | }); | ||
}); | }); | ||
} | } | ||
Revision as of 09:27, 17 June 2026
var selectors = [
"#games > table"
];
var found = false;
for (var i = 0; i < selectors.length; i++) {
if (document.querySelector(selectors[i])) {
found = true;
break;
}
}
/* ------------- DataTables Loader and initialisation ---------------- */
if (found === true) {
/* Load CSS. */
const dtsource =
"https://cdn.datatables.net/v/dt/moment-2.29.4/dt-2.3.7/b-3.2.6/b-colvis-3.2.6/b-html5-3.2.6/b-print-3.2.6/cc-1.2.0/date-1.6.3/fh-4.0.5/r-3.0.8/sc-2.4.3/sb-1.8.4/sp-2.3.5/sl-3.1.3/sr-1.4.3/datatables.min.css";
if (!document.querySelector('link[href*="datatables.min.css"]')) {
$("<link/>", { rel: "stylesheet", href: dtsource }).appendTo("head");
}
if (!document.querySelector("#datatable-styles")) {
$("<style/>", {
id: "datatable-styles",
text: `
table.dataTable > tbody > tr > td {
padding-top: 0.25rem;
padding-bottom: 0.25rem;
}
.dt-loading {
display: block !important;
min-height: 4rem;
position: relative;
}
.dt-loading > * {
display: none !important;
}
.dt-loading::before {
animation: dt-loading 0.8s linear infinite;
border: 0.25rem solid #dee2e6;
border-radius: 50%;
border-top-color: #6c757d;
content: "";
height: 2rem;
left: calc(50% - 1rem);
position: absolute;
top: 1rem;
width: 2rem;
}
@keyframes dt-loading {
to {
transform: rotate(360deg);
}
}
.dtsp-bordered, .dtsp-bordered:hover,
.dtsp-searchPane, .dtsp-searchPane:hover {
border: 0 !important;
}
.dtsp-topRow button:hover, .dtsp-topRow input:hover,
.dtsp-topRow button:focus, .dtsp-topRow input:focus,
.dtsp-topRow button, .dtsp-topRow input {
margin: 0 !important;
}
.dtsp-paneButton.clearButton {
font-size: 1.5rem;
line-height: 1;
}
.dtsp-paneButton.clearButton:not(:disabled) {
color: var(--bs-danger, #dc3545);
}
.dt-filter-toggle {
align-items: center;
background: var(--bs-primary, #0d6efd);
border: 0;
border-radius: 0.375rem;
color: #fff;
display: inline-flex;
font-weight: 600;
gap: 0.375rem;
line-height: 1.25;
margin-bottom: 0.75rem;
padding: 0.5rem 0.75rem;
}
.dt-filter-toggle:focus {
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
outline: 0;
}
.dt-filter-toggle::before {
content: "\\2630";
font-size: 1rem;
line-height: 1;
}
.dt-filter-backdrop {
background: rgba(0, 0, 0, 0.35);
inset: 0;
opacity: 0;
pointer-events: none;
position: fixed;
transition: opacity 180ms ease;
z-index: 1040;
}
.dt-filter-backdrop.is-open {
opacity: 1;
pointer-events: auto;
}
.dt-filter-panel {
background: var(--bs-body-bg, #fff);
box-shadow: 0.5rem 0 1.5rem rgba(0, 0, 0, 0.18);
display: flex;
flex-direction: column;
height: 100vh;
left: 0;
max-width: min(92vw, 24rem);
overflow: hidden;
position: fixed;
top: 0;
transform: translateX(-100%);
transition: transform 220ms ease;
width: 24rem;
z-index: 1050;
}
.dt-filter-panel.is-open {
transform: translateX(0);
}
.dt-filter-panel__header {
align-items: center;
border-bottom: 1px solid var(--bs-border-color, #dee2e6);
display: flex;
flex: 0 0 auto;
justify-content: space-between;
padding: 0.75rem 1rem;
}
.dt-filter-panel__title {
font-size: 1rem;
font-weight: 600;
margin: 0;
}
.dt-filter-panel__close {
background: transparent;
border: 0;
color: inherit;
font-size: 1.75rem;
line-height: 1;
padding: 0.125rem 0.375rem;
}
.dt-filter-panel__body {
flex: 1 1 auto;
overflow: auto;
padding: 0.75rem;
}
.dt-filter-panel__body .dtsp-panesContainer {
margin: 0 !important;
}
.dt-filter-panel__body .dtsp-searchPanes {
display: block !important;
}
.dt-filter-panel__body .dtsp-searchPane {
margin-bottom: 0.75rem !important;
width: 100% !important;
}
body.dt-filter-panel-open {
overflow: hidden;
}
`,
}).appendTo("head");
}
$("#games > table").addClass("dt-loading").attr("aria-busy", "true");
/* Load JavaScript. */
$.when(
mw.loader.getScript(
"https://cdn.datatables.net/v/dt/moment-2.29.4/dt-2.3.7/b-3.2.6/b-colvis-3.2.6/b-html5-3.2.6/b-print-3.2.6/cc-1.2.0/date-1.6.3/fh-4.0.5/r-3.0.8/sc-2.4.3/sb-1.8.4/sp-2.3.5/sl-3.1.3/sr-1.4.3/datatables.min.js",
),
).then(
() => {
window.datatablesLoaded = true;
initDataTable();
},
(e) => mw.log.error(e.message),
);
}
/* ------------- DataTables configuration ---------------------------- */
function initDataTable() {
function getDataTableColumnCount(table) {
var headerRow =
table.tHead && table.tHead.rows.length
? table.tHead.rows[table.tHead.rows.length - 1]
: null;
if (headerRow) {
return headerRow.cells.length;
}
return table.rows.length ? table.rows[0].cells.length : 0;
}
function normaliseDataTableRows(table, expectedColumnCount) {
$("tbody tr", table).each(function () {
var row = this;
var cellCount = row.cells.length;
if (cellCount === 1 && row.cells[0].colSpan > 1) {
return;
}
while (cellCount < expectedColumnCount) {
row.appendChild(document.createElement("td"));
cellCount++;
}
});
}
function waitForTableToSettle(table, callback) {
var settleTimer;
var timeoutTimer;
var observer;
var settled = false;
function finish() {
if (settled) return;
settled = true;
clearTimeout(settleTimer);
clearTimeout(timeoutTimer);
if (observer) {
observer.disconnect();
}
callback();
}
function scheduleFinish() {
clearTimeout(settleTimer);
settleTimer = setTimeout(finish, 500);
}
if (window.MutationObserver) {
observer = new MutationObserver(scheduleFinish);
observer.observe(table.tBodies[0] || table, {
childList: true,
subtree: true,
});
}
timeoutTimer = setTimeout(finish, 30000);
scheduleFinish();
}
function getAcceptsValues(html) {
return (html || "")
.split(/<br\s*\/?>/i)
.map((value) => value.trim())
.filter(Boolean);
}
function getTableData(table, columnCount) {
return Array.from(table.tBodies[0] ? table.tBodies[0].rows : [])
.filter((row) => !(row.cells.length === 1 && row.cells[0].colSpan > 1))
.map((row) => {
var data = Array.from(row.cells, (cell) => cell.innerHTML.trim());
while (data.length < columnCount) {
data.push("");
}
return data.slice(0, columnCount);
});
}
function buildTableLayout(table, titles) {
var headerRow = document.createElement("tr");
var tableHead = document.createElement("thead");
titles.forEach((title) => {
var headerCell = document.createElement("th");
headerCell.textContent = title;
headerRow.appendChild(headerCell);
});
table.replaceChildren(tableHead, document.createElement("tbody"));
tableHead.appendChild(headerRow);
}
function suppressSearchPaneBorders(container) {
if (!container) {
return;
}
function removeBorderClass() {
container.querySelectorAll(".dtsp-bordered").forEach(function (element) {
element.classList.remove("dtsp-bordered");
});
}
removeBorderClass();
new MutationObserver(removeBorderClass).observe(container, {
attributes: true,
attributeFilter: ["class"],
childList: true,
subtree: true,
});
}
function openFellowshipLinksInNewTab(dataTable) {
dataTable
.column(0)
.nodes()
.toArray()
.forEach(function (cell) {
cell.querySelectorAll("a").forEach(function (link) {
link.target = "_blank";
});
});
}
function setupFilterOffCanvas(dataTable, table) {
var wrapper = table.closest(".dt-container") || table.parentNode;
var panes = wrapper ? wrapper.querySelector(".dtsp-panesContainer") : null;
if (!wrapper || !panes || wrapper.querySelector(".dt-filter-toggle")) {
return;
}
var toggle = document.createElement("button");
var panel = document.createElement("aside");
var backdrop = document.createElement("div");
var header = document.createElement("div");
var title = document.createElement("h2");
var close = document.createElement("button");
var body = document.createElement("div");
var lastFocusedElement = null;
toggle.type = "button";
toggle.className = "dt-filter-toggle";
toggle.textContent = "Filters";
toggle.setAttribute("aria-controls", "dt-filter-panel");
toggle.setAttribute("aria-expanded", "false");
panel.id = "dt-filter-panel";
panel.className = "dt-filter-panel";
panel.setAttribute("aria-hidden", "true");
panel.setAttribute("aria-label", "Data filters");
backdrop.className = "dt-filter-backdrop";
header.className = "dt-filter-panel__header";
title.className = "dt-filter-panel__title";
title.textContent = "Filters";
close.type = "button";
close.className = "dt-filter-panel__close";
close.setAttribute("aria-label", "Close filters");
close.innerHTML = "×";
body.className = "dt-filter-panel__body";
header.append(title, close);
body.appendChild(panes);
panel.append(header, body);
wrapper.insertBefore(toggle, wrapper.firstChild);
document.body.append(backdrop, panel);
function openPanel() {
lastFocusedElement = document.activeElement;
panel.classList.add("is-open");
backdrop.classList.add("is-open");
document.body.classList.add("dt-filter-panel-open");
panel.setAttribute("aria-hidden", "false");
toggle.setAttribute("aria-expanded", "true");
close.focus();
dataTable.columns.adjust();
}
function closePanel() {
panel.classList.remove("is-open");
backdrop.classList.remove("is-open");
document.body.classList.remove("dt-filter-panel-open");
panel.setAttribute("aria-hidden", "true");
toggle.setAttribute("aria-expanded", "false");
if (lastFocusedElement && document.contains(lastFocusedElement)) {
lastFocusedElement.focus();
}
dataTable.columns.adjust();
}
toggle.addEventListener("click", openPanel);
close.addEventListener("click", closePanel);
backdrop.addEventListener("click", closePanel);
document.addEventListener("keydown", function (event) {
if (event.key === "Escape" && panel.classList.contains("is-open")) {
closePanel();
}
});
}
$(".dataTable")
.each(function () {
var table = this;
waitForTableToSettle(table, function () {
if ($.fn.dataTable.isDataTable(table)) {
return;
}
normaliseDataTableRows(table, getDataTableColumnCount(table));
$(table).DataTable({
dom: "f",
retrieve: true,
order: [[0, "asc"]],
pageLength: 1000,
});
});
});
// ----- GAMES ------
$("#games > table").each(function () {
var table = this;
waitForTableToSettle(table, function () {
if ($.fn.dataTable.isDataTable(table)) {
return;
}
var titles = [
"Game", "Developer", "Publisher", "Genre", "Platform", "Mode", "Released"
];
var data = getTableData(table, titles.length);
buildTableLayout(table, titles);
var dataTable = new DataTable(table, {
columns: [
{
title: "Game",
render: function (data, type) {
if (type === "display") {
return (
'<span style="display: list-item; margin-left: 1.25rem; white-space: nowrap">' +
data +
"</span>"
);
}
return data;
},
searchPanes: {
show: false,
},
},
{
title: "Developer",
visible: true,
searchPanes: {
show: true,
},
},
{
title: "Publisher",
visible: true,
searchPanes: {
show: true,
},
},
{
title: "Genre",
visible: true,
searchPanes: {
show: true,
},
},
{
title: "Platform",
visible: true,
searchPanes: {
show: true,
},
},
{
title: "Mode",
visible: true,
render: {
display: function (data) {
return data;
},
sp: function (data) {
return getAcceptsValues(data);
},
},
searchPanes: {
show: true,
orthogonal: "sp",
},
},
{
title: "Released",
visible: true,
searchPanes: {
show: true,
},
},
],
layout: {
topStart: null,
topEnd: null,
top2: {
searchPanes: {
cascadePanes: true,
initCollapsed: true,
columns: [1, 2, 3, 4, 5],
},
},
top1: {
search: {
className: "mx-0 w-100",
},
},
},
order: [[0, "asc"]],
paging: false,
searchDelay: 400,
});
var lastGlobalSearch = dataTable.search();
var paneIndexes = [1, 2, 3, 4, 5];
dataTable.on("draw.dt", function () {
var globalSearch = dataTable.search();
openFellowshipLinksInNewTab(dataTable);
if (globalSearch === lastGlobalSearch) {
return;
}
lastGlobalSearch = globalSearch;
paneIndexes.forEach(function (paneIndex) {
dataTable.searchPanes.rebuildPane(paneIndex, true);
});
});
dataTable.rows.add(data).draw();
$(".dataTable")
.removeClass("dt-loading")
.removeAttr("aria-busy")
.show();
dataTable.searchPanes.rebuildPane();
setupFilterOffCanvas(dataTable, table);
suppressSearchPaneBorders(document.querySelector(".dt-filter-panel"));
dataTable.columns.adjust().draw(false);
});
});
}
