From 5f214647521a93fa6cb54fcac7d4e1ae66fb7cec Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Thu, 27 Jan 2022 10:23:11 +0100 Subject: Resource filtering on the client, pt 1. Here's the initial version of this system. We've got filtering, but only by clicking checkboxes. The overall look and style are pretty close to where we want them, but it's missing tons of polish to be complete. The following commits will contain that polish. --- pydis_site/static/js/resources.js | 178 ++++++++++++++++++++++++++++++-------- 1 file changed, 143 insertions(+), 35 deletions(-) (limited to 'pydis_site/static/js') diff --git a/pydis_site/static/js/resources.js b/pydis_site/static/js/resources.js index 5c353f97..dee59e52 100644 --- a/pydis_site/static/js/resources.js +++ b/pydis_site/static/js/resources.js @@ -1,48 +1,156 @@ "use strict"; -const initialParams = new URLSearchParams(window.location.search); -const checkboxOptions = ['topic', 'type', 'payment', 'complexity']; -const createQuerySelect = (opt) => { - return "input[name=" + opt + "]" -} +// Filters that are currently selected +var activeFilters = { + topics: [], + type: [], + "payment-tiers": [], + complexity: [] +}; -checkboxOptions.forEach((option) => { - document.querySelectorAll(createQuerySelect(option)).forEach((checkbox) => { - if (initialParams.get(option).includes(checkbox.value)) { - checkbox.checked = true - } - }); -}); +/* Update the resources to match 'active_filters' */ +function update() { + let resources = $('.resource-box'); -function buildQueryParams() { - let params = new URLSearchParams(window.location.search); - checkboxOptions.forEach((option) => { - let tempOut = "" - document.querySelectorAll(createQuerySelect(option)).forEach((checkbox) => { - if (checkbox.checked) { - tempOut += checkbox.value + ","; + // If there's nothing in the filters, show everything and return. + if ( + activeFilters.topics.length === 0 && + activeFilters.type.length === 0 && + activeFilters["payment-tiers"].length === 0 && + activeFilters.complexity.length === 0 + ) { + resources.show(); + return; + } + + // Otherwise, hide everything and then filter the resources to decide what to show. + resources.hide(); + resources.filter(function() { + let validation = { + topics: false, + type: false, + 'payment-tiers': false, + complexity: false + }; + let resourceBox = $(this); + + // Validate the filters + $.each(activeFilters, function(filterType, activeFilters) { + // If the filter list is empty, this passes validation. + if (activeFilters.length === 0) { + validation[filterType] = true; + return; } + + // Otherwise, we need to check if one of the classes exist. + $.each(activeFilters, function(index, filter) { + if (resourceBox.hasClass(filter)) { + validation[filterType] = true; + } + }); }); - params.set(option, tempOut); - }); - window.location.search = params; + // If validation passes, show the resource. + if (Object.values(validation).every(Boolean)) { + return true; + } else { + return false; + } + }).show(); } -function clearQueryParams() { - checkboxOptions.forEach((option) => { - document.querySelectorAll(createQuerySelect(option)).forEach((checkbox) => { - checkbox.checked = false; - }); +// Executed when the page has finished loading. +document.addEventListener("DOMContentLoaded", function () { + + // If you collapse or uncollapse a filter group, swap the icon. + $('button.collapsible').click(function() { + let icon = $(this).find(".card-header-icon i"); + + if ($(icon).hasClass("fa-window-minimize")) { + $(icon).removeClass(["far", "fa-window-minimize"]); + $(icon).addClass(["fas", "fa-angle-down"]); + } else { + $(icon).removeClass(["fas", "fa-angle-down"]); + $(icon).addClass(["far", "fa-window-minimize"]); + } + }); + + // Update the filters on page load to reflect URL parameters. + + // If you click on the div surrounding the filter checkbox, it clicks the checkbox. + $('.filter-panel').click(function() { + let checkbox = $(this).find(".filter-checkbox"); + checkbox.prop("checked", !checkbox.prop("checked")); + checkbox.change(); }); -} -function selectAllQueryParams(column) { - checkboxOptions.forEach((option) => { - document.querySelectorAll(createQuerySelect(option)).forEach((checkbox) => { - if (checkbox.className == column) { - checkbox.checked = true; + // When checkboxes are toggled, trigger a filter update. + $('.filter-checkbox').change(function () { + let filterItem = this.dataset.filterItem; + let filterName = this.dataset.filterName; + let cssClass = filterName + "-" + filterItem; + var filterIndex = activeFilters[filterName].indexOf(cssClass); + + if (this.checked) { + if (filterIndex === -1) { + activeFilters[filterName].push(cssClass); } - }); + update(); + } else { + if (filterIndex !== -1) { + activeFilters[filterName].splice(filterIndex, 1); + } + update(); + } }); -} +}); + + + +// const initialParams = new URLSearchParams(window.location.search); +// const checkboxOptions = ['topic', 'type', 'payment', 'complexity']; +// +// const createQuerySelect = (opt) => { +// return "input[name=" + opt + "]" +// } +// +// checkboxOptions.forEach((option) => { +// document.querySelectorAll(createQuerySelect(option)).forEach((checkbox) => { +// if (initialParams.get(option).includes(checkbox.value)) { +// checkbox.checked = true +// } +// }); +// }); +// +// function buildQueryParams() { +// let params = new URLSearchParams(window.location.search); +// checkboxOptions.forEach((option) => { +// let tempOut = "" +// document.querySelectorAll(createQuerySelect(option)).forEach((checkbox) => { +// if (checkbox.checked) { +// tempOut += checkbox.value + ","; +// } +// }); +// params.set(option, tempOut); +// }); +// +// window.location.search = params; +// } +// +// function clearQueryParams() { +// checkboxOptions.forEach((option) => { +// document.querySelectorAll(createQuerySelect(option)).forEach((checkbox) => { +// checkbox.checked = false; +// }); +// }); +// } +// +// function selectAllQueryParams(column) { +// checkboxOptions.forEach((option) => { +// document.querySelectorAll(createQuerySelect(option)).forEach((checkbox) => { +// if (checkbox.className == column) { +// checkbox.checked = true; +// } +// }); +// }); +// } -- cgit v1.2.3