Home > Mobile >  filter has an error in vanilla javascript small app (to do list)
filter has an error in vanilla javascript small app (to do list)

Time:03-05

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>

  • Related