Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

300
Vistas
filter has an error in vanilla javascript small app (to do list)

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" class="todo-input">
  <button class="todo-button" type="submit">
            <i class="fas fa-plus-square"></i>
        </button>
  <div class="select">
    <select name="todos" class="filter-todo">
      <option value="all">All</option>
      <option value="completed">Completed</option>
      <option value="uncompleted">Uncompleted</option>
    </select>
  </div>
</form>
<div class="todo-container">
  <ul class="todo-list">
  </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

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

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>

about 4 years ago · Juan Pablo Isaza Denunciar

0

To show/hide your list of "todo" you can simplify this by using data attributes and then toggle them. Here I used one for the "action" state and the other to show/hide based on that.

function filterTodo(event) {
  event.preventDefault();
  let todoList = document.querySelector(".todo-list");
  let todoSelect = document.querySelector(".filter-todo");
  const todos = todoList.querySelectorAll(".todo-item");
  let val = event.target.value;
  todos.forEach(function(todo) {
    todo.dataset.status = todo.dataset.action === val && val !== "all" ? val : val === "all" ? "" : "none";
  });
}
let b = document.querySelector(".todo-button");
b.addEventListener('click', filterTodo);
let sel = document.querySelector(".filter-todo");
sel.addEventListener('change', filterTodo);
.todo-container,
.todo-container .todo-list {
  border: solid 1px lime;
  display: flex;
  flex-direction: column;
}

.todo-item {
  display: flex;
  background-color: #40404010;
  border: 1px solid #40404040;
  margin: 0.5em;
}

.todo-item[data-status="completed"] {
  background-color: #10401010;
}

.todo-item[data-action="completed"]::before {
  content: "DONE: ";
  color: green;
}

.todo-item[data-status="completed"] span {
  color: lime;
}

.todo-item[data-status="uncompleted"] {
  background-color: #40101010;
  text-decoration-line: underline overline;
}

.todo-item[data-status="none"] {
  display: none;
  text-decoration-color: red;
  text-decoration-style: solid;
  text-decoration-line: underline;
}

.todo-item[data-status=""] {
  text-decoration-color: cyan;
  text-decoration-style: solid;
  text-decoration-line: underline;
}
<form>
  <input type="text" class="todo-input" />
  <button class="todo-button" type="submit">
     <i class="fas fa-plus-square">[+]</i>
  </button>
  <div class="select-container">
    <select name="todos" class="filter-todo">
      <option value="all">All</option>
      <option value="completed">Completed</option>
      <option value="uncompleted">Uncompleted</option>
    </select>
  </div>
</form>
<div class="todo-container">
  <ul class="todo-list">
    <li class="todo-item">Get a new cat: I have no status or action</li>
    <li class="todo-item" data-action="completed" data-status="completed">Get a new Hippo</li>
    <li class="todo-item" data-action="uncompleted" data-status="uncompleted">Send MORE money!</li>
    <li class="todo-item" data-status="none">Send me money! I was hidden?</li>
    <li class="todo-item" data-status="fish">Send me money! fish?</li>
    <li class="todo-item" data-status="">Get to the bank NOW!</li>
  </ul>
</div>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda