diff --git a/sass/style.scss b/sass/style.scss index 1df0e7b..76a0628 100644 --- a/sass/style.scss +++ b/sass/style.scss @@ -22,13 +22,15 @@ main.songs { } .filters { - // `display: grid` is set via JS to prevent displaying the inputs - // on browsers wih JavaScript disabled. - display: none; + display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 1em; margin: 1em 0; + // This is removed via JS to prevent displaying the inputs + // on browsers wih JavaScript disabled. + &.hidden { display: none } + &>* { border: 1px solid #aaa; border-radius: .5em; @@ -38,6 +40,12 @@ main.songs { &>.button { text-align: center; + cursor: pointer; + + &.selected { + border-color: #333; + box-shadow: rgba(0, 0, 0, 0.2) 0 0 10px; + } } } @@ -55,6 +63,8 @@ main.songs { box-shadow: rgba(0, 0, 0, 0.2) 0 0 10px; border-left: .7em solid #000; + &.hidden { display: none } + &.mixtape { border-color: #654575 } &.classic { border-color: #a55d05 } diff --git a/static/js/filter.js b/static/js/filter.js new file mode 100644 index 0000000..186aa48 --- /dev/null +++ b/static/js/filter.js @@ -0,0 +1,41 @@ +const filters = document.querySelector(".filters"); +const buttons = Array.from(filters.querySelectorAll(".button")); +const search = document.querySelector("input[type='text']"); +const songList = document.querySelector(".song-list"); + +let selectedCategory = null; + +function buttonToggle(clickedButton) { + buttons.forEach(button => { + if (button === clickedButton && !button.classList.contains("selected")) { + button.classList.add("selected"); + selectedCategory = button.dataset.category; + } else { + button.classList.remove("selected"); + if (button.dataset.category == selectedCategory) selectedCategory = null; + } + }); + filterSongs(); +} + +function filterSongs() { + const searchTerm = search.value.trim().toLowerCase().normalize("NFD").replace(/\p{Diacritic}/gu, ""); + const songs = Array.from(songList.children); + songs.forEach(song => { + const title = song.dataset.title.toLowerCase().normalize("NFD").replace(/\p{Diacritic}/gu, ""); + const matching = title.includes(searchTerm) && (!selectedCategory || song.dataset.category === selectedCategory); + song.classList.toggle("hidden", !matching); + }); +} + +// Event listeners +search.addEventListener("keyup", filterSongs); +buttons.forEach(button => button.addEventListener("click", () => buttonToggle(button))); + +// Normalize song titles +Array.from(songList.children).forEach(song => { + song.dataset.title = song.dataset.title.toLowerCase().normalize("NFD").replace(/\p{Diacritic}/gu, ""); +}); + +// Display the filter section on JS-enabled browsers +window.addEventListener("load", () => filters.classList.remove = "hidden"); diff --git a/templates/index.html b/templates/index.html index c82d933..7745953 100644 --- a/templates/index.html +++ b/templates/index.html @@ -13,12 +13,12 @@
-
classic
-
mixtape
+
classic
+
mixtape
{% for song in section.pages %} -
+
{{ song.title }}
{% if song.taxonomies["artist"] %} @@ -38,6 +38,8 @@
{% endblock %} -{% block script %}{% endblock %} +{% block script %} + +{% endblock %}