4.4 - Filters
Introduction

How it works
Most of the filters are input type="text"
with a data-list
attribute. The data-lpignore="true"
attribute makes sure there won't be any icons from the LastPass extension.
<fieldset>
<label for="key">key</label>
<input
type="text"
name="key"
id="key"
list="key_list"
data-lpignore="true"
placeholder="Search"
/>
<datalist id="key_list">
<option>C</option>
<option>Dâ™</option>
<option>D</option>
<option>Eâ™</option>
<option>E</option>
<option>G</option>
<option>F#</option>
<option>Aâ™</option>
<option>A</option>
<option>Bâ™</option>
<option>B</option>
</datalist>
</fieldset>
The genres filter is being rendered with a seperate genres list. The genres are stored in genres.json
.
<fieldset>
<label for="tag">Genre</label>
<input
type="text"
name="genre"
id="genre"
list="genre_list"
data-lpignore="true"
placeholder="Search"
/>
<datalist id="genre_list">
<% Object.keys(genreList).forEach(function(main) { %> <%
genreList[main].forEach(genre => { %>
<option value="<%= genre %>"><%= genre %></option>
<% }) %> <% }) %>
</datalist>
</fieldset>
genres.json
{
"blues": [
"blues"
],
"classical": [
"classical",
"new-age",
"opera",
"piano"
],
...
}
This makes it possible to easily change or add genres to the filter.
Because of the short time and that our focus laid elsewhere the filters are not filtering anything right now. Instead they work as a search query.
In the code below every filter has got an event listener on it. If the input changes it will search the Spotify API.
const filters = [
{ input: searchBar, form: 'quickSearchForm' },
{ input: genreInput, form: 'filtersForm' },
{ input: instrumentInput, form: 'filtersForm' },
{ input: vocalsInput, form: 'filtersForm' },
{ input: keyInput, form: 'filtersForm' },
{ input: langInput, form: 'filtersForm' },
{ input: moodInput, form: 'filtersForm' },
{ input: themesInput, form: 'filtersForm' },
{ input: countryInput, form: 'filtersForm' },
{ input: yearInput, form: 'filtersForm' },
];
function fetchOnInput(input, formID) {
input.addEventListener(
'input',
debounce((event) => {
const userInput = event.target.value;
const url = document.getElementById(formID).getAttribute('action');
history.replaceState({}, '', `?searchValue=${userInput}&token=${token}`);
let areThereChips = document.querySelectorAll('.chips');
if (areThereChips.length >= 1) {
areThereChips.forEach((item) => item.remove());
}
const newEl = document.createElement('span');
newEl.innerHTML = `${userInput} <span class="material-icons"> clear </span>`;
newEl.setAttribute('class', 'chips');
activeFiltersChips.append(newEl);
fetch(`${url}?query=${userInput}&async=true&token=${token}`)
.then((res) => res.text())
.then((html) => {
const resultComponents = document.querySelectorAll('.search-results');
resultComponents.forEach((component) => {
component.innerHTML = html;
});
});
})
);
}
filters.forEach((item) => {
fetchOnInput(item.input, item.form);
});
Last updated
Was this helpful?