Skip to content

Instantly share code, notes, and snippets.

@jh3y
Created May 15, 2022 11:09
Show Gist options
  • Save jh3y/c33a3e3c07780f354370d07c6a3a28d7 to your computer and use it in GitHub Desktop.
Save jh3y/c33a3e3c07780f354370d07c6a3a28d7 to your computer and use it in GitHub Desktop.
How to make a CSS powered filter box ✨
class Search {
constructor(el) {
const ID = (this.ID = el.getAttribute("data-search-id"))
this.STYLES = document.querySelector(`#search-${ID}__styles`)
this.INPUT = document.querySelector(`#search-${ID}`)
this.INPUT.addEventListener("input", this.UPDATE.bind(this))
this.TAGS = document.querySelector(`#search-${ID}__tags`)
if (this.TAGS) {
this.CHECKS = this.TAGS.querySelectorAll('[type="radio"]')
this.CHECKS.forEach((c) =>
c.addEventListener("click", this.UPDATE.bind(this))
)
}
if (window.location.search) {
// Set the tag as checked
const tag = window.location.search.slice(window.location.search.indexOf('=') + 1)
document.querySelector(`#${tag}`).click()
}
}
UPDATE(e) {
let selector = `.${this.ID} > li`
// Could be a checkbox or the search field. Make changes based on that.
if (e.target !== this.INPUT) {
this.SELECTED_TAG =
e.target.checked && this.SELECTED_TAG !== e.target.id
? e.target.id
: undefined
if (!this.SELECTED_TAG) e.target.checked = false
}
if (this.INPUT.value.length >= 3) {
// We are using the input field. Do we have a selected tag to combine?
// And is the searchTerm >= 3 in length?
selector += `[data-search-term*="${this.INPUT.value}" i]`
}
if (this.SELECTED_TAG)
selector += `[data-search-tags*="${this.SELECTED_TAG}" i]`
if (this.INPUT.value.length >= 3 || this.SELECTED_TAG) {
this.STYLES.innerText = `
.${this.ID} > li {
display: none;
}
${selector} {
display: list-item;
}
`
} else {
this.STYLES.innerText = ``
}
}
}
document.querySelectorAll(".search").forEach((s) => new Search(s))
.search
& > * + *
margin-top var(--sz-7)
&__input
width 100%
&__list
margin 0
padding calc(var(--sz-4)) 0 0 0
list-style-type none
& > *
margin-top var(--sz-3)
&__tags-title
font-size var(--sz-4)
text-transform uppercase
margin-bottom var(--sz-1)
.tags
padding 0
margin 0
list-style-type none
& > *
margin-bottom var(--sz-1)
& > *:not(:last-child)
margin-right var(--sz-1)
.tag
--bd transparent
--bg var(--bg-3)
position relative
display inline-block
&:hover
--bg var(--bg-2)
&__control
opacity 0
position absolute
&:checked ~ label
--bd var(--border)
--bg var(--bg-2)
&__label
background var(--bg)
cursor pointer
border var(--sz-0) solid var(--bd)
padding var(--sz-2)
display flex
font-size var(--sz-4)
align-items center
&__icon
height var(--sz-6)
width var(--sz-6)
fill var(--color)
margin-right var(--sz-2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment