Skip to content

Made admin panel tables sortable and filterable #87

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
made tables sortable and filterable
  • Loading branch information
sheldor1510 committed Jun 16, 2023
commit 0f962624c4a41070e8ab2e49a067316b1c0212f3
2 changes: 2 additions & 0 deletions resources/templates/footer.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

</body>

<script src="<?php echo $CONFIG["site"]["prefix"]; ?>/js/filterable.js"></script>
<script src="<?php echo $CONFIG["site"]["prefix"]; ?>/js/sortable.js"></script>
<script src="<?php echo $CONFIG["site"]["prefix"]; ?>/js/global.js"></script>
<script src="<?php echo $CONFIG["site"]["prefix"]; ?>/js/tables.js"></script>

Expand Down
10 changes: 5 additions & 5 deletions webroot/admin/pi-mgmt.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
<h1>PI Management</h1>
<hr>

<input type="text" id="tableSearch" placeholder="Search...">
<!-- <input type="text" id="tableSearch" placeholder="Search..."> -->

<h5>Pending PI Requests</h5>
<table class="searchable">
Expand Down Expand Up @@ -104,11 +104,11 @@

<h5>List of PIs</h5>

<table class="searchable longTable">
<table class="searchable longTable sortable filterable">
<tr class="key">
<td>Name</td>
<td>Unity ID</td>
<td>Mail</td>
<input type="text" style="max-width: fit-content; margin-right: 100px;" placeholder="Filter by Name..." class="filterSearch" id="name-filter"><td id="name"><span class="filter">⫧ </span>Name</td>
<input type="text" style="max-width: fit-content; margin-right: 100px;" placeholder="Filter by Unity ID..." class="filterSearch" id="unityID-filter"><td id="unityID"><span class="filter">⫧ </span>Unity ID</td>
<input type="text" style="max-width: fit-content; margin-right: 5px;" placeholder="Filter by Mail..." class="filterSearch" id="mail-filter"><td id="mail"><span class="filter">⫧ </span>Mail</td>
<td>Actions</td>
</tr>

Expand Down
14 changes: 7 additions & 7 deletions webroot/admin/user-mgmt.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@
<h1>User Management</h1>
<hr>

<input type="text" id="tableSearch" placeholder="Search...">
<!-- <input type="text" id="tableSearch" placeholder="Search..."> -->

<table class="searchable longTable">
<table class="searchable longTable sortable filterable">
<tr class="key">
<td>Name</td>
<td>UID</td>
<td>Org</td>
<td>Mail</td>
<td>Groups</td>
<input type="text" style="max-width: fit-content; margin-right: 5px;" placeholder="Filter by Name..." class="filterSearch" id="name-filter"><td id="name"><span class="filter">⫧ </span>Name</td>
<input type="text" style="max-width: fit-content; margin-right: 5px;" placeholder="Filter by UID..." class="filterSearch" id="uid-filter"><td id="uid"><span class="filter">⫧ </span>UID</td>
<input type="text" style="max-width: fit-content; margin-right: 5px;" placeholder="Filter by Org..." class="filterSearch" id="org-filter"><td id="org"><span class="filter">⫧ </span>Org</td>
<input type="text" style="max-width: fit-content; margin-right: 5px;" placeholder="Filter by Mail..." class="filterSearch" id="mail-filter"><td id="mail"><span class="filter">⫧ </span>Mail</td>
<input type="text" style="max-width: fit-content; margin-right: 5px;" placeholder="Filter by Groups..." class="filterSearch" id="groups-filter"><td id="groups"><span class="filter">⫧ </span>Groups</td>
<td>Actions</td>
</tr>

Expand Down
86 changes: 86 additions & 0 deletions webroot/js/filterable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");

if (pair[0] == variable) {
return pair[1];
}
}
return false;
}

function updateQueryStringParameter(uri, key, value) {
let currentURL = new URL(window.location.href);
let params = currentURL.searchParams;
if (params.has(key)) {
params.delete(key);
}
params.append(key, value);
window.history.pushState("object or string", "Title", currentURL.href);
}

