Jeknar :
I'm working on my to do list app. Most of it works fine, but I still get this issue (Uncaught TypeError: Cannot read property of undefined). For some reason I cannot understand yet, I cannot pass the array toDoList
to the searchList
function in order to filter the relevant elements for my dynamic search feature. Would anybody be willing to help?
const button = document.querySelector("button");
let toDoList = [];
const input = document.querySelector(".add");
const search = document.querySelector(".search");
const ul = document.querySelector("ul");
const removeBtn = document.getElementsByClassName("remove");
const span = document.querySelector("h1 span");
const key = 0
const addItem = (e) => {
e.preventDefault()
ul.innerHTML = ""
toDoList.push(input.value)
toDoList.forEach((toDoElement, key) => {
const task = document.createElement("li")
task.dataset.key = key;
key++
task.className = "task";
task.textContent = toDoElement
task.innerHTML += ` <button>usuń</button>`
ul.appendChild(task);
span.textContent = toDoList.length;
task.querySelector("button").addEventListener("click", removeItem)
})
}
const searchList = (e, toDoList) => {
ul.innerHTML = ""
if (search.value === "") {
toDoList.forEach((toDoElement, key) => {
const task = document.createElement("li")
task.dataset.key = key;
key++
task.className = "task";
task.textContent = toDoElement
task.innerHTML += ` <button>usuń</button>`
ul.appendChild(task);
span.textContent = toDoList.length;
task.querySelector("button").addEventListener("click", removeItem)
})
} else {
const searchText = e.target.value.toLowerCase();
console.log(searchText);
console.log(toDoList);
let result = toDoList.filter(li => li.textContent.toLowerCase().includes(searchText))
console.log(result)
}
}
const removeItem = (e) => {
e.target.parentNode.remove();
const index = e.target.parentNode.dataset.key;
toDoList.splice(index, 1)
span.textContent = toDoList.length;
}
button.addEventListener("click", addItem);
search.addEventListener("input", searchList)
<form>
<input type="text" class="add">
<button>Dodaj zadanie</button>
</form>
<form>
<input type="text" class="search">
</form>
<h1>Liczba zadań: <span></span></h1>
<ul></ul>
Herculean Inc :
You stored toDoList
globally, so defining a function variable named toDoList
overwrote it in that scope with whatever was passed in (which was nothing, so it was undefined
). As others said, just removing the parameter from searchList
was sufficient.
I tried to tidy the code up as well so it is more readable, and I added missing semicolons. They are not optional! ;-)
const button = document.querySelector("button");
const input = document.querySelector(".add");
const search = document.querySelector(".search");
const ul = document.querySelector("ul");
const removeBtn = document.getElementsByClassName("remove");
const span = document.querySelector("h1 span");
var toDoList = [];
const key = 0;
const addItem = (e) => {
e.preventDefault();
ul.innerHTML = "";
toDoList.push(input.value);
toDoList.forEach((toDoElement, key) => {
const task = document.createElement("li");
task.dataset.key = key++;
task.className = "task";
task.innerHTML = toDoElement + "<button>Remove</button>";
task.querySelector("button").addEventListener("click", removeItem);
ul.appendChild(task);
span.textContent = toDoList.length;
});
}
const removeItem = (e) => {
e.target.parentNode.remove();
const index = e.target.parentNode.dataset.key;
toDoList.splice(index, 1);
span.textContent = toDoList.length;
}
const searchList = (e) => {
ul.innerHTML = "";
if (!search.value)
toDoList.forEach((toDoElement, key) => {
const task = document.createElement("li");
task.dataset.key = key++;
task.className = "task";
task.innerHTML = toDoElement + "<button>Remove</button>";
task.querySelector("button").addEventListener("click", removeItem);
ul.appendChild(task);
span.innerHTML = toDoList.length;
});
else {
const searchText = e.target.value.toLowerCase();
let result = toDoList.filter(
li => li.toLowerCase().includes(searchText)
);
console.clear();
console.log("Search:", searchText);
console.log("ToDoList:", toDoList);
console.log("Results:", result);
}
}
button.addEventListener("click", addItem);
search.addEventListener("input", searchList);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>toDoList</title>
</head>
<body>
<form>
<input type="text" class="add">
<button>Add task</button>
</form>
<br>
<form>
<label for="search_input">Search</label><br>
<input id="search_input" type="text" class="search">
</form>
<h1>Num tasks: <span>0</span></h1>
<ul></ul>
<script src="main.js"></script>
</body>
</html>