Copy <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
.
Copy <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>
Copy {
"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.
Copy 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);
});