function updateFilterInputs() {
$(".filterSearch").each(function() {
if (getQueryVariable("filter") != false) {
if (this.id == getQueryVariable("filter")+"-filter") {
if ($(this).css("display") == "inline-block" && $(this).css("visibility") == "visible" && getQueryVariable("value") == false) {
updateQueryStringParameter(window.location.href, "filter", "");
updateQueryStringParameter(window.location.href, "value", "");
updateFilterInputs();
return;
}
$(this).css("display", "inline-block");
$(this).css("visibility", "visible");
} else {
$(this).css("display", "inline-block");
$(this).css("visibility", "hidden");
}
} else {
$(this).css("display", "none");
}

if (getQueryVariable("value") != false) {
$(this).val(getQueryVariable("value"));
} else {
$(this).val("");
}

$(this).on("keyup", function(e) {
updateQueryStringParameter(window.location.href, "value", $(this).val());
filterRows();
})
});
}

updateFilterInputs();

var filters = document.querySelectorAll("span.filter");
filters.forEach(function(filter) {
filter.addEventListener("click", function(e) {
e.preventDefault();
e.stopPropagation();
updateQueryStringParameter(window.location.href, "filter", e.target.parentElement.id);
updateFilterInputs();
});
});

function filterRows() {
var filter = getQueryVariable("filter");
var filterValue = getQueryVariable("value");

if (filter) {
var table = document.querySelector("table.filterable");
var rows = Array.from(table.querySelectorAll("tr:nth-child(n+2)"));
var column = table.querySelector("tr.key").querySelector("td#" + filter).cellIndex;
rows.forEach(function(row) {
if (row.cells[column].textContent.trim().toLowerCase().indexOf(filterValue.toLowerCase()) == -1) {
row.style.display = "none";
} else {
row.style.display = "";
}
}
);
}
}
73 changes: 73 additions & 0 deletions webroot/js/sortable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
var table = document.querySelector("table.sortable");
table.querySelectorAll("td").forEach(function(td) {
td.addEventListener("click", function(e) {
if (td.parentElement.classList.contains("key") && td.innerHTML != "Actions") {
if (e.target.classList.contains("filter")) {
updateQueryStringParameter(window.location.href, "filter", e.target.parentElement.id);
updateFilterInputs();
} else {
var column = td.cellIndex;
var rows = Array.from(table.querySelectorAll("tr:nth-child(n+2)"));
var order = td.classList.toggle("asc") ? 1 : -1;
rows.sort(function(a, b) {
return order * (a.cells[column].textContent.trim().localeCompare(b.cells[column].textContent.trim(), undefined, {
numeric: true
}));
});
rows.forEach(function(row) {
table.appendChild(row);
});
var keys = document.querySelectorAll("tr.key");
keys.forEach(function(key) {
key.querySelectorAll("td").forEach(function(td) {
td.innerHTML = td.innerHTML.replace(/ ▲| ▼/, "");
});
});
var orderSymbol = order == 1 ? "&#x25B2;" : "&#x25BC;";
td.innerHTML = td.innerHTML + " " + orderSymbol;
updateQueryStringParameter(window.location.href, "sort", td.id);
updateQueryStringParameter(window.location.href, "order", order == 1 ? "asc" : "desc");
}
}
});
});

function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");

if (pair[0] == variable) {
return pair[1];
}
}
return false;
}

function updateQueryStringParameter(uri, key, value) {
let currentURL = new URL(window.location.href);
let params = currentURL.searchParams;
if (params.has(key)) {
params.delete(key);
}
params.append(key, value);
window.history.pushState("object or string", "Title", currentURL.href);
}

window.onload = function() {
var sort = getQueryVariable("sort");
var order = getQueryVariable("order");
if (sort) {
var sortElement = document.getElementById(sort);
if (sortElement) {
if (order == "asc") {
sortElement.click();
} else if (order == "desc") {
sortElement.click();
sortElement.click();
}
}
}
filterRows();
}