Sample:
Records
Filter
Results
-
Bambule (1998)
Absolute Beginner
-
Very proud of ya (1996)
AFI
-
All Hollows EP (1999)
AFI
-
Die große Palmöllüge (2020)
Akne Kid Joe
-
Suffer (1988)
Bad Religion
-
Age of Unreason (2019)
Bad Religion
-
Licensed to Ill (1986)
Beastie Boys
-
Paul's Boutique (1989)
Beastie Boys
-
Check Your Head (1992)
Beastie Boys
-
Ill Communication (1994)
Beastie Boys
Code:
<style>
strong {
display: block;
}
.pagination ol {
display: flex;
list-style: none;
gap: 0.5em;
margin: 0;
padding: 0;
}
.pagination a {
align-items: center;
aspect-ratio: 1;
border: 1px solid;
border-radius: 50%;
display: flex;
justify-content: center;
text-decoration: none;
width: 2em;
}
.pagination a:is([aria-current="page"], :hover, :focus-visible) {
background-color: #3c843f;
color: #ffffff;
}
.visually-hidden {
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
</style>
<h1>Records</h1>
<h2>Filter</h2>
<form role="form" aria-label="Filter" id="filter">
<label for="artist">Artist</label>
<select id="artist" name="artist">
<option value="">All</option>
<option>AFI</option>
<option>Absolute Beginner</option>
<option>Akne Kid Joe</option>
<option>Bad Religion</option>
<option>Beastie Boys</option>
<option>Bilderbuch</option>
<option>Billy Joel</option>
<option>Bring me the Horizon</option>
<option>Dead Kennedys</option>
<option>Dendemann</option>
<option>Der Nino aus Wien</option>
<option>Dog Eat Dog</option>
<option>Dr. Dre</option>
<option>Eater</option>
<option>Idles</option>
<option>Minutemen</option>
<option>PUP</option>
<option>Rancid</option>
<option>The Eradicator</option>
<option>The Menzingers</option>
</select>
<fieldset>
<legend>Country</legend>
<input type="checkbox" name="country" id="country_at" value="at">
<label for="country_at">Austria</label>
<input type="checkbox" name="country" id="country_ca" value="ca">
<label for="country_ca">Canada</label>
<input type="checkbox" name="country" id="country_us" value="us">
<label for="country_us">USA</label>
<input type="checkbox" name="country" id="country_de" value="de">
<label for="country_de">Germany</label>
<input type="checkbox" name="country" id="country_uk" value="uk">
<label for="country_uk">United Kingdom</label>
</fieldset>
<fieldset>
<legend>Shipping</legend>
<input type="radio" name="shipping" id="shipping_eu" value="eu">
<label for="shipping_eu">Europe</label>
<input type="radio" name="shipping" id="shipping_world" value="worldwide">
<label for="shipping_world">Worldwide</label>
<input type="radio" name="shipping" id="shipping_us" value="us">
<label for="shipping_us">USA</label>
</fieldset>
<fieldset id="sorting">
<legend>Sort by</legend>
<div>
<input type="radio" id="sorting_artist" name="sorting" checked value="artist">
<label for="sorting_artist">Artist</label>
<input type="radio" id="sorting_date" name="sorting" value="year">
<label for="sorting_date">Date</label>
</div>
</fieldset>
<div id="live-region-sorting" hidden>Sorted by [type]</div>
<button>Search</button>
</form>
<div role="region" aria-labelledby="results_heading" id="results" tabindex="-1">
<h2 id="results_heading">Results</h2>
<div role="status" class="visually-hidden"></div>
<ol>
<li>
<strong>Bambule (1998)</strong>
Absolute Beginner
</li>
<li>
<strong>Very proud of ya (1996)</strong>
AFI
</li>
<li>
<strong>All Hollows EP (1999)</strong>
AFI
</li>
<li>
<strong>Die große Palmöllüge (2020)</strong>
Akne Kid Joe
</li>
<li>
<strong>Suffer (1988)</strong>
Bad Religion
</li>
<li>
<strong>Age of Unreason (2019)</strong>
Bad Religion
</li>
<li>
<strong>Licensed to Ill (1986)</strong>
Beastie Boys
</li>
<li>
<strong>Paul's Boutique (1989)</strong>
Beastie Boys
</li>
<li>
<strong>Check Your Head (1992)</strong>
Beastie Boys
</li>
<li>
<strong>Ill Communication (1994)</strong>
Beastie Boys
</li>
</ol>
</div>
<nav aria-label="Select page" class="pagination">
<ol>
<li>
<a href="/filter.html/1" aria-current="page">1</a>
</li>
<li>
<a href="/filter.html/2">2</a>
</li>
<li>
<a href="/filter.html/3">3</a>
</li>
<li>
<a href="/filter.html/4">4</a>
</li>
</ol>
</nav>
<script>
const form = document.getElementById("filter");
const results = document.getElementById("results");
const list = results.querySelector("ol");
const sorting = form.querySelector("#sorting");
const liveRegion = document.querySelector("[role='status']")
const sortingMessage = document.querySelector("#live-region-sorting");
let records,
filtered;
function finishQuery() {
results.focus();
}
function showResults() {
list.innerHTML = "";
console.log(filtered)
for (let i = 0; i < filtered.length; i++) {
const record = filtered[i];
const item = document.createElement("li");
const title = document.createElement("strong");
title.textContent = `${record.title} (${record.year})`;
item.append(title, record.artist);
list.append(item);
}
}
function filterForm(e) {
e.preventDefault();
const formData = new FormData(form);
filtered = records.filter((record) => {
const artist = formData.get("artist");
const countries = formData.getAll("country");
const shipping = formData.getAll("shipping");
if (artist && record.artist !== artist) {
console.log(1)
return;
}
if (countries.length && !countries.includes(record.country)) {
console.log(2)
return;
}
if (shipping.length && !shipping.includes(record.shipping)) {
console.log(3)
return;
}
console.log(4)
return true;
});
showResults();
finishQuery();
}
async function getRecords() {
const response = await fetch("/assets/data/records.json");
return await response.json();
}
function sortRecords(type) {
function compare(a,b) {
let fieldA = a[type];
let fieldB = b[type];
if (typeof fieldA === 'string') {
fieldA = fieldA.toLowerCase()
fieldB = fieldB.toLowerCase()
}
if (fieldA < fieldB){
return -1;
}
if (fieldA > fieldB){
return 1;
}
return 0;
}
filtered.sort(compare);
}
getRecords().then((data) => {
records = data;
filtered = data;
form.addEventListener("submit", filterForm);
sorting.addEventListener("change", (e) => {
const type = e.target.value;
sortRecords(type);
showResults();
liveRegion.textContent = sortingMessage.textContent.replace("[type]", type);
});
});
</script>