Make grid filters controlled through data- fields
This commit is contained in:
parent
ccbc904a25
commit
6f0e132a36
@ -5,20 +5,24 @@ class BrickGridFilter {
|
||||
|
||||
// Grid sort elements (built based on the initial id)
|
||||
this.html_search = document.getElementById(`${this.grid.id}-search`);
|
||||
this.html_status = document.getElementById(`${this.grid.id}-status`);
|
||||
this.html_theme = document.getElementById(`${this.grid.id}-theme`);
|
||||
this.html_filter = document.getElementById(`${this.grid.id}-filter`);
|
||||
|
||||
// Filter setup
|
||||
// Search setup
|
||||
if (this.html_search) {
|
||||
this.html_search.addEventListener("keyup", ((grid) => () => {
|
||||
grid.filter();
|
||||
this.html_search.addEventListener("keyup", ((gridfilter) => () => {
|
||||
gridfilter.filter();
|
||||
})(this));
|
||||
}
|
||||
|
||||
if (this.html_status) {
|
||||
this.html_status.addEventListener("change", ((grid) => () => {
|
||||
grid.filter();
|
||||
// Filters setup
|
||||
this.selects = [];
|
||||
if (this.html_filter) {
|
||||
this.html_filter.querySelectorAll("select[data-filter]").forEach(select => {
|
||||
select.addEventListener("change", ((gridfilter) => () => {
|
||||
gridfilter.filter();
|
||||
})(this));
|
||||
this.selects.push(select);
|
||||
});
|
||||
}
|
||||
|
||||
if (this.html_theme) {
|
||||
@ -30,52 +34,62 @@ class BrickGridFilter {
|
||||
|
||||
// Filter
|
||||
filter() {
|
||||
var filters = {};
|
||||
let options = {
|
||||
search: undefined,
|
||||
filters: [],
|
||||
};
|
||||
|
||||
// Check if there is a search filter
|
||||
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
|
||||
if (this.html_status && this.html_status.value != "") {
|
||||
if (this.html_status.value.startsWith("-")) {
|
||||
filters["filter"] = this.html_status.value.substring(1);
|
||||
filters["filter-target"] = "0";
|
||||
// Build filters
|
||||
for (const select of this.selects) {
|
||||
if (select.value != "") {
|
||||
// Multi-attribute filter
|
||||
switch (select.dataset.filter) {
|
||||
// List contains values
|
||||
case "solo":
|
||||
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 {
|
||||
filters["filter"] = this.html_status.value;
|
||||
filters["filter-target"] = "1";
|
||||
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
|
||||
const cards = this.grid.html_grid.querySelectorAll(`${this.grid.target} > .card`);
|
||||
cards.forEach(current => {
|
||||
// Set filter
|
||||
if ("filter" in filters) {
|
||||
if (current.getAttribute("data-" + filters["filter"]) != filters["filter-target"]) {
|
||||
current.parentElement.classList.add("d-none");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Theme filter
|
||||
if ("theme" in filters) {
|
||||
if (current.getAttribute("data-theme") != filters["theme"]) {
|
||||
// Process all filters
|
||||
for (const filter of options.filters) {
|
||||
if (current.getAttribute(`data-${filter.attribute}`) != filter.value) {
|
||||
current.parentElement.classList.add("d-none");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 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"]) {
|
||||
if (current.getAttribute(attribute).includes(filters["search"])) {
|
||||
if (current.getAttribute(attribute).includes(options.search)) {
|
||||
current.parentElement.classList.remove("d-none");
|
||||
return;
|
||||
}
|
||||
|
@ -35,12 +35,14 @@
|
||||
</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">
|
||||
<label class="visually-hidden" for="grid-status">Status</label>
|
||||
<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>
|
||||
<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="-has-missing">Set is complete</option>
|
||||
<option value="has-missing">Set has missing pieces</option>
|
||||
@ -56,7 +58,9 @@
|
||||
<label class="visually-hidden" for="grid-theme">Theme</label>
|
||||
<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>
|
||||
<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>
|
||||
{% for theme in collection.themes %}
|
||||
<option value="{{ theme | lower }}">{{ theme }}</option>
|
||||
|
Loading…
Reference in New Issue
Block a user