Create dedicated javascript object for Grid sort

This commit is contained in:
Gregoo 2025-01-30 22:30:14 +01:00
parent f854a01925
commit d80728d133
4 changed files with 158 additions and 140 deletions

View File

@ -6,26 +6,12 @@ class BrickGrid {
// Grid elements (built based on the initial id) // Grid elements (built based on the initial id)
this.html_grid = document.getElementById(this.id); this.html_grid = document.getElementById(this.id);
this.html_sort = document.getElementById(`${this.id}-sort`);
this.html_search = document.getElementById(`${this.id}-search`); this.html_search = document.getElementById(`${this.id}-search`);
this.html_status = document.getElementById(`${this.id}-status`); this.html_status = document.getElementById(`${this.id}-status`);
this.html_theme = document.getElementById(`${this.id}-theme`); this.html_theme = document.getElementById(`${this.id}-theme`);
// Sort buttons // Sort setup
this.html_sort_buttons = {}; this.sort = new BrickGridSort(this);
if (this.html_sort) {
this.html_sort.querySelectorAll("button[data-sort-attribute]").forEach(button => {
this.html_sort_buttons[button.id] = new BrickGridSortButton(button, this);
});
}
// Clear button
this.html_clear = document.querySelector("button[data-sort-clear]")
if (this.html_clear) {
this.html_clear.addEventListener("click", ((grid) => (e) => {
grid.clear();
})(this))
}
// Filter setup // Filter setup
if (this.html_search) { if (this.html_search) {
@ -46,46 +32,6 @@ class BrickGrid {
})(this)); })(this));
} }
// Cookie setup
const cookies = document.cookie.split(";").reduce((acc, cookieString) => {
const [key, value] = cookieString.split("=").map(s => s.trim().replace(/^"|"$/g, ""));
if (key && value) {
acc[key] = decodeURIComponent(value);
}
return acc;
}, {});
// Initial sort
if ("sort-id" in cookies && cookies["sort-id"] in this.html_sort_buttons) {
const current = this.html_sort_buttons[cookies["sort-id"]];
if("sort-order" in cookies) {
current.button.setAttribute("data-sort-order", cookies["sort-order"]);
}
this.sort(current, true);
}
}
// Clear
clear() {
// Cleanup all
for (const [id, button] of Object.entries(this.html_sort_buttons)) {
button.toggle();
button.inactive();
}
// Clear cookies
document.cookie = `sort-id=""; Path=/; SameSite=strict`;
document.cookie = `sort-order=""; Path=/; SameSite=strict`;
// Reset sorting
tinysort(this.target, {
selector: "div",
attr: "data-index",
order: "asc",
});
} }
// Filter // Filter
@ -153,53 +99,6 @@ class BrickGrid {
} }
} }
// Sort
sort(current, no_flip=false) {
const attribute = current.data.sortAttribute;
const natural = current.data.sortNatural;
// Cleanup all
for (const [id, button] of Object.entries(this.html_sort_buttons)) {
if (button != current) {
button.toggle();
button.inactive();
}
}
// Sort
if (attribute) {
let order = current.data.sortOrder;
// First ordering
if (!no_flip) {
if(!order) {
if (current.data.sortDesc) {
order = "desc"
} else {
order = "asc"
}
} else {
// Flip the sorting order
order = (order == "desc") ? "asc" : "desc";
}
}
// Toggle the ordering
current.toggle(order);
// Store cookies
document.cookie = `sort-id="${encodeURIComponent(current.button.id)}"; Path=/; SameSite=strict`;
document.cookie = `sort-order="${encodeURIComponent(order)}"; Path=/; SameSite=strict`;
// Do the sorting
tinysort(this.target, {
selector: "div",
attr: "data-" + attribute,
natural: natural == "true",
order: order,
});
}
}
} }
// Helper to setup the grids // Helper to setup the grids

View File

