So I'm building a small app using vanilla javascript , this app is a to-do list with some functionality, I have an error when I press on the filter here is the javascript code:
function filterTodo(e) {
const todos = todoList.childNodes;
// console.log(todos);
todos.forEach(function(todo) {
switch (e.target.value) {
case "all":
todo.style.display = "flex";
break;
case "completed":
if (todo.classList.contains("completed")) {
todo.style.display = "flex";
} else {
todo.style.display = "none";
}
break;
case "uncompleted":
if (!todo.classList.contains("completed")) {
todo.style.display = "flex";
} else {
todo.style.display = "none";
}
break;
}
});
}
<form>
<input type="text" >
<button type="submit">
<i ></i>
</button>
<div >
<select name="todos" >
<option value="all">All</option>
<option value="completed">Completed</option>
<option value="uncompleted">Uncompleted</option>
</select>
</div>
</form>
<div >
<ul >
</ul>
</div>
Here is an image for the error: [This error keeps showing up when I press on the filter][1] [1]: https://i.stack.imgur.com/63CXI.png
I can't find my mistake but I think that (todo) is not identified in the anonymous function or there is a mistake with the forEach function. please help and thank you.
Note:Here is the url for the whole app on github:https://github.com/Shtaiwee1/Web_fund_additional_apps/tree/master/To_do_list
CodePudding user response:
You could just change the class of your list (the <ul>
not the <li>
) and let CSS casscading take care of the rest. .forEach()
is definitely not needed nor any array or NodeList for that matter. Also, you should always have a default
in a switch()
-- in this example default
removes both classes from <ul>
(it doesn't matter if class is actually there or not so covering both is 100% no calculations involved). BTW, "click" is ok in this situation, but you should use "change" event since it's designed for form controls like <select>
.
const form = document.forms[0];
const select = form.elements.filter;
select.addEventListener('change', filterList);
function filterList(e) {
const select = e.target;
const list = document.querySelector('.list');
if (select.matches('#filter')) {
switch (select.value) {
case 'done':
list.classList.remove('open');
list.classList.add('done');
break;
case 'open':
list.classList.remove('done');
list.classList.add('open');
break;
default:
list.classList.remove('done');
list.classList.remove('open');
break;
}
}
};
li.open::before {
content: '⬛'
}
li.done::before {
content: '☑️'
}
.list.open li.done {
display: none
}
.list.done li.open {
display: none
}
<form>
<select id='filter'>
<option default value=''>All</option>
<option value='done'>Completed</option>
<option value='open'>Uncompleted</option>
</select>
<ul class='list'>
<li class='done'>Task</li>
<li class='open'>Task</li>
<li class='done'>Task</li>
<li class='done'>Task</li>
<li class='open'>Task</li>
<li class='done'>Task</li>
<li class='open'>Task</li>
<li class='open'>Task</li>
<li class='done'>Task</li>
</ul>
</form>