Explained solution 06: Render a safe, usable filter
A: change notification → listener callback → read select.value → filter events → create/append cards → update count. Filtering is data work; replacing children changes the DOM.
B: textContent makes the fixture title literal text. innerHTML would parse its tags. Avoid treating an untrusted title as markup. This does not solve every kind of unsafe attribute or URL; it solves this text insertion need.
C: add <label for="search">Search titles</label><input id="search" type="search">, then use one shared refresh function:
const search = document.querySelector("#search");
function refresh() {
const query = search.value.trim().toLowerCase();
const selected = category.value;
const visible = events.filter((event) => {
return event.title.toLowerCase().includes(query)
&& (selected === "all" || event.category === selected);
});
renderEvents(visible);
}
search.addEventListener("input", refresh);
category.addEventListener("change", refresh);
refresh();
Replace the old category listener rather than adding a second redundant one. Do not recreate the search input while rendering the list. The full combined filter is also in capstone/reference/core.js.