I build my first ToDo App, and its almost done. But i meet some trouble with delete items from list. If i create new task and try delete it, its deleted only from DOM, but if i refresh page i can delete task from local storage and from DOM. Please, explain what i make wrong and how to fix that. Thank you for your attention.
<div >
<ul ></ul>
<form action="">
<label for="task">
<input id="task" type="text" placeholder="Enter new task" maxlength="30">
<input type="submit" value=" ">
</label>
</form>
</div>
const taskList = document.querySelector(".todo_tasks-wrapper");
const formTodo = document.querySelector(".control");
const inputTask = document.querySelector(".todo_input");
const taskKeeper = [];
let taskIdCounter = -1;
const data = JSON.parse(localStorage.getItem("tasks"));
const updateHtml = (taskObj) => {
const newLi = document.createElement("li");
newLi.innerHTML = `<li id="${taskObj.id}" >
<span>${taskObj.task}</span>
<button >
<img src="assets/todo-cancel.png" alt="Cancel">
</button>
</li>`;
taskList.append(newLi);
}
const newTask = (info) => {
taskIdCounter = 1;
const taskObj = {
task: info,
id: taskIdCounter,
};
taskKeeper.push(taskObj);
localStorage.setItem("tasks", JSON.stringify(taskKeeper));
updateHtml(taskObj);
};
formTodo.addEventListener("submit", event => {
event.preventDefault();
const info = inputTask.value.trim();
if(info.length !== 0) {
newTask(info);
inputTask.value = "";
inputTask.focus();
}
});
taskList.addEventListener("click", (event) => {
for (let el of event.composedPath()) {
if (el.matches && el.matches("button.cancel-task")) {
let uniqueId = (el.parentNode.getAttribute("id"));
for (let itemId of data) {
if(itemId.id === uniqueId) {
let getIndex = data.indexOf(itemId);
data.splice(getIndex, 1);
localStorage.setItem("tasks", JSON.stringify(data));
}
}
el.parentNode.remove();
}
}
});
if(data !== null) {
for (let item of data) {
updateHtml(item);
}
}
CodePudding user response:
- Don't use IDs for your tasks. When deleting an element, you can assign a click handler on creation of your
"x"
button. - Your
taskIdCounter
is useless since on page refresh you're starting again from 0. Get rid of it. You know now hot to remove Items from a list - Don't use a
form
if you don't need one. - Use
type="button"
on your BUTTONElements
Here's a remake of your code:
<ul id="tasks-list"></ul>
<div>
<input id="tasks-text" id="task" type="text" placeholder="Enter new task" maxlength="30">
<button id="tasks-add" type="button"> </button>
</div>
JavaScript
// DOM utility functions:
const el = (sel, par) => (par || document).querySelector(sel);
const els = (sel, par) => (par || document).querySelectorAll(sel);
const elNew = (tag, prop) => Object.assign(document.createElement(tag), prop);
// Tasks:
const elList = el("#tasks-list");
const elText = el("#tasks-text");
const elAdd = el("#tasks-add");
const tasks = JSON.parse(localStorage.tasks ?? "[]");
const taskRemove = (taskObj, elTask) => {
const idx = tasks.indexOf(taskObj);
tasks.splice(idx, 1);
localStorage.tasks = JSON.stringify(tasks);
elTask && elTask.remove();
};
const taskAdd = (text) => {
const taskObj = { task: text };
tasks.push(taskObj);
localStorage.tasks = JSON.stringify(tasks);
taskInsert(taskObj);
};
const taskInsert = (taskObj) => {
const elTask = elNew("li", {
className: "item-task",
innerHTML: `<span>${taskObj.task}</span>`
});
const elRemove = elNew("button", {
type: "button",
innerHTML: "×",
onclick() {
taskRemove(taskObj, elTask);
}
});
elTask.append(elRemove);
elList.append(elTask);
};
elAdd.addEventListener("click", () => {
const info = elText.value.trim();
if (!info.length) return;
taskAdd(info);
elText.value = "";
elText.focus();
});
// Init
tasks.forEach(taskInsert);
As you can see, to get the index
of the task to remove, simply pass the original object reference into const idx = tasks.indexOf(item);