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)
|
// 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;
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user