@ -1,49 +1,118 @@
// Sort button // Grid sort
class BrickGridSortButton { class BrickGridSort {
constructor(button, grid) { constructor(grid) {
this.button = button;
this.grid = grid; this.grid = grid;
this.data = this.button.dataset;
// Setup // Grid sort elements (built based on the initial id)
button.addEventListener("click", ((grid, button) => (e) => { this.html_sort = document.getElementById(`${this.grid.id}-sort`);
grid.sort(button);
})(grid, this)); if (this.html_sort) {
// Cookie names
this.cookie_id = `${this.grid.id}-sort-id`;
this.cookie_order = `${this.grid.id}-sort-order`;
// Sort buttons
this.html_sort_buttons = {};
this.html_sort.querySelectorAll("button[data-sort-attribute]").forEach(button => {
this.html_sort_buttons[button.id] = new BrickGridSortButton(button, this);
});
// Clear button
this.html_clear = this.html_sort.querySelector("button[data-sort-clear]")
if (this.html_clear) {
this.html_clear.addEventListener("click", ((grid) => () => {
grid.clear();
})(this))
}
// Cookie setup
const cookies = document.cookie.split(";").reduce((acc, cookieString) => {
const [key, value] = cookieString.split("=").map(s => s.trim().replace(/^"|"$/g, ""));
if (key && value) {
acc[key] = decodeURIComponent(value);
}
return acc;
}, {});
// Initial sort
if (this.cookie_id in cookies && cookies[this.cookie_id] in this.html_sort_buttons) {
const current = this.html_sort_buttons[cookies[this.cookie_id]];
if(this.cookie_order in cookies) {
current.button.setAttribute("data-sort-order", cookies[this.cookie_order]);
}
this.sort(current, true);
}
}
} }
// Active // Clear sort
active() { clear() {
this.button.classList.remove("btn-outline-primary"); // Cleanup all
this.button.classList.add("btn-primary"); for (const [id, button] of Object.entries(this.html_sort_buttons)) {
} button.toggle();
button.inactive();
// Inactive
inactive() {
delete this.button.dataset.sortOrder;
this.button.classList.remove("btn-primary");
this.button.classList.add("btn-outline-primary");
}
// Toggle sorting
toggle(order) {
// Cleanup
delete this.button.dataset.sortOrder;
let icon = this.button.querySelector("i.ri");
if (icon) {
this.button.removeChild(icon);
} }
// Set order // Clear cookies
if (order) { document.cookie = `${this.cookie_id}=""; Path=/; SameSite=strict`;
this.active(); document.cookie = `${this.cookie_order}=""; Path=/; SameSite=strict`;
this.button.dataset.sortOrder = order; // Reset sorting
tinysort(this.grid.target, {
selector: "div",
attr: "data-index",
order: "asc",
});
icon = document.createElement("i"); }
icon.classList.add("ri", "ms-1", `ri-sort-${order}`);
this.button.append(icon); // Sort
sort(current, no_flip=false) {
const attribute = current.data.sortAttribute;
const natural = current.data.sortNatural;
// Cleanup all
for (const [id, button] of Object.entries(this.html_sort_buttons)) {
if (button != current) {
button.toggle();
button.inactive();
}
}
// Sort
if (attribute) {
let order = current.data.sortOrder;
// First ordering
if (!no_flip) {
if(!order) {
if (current.data.sortDesc) {
order = "desc";
} else {
order = "asc";
}
} else {
// Flip the sorting order
order = (order == "desc") ? "asc" : "desc";
}
}
// Toggle the ordering
current.toggle(order);
// Store cookies
document.cookie = `${this.cookie_id}="${encodeURIComponent(current.button.id)}"; Path=/; SameSite=strict`;
document.cookie = `${this.cookie_order}="${encodeURIComponent(order)}"; Path=/; SameSite=strict`;
// Do the sorting
tinysort(this.grid.target, {
selector: "div",
attr: "data-" + attribute,
natural: natural == "true",
order: order,
});
} }
} }
} }

View File

@ -0,0 +1,49 @@
// Grid sort button
class BrickGridSortButton {
constructor(button, grid) {
this.button = button;
this.grid = grid;
this.data = this.button.dataset;
// Setup
button.addEventListener("click", ((grid, button) => (e) => {
grid.sort(button);
})(grid, this));
}
// Active
active() {
this.button.classList.remove("btn-outline-primary");
this.button.classList.add("btn-primary");
}
// Inactive
inactive() {
delete this.button.dataset.sortOrder;
this.button.classList.remove("btn-primary");
this.button.classList.add("btn-outline-primary");
}
// Toggle sorting
toggle(order) {
// Cleanup
delete this.button.dataset.sortOrder;
let icon = this.button.querySelector("i.ri");
if (icon) {
this.button.removeChild(icon);
}
// Set order
if (order) {
this.active();
this.button.dataset.sortOrder = order;
icon = document.createElement("i");
icon.classList.add("ri", "ms-1", `ri-sort-${order}`);
this.button.append(icon);
}
}
}

View File

@ -82,6 +82,7 @@
<script src="{{ url_for('static', filename='scripts/changer.js') }}"></script> <script src="{{ url_for('static', filename='scripts/changer.js') }}"></script>
<script src="{{ url_for('static', filename='scripts/grid/grid.js') }}"></script> <script src="{{ url_for('static', filename='scripts/grid/grid.js') }}"></script>
<script src="{{ url_for('static', filename='scripts/grid/sort.js') }}"></script> <script src="{{ url_for('static', filename='scripts/grid/sort.js') }}"></script>
<script src="{{ url_for('static', filename='scripts/grid/sort_button.js') }}"></script>
<script src="{{ url_for('static', filename='scripts/set.js') }}"></script> <script src="{{ url_for('static', filename='scripts/set.js') }}"></script>
<script src="{{ url_for('static', filename='scripts/socket/socket.js') }}"></script> <script src="{{ url_for('static', filename='scripts/socket/socket.js') }}"></script>
<script src="{{ url_for('static', filename='scripts/socket/instructions.js') }}"></script> <script src="{{ url_for('static', filename='scripts/socket/instructions.js') }}"></script>