I’m building an overview of plants with HTML, SCSS and JS and the user should have the option to filter plants by their need of light. It works fine, that the plants are displayed as cards but checking the checkbox does absolutely nothing.
This is what the checkboxes in HTML look like:
<div class="multiple-choice">
<span><b>Light:</b><br/></span>
<label for="halbschattig">
<input type="checkbox" name="checklight" value="0" id="halbschattig">
halbschattig
</label><br/>
<label for="hell">
<input type="checkbox" name="checklight" value="1" id="hell">
hell
</label><br />
<label for="sonnig">
<input type="checkbox"
name="checklight" value="2" id="sonnig">
sonnig
</label>
</div>
I stored all information about the plants in a JSON file, fetch it and then they get displayed. This is my JS code to fetch and display the data:
let plantsArr = [];
const plantcards = document.getElementById("plantcards");
let allCheckboxes = document.querySelectorAll("input[type=checkbox]");
let plantcard = Array.from(document.querySelectorAll(".plantcard"));
let checked = {};
async function getPlants() {
try {
const response = await fetch("../files/pflanzen.json", {
method: "GET",
});
if (!response.ok) {
throw new Error(`Error! status: ${response.status}`);
}
let data = await response.json();
for (const key in data) {
{
plantsArr.push(data[key]);
}
}
return data;
} catch (error) {
console.log(error);
}
}
/* Load plants */
getPlants().then((data) => {
data.forEach((data) => {
plantcards.insertAdjacentHTML(
"afterbegin",
`<article class="plantcard">
<div class="article-wrapper">
<figure>
<img src="../images/plant_types/${data.Image}" alt="${data.Name}" />
</figure>
<div class="article-body">
<h2>${data.Name}</h2>
<h3>${data.NameLatin}</h3>
<p>
Standort: ${getPlantLight(data.Light)}<br/>
</p>
<a href="#" class="read-more">
Read more <span class="sr-only">about this is some title</span>
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M12.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</a>
</div>
</div>
</article>`
);
});
});
I tried to apply the filter (at the moment only for the light demand until this works) like the following:
getChecked("checklight");
Array.prototype.forEach.call(allCheckboxes, function (el) {
el.addEventListener("change", toggleCheckbox);
});
function toggleCheckbox(e) {
getChecked(e.target.name);
setVisibility();
}
function getChecked(name) {
checked[name] = Array.from(
document.querySelectorAll("input[name=" + name + "]:checked")
).map(function (el) {
return el.value;
});
}
function setVisibility() {
plantcard.map(function (el) {
let checklight = checked.checklight.length
? _.intersection(Array.from(el.classList), checked.checklight).length
: true;
if (checklight) {
el.style.display = "block";
console.log("block");
} else {
el.style.display = "none";
console.log("none");
}
});
}
Nothing happens in the console. If anyone might have a look at this and could give me a hint what I’m missing I’d be very grateful! 🙂