diff options
author | 2022-01-27 10:23:11 +0100 | |
---|---|---|
committer | 2022-01-27 10:23:11 +0100 | |
commit | 5f214647521a93fa6cb54fcac7d4e1ae66fb7cec (patch) | |
tree | 48f8bdfb0e2dd8e99532d28bde10ea5e8112d9cf /pydis_site/static | |
parent | Clean up dependency file and bump simple-bulma. (diff) |
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.
Diffstat (limited to 'pydis_site/static')
-rw-r--r-- | pydis_site/static/css/resources/resources.css | 48 | ||||
-rw-r--r-- | pydis_site/static/js/resources.js | 178 |
2 files changed, 166 insertions, 60 deletions
diff --git a/pydis_site/static/css/resources/resources.css b/pydis_site/static/css/resources/resources.css index 488effc3..f70cbd64 100644 --- a/pydis_site/static/css/resources/resources.css +++ b/pydis_site/static/css/resources/resources.css @@ -1,29 +1,27 @@ -/*.box, .tile.is-parent {*/ -/* transition: 0.1s ease-out;*/ -/*}*/ -/*.box {*/ -/* min-height: 15vh;*/ -/*}*/ -/*.tile.is-parent:hover .box {*/ -/* box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);*/ -/*}*/ -/*.tile.is-parent:hover {*/ -/* padding: 0.65rem 0.85rem 0.85rem 0.65rem;*/ -/* filter: saturate(1.1) brightness(1.1);*/ -/*}*/ +/* Disable highlighting for all text in the filters. */ +.filter-checkbox, +.filter-panel label, +.card-header span { + user-select: none +} -/*#readingBlock {*/ -/* background-image: linear-gradient(141deg, #911eb4 0%, #b631de 71%, #cf4bf7 100%);*/ -/*}*/ +/* Remove pointless margin in panel header */ +#filter-panel-header { + margin-bottom: 0; +} -/*#interactiveBlock {*/ -/* background-image: linear-gradient(141deg, #d05600 0%, #da722a 71%, #e68846 100%);*/ -/*}*/ +/* Full width filter cards */ +#resource-filtering-panel .card .collapsible-content .card-content { + padding:0 +} -/*#communitiesBlock {*/ -/* background-image: linear-gradient(141deg, #3b756f 0%, #3a847c 71%, #41948b 100%);*/ -/*}*/ +/* Disable clicking on the checkbox itself. */ +/* Instead, we want to let the anchor tag handle clicks. */ +.filter-checkbox { + pointer-events: none; +} -/*#podcastsBlock {*/ -/* background-image: linear-gradient(141deg, #232382 0%, #30309c 71%, #4343ad 100%);*/ -/*}*/ +/* Blurple category icons */ +i.is-primary { + color: #7289da; +} 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; +// } +// }); +// }); +// } |