Make grid filters controlled through data- fields

This commit is contained in:
Gregoo 2025-01-30 23:24:22 +01:00
parent ccbc904a25
commit 6f0e132a36
2 changed files with 58 additions and 40 deletions

View File

@ -5,20 +5,24 @@ class BrickGridFilter {
// Grid sort elements (built based on the initial id) // Grid sort elements (built based on the initial id)
this.html_search = document.getElementById(`${this.grid.id}-search`); this.html_search = document.getElementById(`${this.grid.id}-search`);
this.html_status = document.getElementById(`${this.grid.id}-status`); this.html_filter = document.getElementById(`${this.grid.id}-filter`);
this.html_theme = document.getElementById(`${this.grid.id}-theme`);
// Filter setup // Search setup
if (this.html_search) { if (this.html_search) {
this.html_search.addEventListener("keyup", ((grid) => () => { this.html_search.addEventListener("keyup", ((gridfilter) => () => {
grid.filter(); gridfilter.filter();
})(this)); })(this));
} }
if (this.html_status) { // Filters setup
this.html_status.addEventListener("change", ((grid) => () => { this.selects = [];
grid.filter(); if (this.html_filter) {
})(this)); this.html_filter.querySelectorAll("select[data-filter]").forEach(select => {
select.addEventListener("change", ((gridfilter) => () => {
gridfilter.filter();
})(this));
this.selects.push(select);
});
} }
if (this.html_theme) { if (this.html_theme) {
@ -30,52 +34,62 @@ class BrickGridFilter {
// Filter // Filter
filter() { filter() {
var filters = {}; let options = {
search: undefined,
filters: [],
};
// Check if there is a search filter // Check if there is a search filter
if (this.html_search && this.html_search.value != "") { if (this.html_search && this.html_search.value != "") {
filters["search"] = this.html_search.value.toLowerCase(); options.search = this.html_search.value.toLowerCase();
} }
// Check if there is a set filter // Build filters
if (this.html_status && this.html_status.value != "") { for (const select of this.selects) {
if (this.html_status.value.startsWith("-")) { if (select.value != "") {
filters["filter"] = this.html_status.value.substring(1); // Multi-attribute filter
filters["filter-target"] = "0"; switch (select.dataset.filter) {
} else { // List contains values
filters["filter"] = this.html_status.value; case "solo":
filters["filter-target"] = "1"; options.filters.push({
attribute: select.dataset.filterAttribute,
value: select.value,
})
break;
// List contains attribute name, looking for true/false
case "status":
if (select.value.startsWith("-")) {
options.filters.push({
attribute: select.value.substring(1),
value: "0"
})
} else {
options.filters.push({
attribute: select.value,
value: "1"
})
}
break;
}
} }
} }
// Check if there is a theme filter
if (this.html_theme && this.html_theme.value != "") {
filters["theme"] = this.html_theme.value;
}
// Filter all cards // Filter all cards
const cards = this.grid.html_grid.querySelectorAll(`${this.grid.target} > .card`); const cards = this.grid.html_grid.querySelectorAll(`${this.grid.target} > .card`);
cards.forEach(current => { cards.forEach(current => {
// Set filter // Process all filters
if ("filter" in filters) { for (const filter of options.filters) {
if (current.getAttribute("data-" + filters["filter"]) != filters["filter-target"]) { if (current.getAttribute(`data-${filter.attribute}`) != filter.value) {
current.parentElement.classList.add("d-none");
return;
}
}
// Theme filter
if ("theme" in filters) {
if (current.getAttribute("data-theme") != filters["theme"]) {
current.parentElement.classList.add("d-none"); current.parentElement.classList.add("d-none");
return; return;
} }
} }
// Check all searchable fields for a match // Check all searchable fields for a match
if ("search" in filters) { if (options.search) {
for (let attribute of ["data-name", "data-number", "data-parts", "data-theme", "data-year"]) { for (let attribute of ["data-name", "data-number", "data-parts", "data-theme", "data-year"]) {
if (current.getAttribute(attribute).includes(filters["search"])) { if (current.getAttribute(attribute).includes(options.search)) {
current.parentElement.classList.remove("d-none"); current.parentElement.classList.remove("d-none");
return; return;
} }

View File

@ -35,12 +35,14 @@
</div> </div>
</div> </div>
</div> </div>
<div class="row row-cols-lg-auto g-1 justify-content-center align-items-center pb-2"> <div id="grid-filter" class="row row-cols-lg-auto g-1 justify-content-center align-items-center pb-2">
<div class="col-12 flex-grow-1"> <div class="col-12 flex-grow-1">
<label class="visually-hidden" for="grid-status">Status</label> <label class="visually-hidden" for="grid-status">Status</label>
<div class="input-group"> <div class="input-group">
<span class="input-group-text"><i class="ri-checkbox-line"></i><span class="ms-1 d-none d-xl-inline"> Status</span></span> <span class="input-group-text"><i class="ri-checkbox-line"></i><span class="ms-1 d-none d-xl-inline"> Status</span></span>
<select id="grid-status" class="form-select form-select-sm" autocomplete="off"> <select id="grid-status" class="form-select form-select-sm"
data-filter="status"
autocomplete="off">
<option value="" selected>All</option> <option value="" selected>All</option>
<option value="-has-missing">Set is complete</option> <option value="-has-missing">Set is complete</option>
<option value="has-missing">Set has missing pieces</option> <option value="has-missing">Set has missing pieces</option>
@ -56,7 +58,9 @@
<label class="visually-hidden" for="grid-theme">Theme</label> <label class="visually-hidden" for="grid-theme">Theme</label>
<div class="input-group"> <div class="input-group">
<span class="input-group-text"><i class="ri-price-tag-3-line"></i><span class="ms-1 d-none d-xl-inline"> Theme</span></span> <span class="input-group-text"><i class="ri-price-tag-3-line"></i><span class="ms-1 d-none d-xl-inline"> Theme</span></span>
<select id="grid-theme" class="form-select form-select-sm" autocomplete="off"> <select id="grid-theme" class="form-select form-select-sm"
data-filter="solo" data-filter-attribute="theme"
autocomplete="off">
<option value="" selected>All</option> <option value="" selected>All</option>
{% for theme in collection.themes %} {% for theme in collection.themes %}
<option value="{{ theme | lower }}">{{ theme }}</option> <option value="{{ theme | lower }}">{{ theme }}</option>