i'm making a to do list with only javascript and css. When i add the task, it creates an article with a h1 and 2 icons. The check icon and delete icon. When i click the check icon, it add the class that changes the text style to line-through. The problem is that it's applying to all h1, and i want it to apply only to one specific h1.
function TaskName() {
window.taskName = {};
window.taskName.handdleClick = () => {
const $Task = document.querySelectorAll("h1");
$Task.forEach((e) => {
e.classList.toggle("task-check");
};
window.taskName.delete = () => {
ItemRemoval();
};
let $Input = document.getElementById("input-item");
let $task = $Input.value;
return /*html*/ `
<article id='task-article'>
<h1 id='task-name'>${$task}</h1>
<img src='images/check 1.png' alt='Completar tarefa' onclick='taskName.handdleClick()' id='check-icon'>
<img src='images/delete.svg' alt='Deletar tarefa' onclick='taskName.delete()' id='delete-icon'>
</article>
`;
}
Your problem starts at the structure of your code:
TaskName that does a lot of things: creating HTML, deleting something from somewhere, handling a click eventwindow) to handle thingsWhat do you need, if you want a Todo app?
Todo to the list of todosTodo item from the list of todosTodo item to done (OK, usually toggle between done and not done)Here's a snippet that does this:
// list of todos & list manipulation functions
let todos = []
const addTodo = (newTodo, todos) => [...todos, newTodo]
const removeTodo = (idToRemove, todos) => todos.filter(({ id }) => idToRemove != id)
const toggleTodoDone = (idToToggle, todos) => todos.map(({ id, done, ...rest }) => id == idToToggle ? { id, done: !done, ...rest } : { id, done, ...rest })
const getTodoItem = (label) => ({
id: Date.now(),
done: false,
label,
})
// DOM manipulation & event handling
const input = document.getElementById("input-add-todo")
const btnAdd = document.getElementById("btn-add-todo")
const container = document.getElementById("container")
const resetInput = () => input.value = ''
btnAdd.addEventListener('click', function() {
const label = input.value
if (label) {
const newTodo = getTodoItem(label)
todos = addTodo(newTodo, todos)
updateContainer(container, todos)
resetInput()
}
})
const getTodoHtml = (todo) => {
const doneClass = todo.done ? ' done' : ''
return `
<div
class="todo-item${doneClass}"
data-id="${todo.id}"
>
${todo.label} - ${todo.done}
<button class="remove-todo" data-id="${todo.id}">X</button>
</div>
`
}
const getTodoListHtml = (todos) => todos.map(getTodoHtml).join('')
const registerEventHandlers = (container) => {
const els = document.querySelectorAll('.todo-item')
els.forEach(el => el.addEventListener('click', function() {
const id = el.dataset.id
todos = toggleTodoDone(id, todos)
updateContainer(container, todos)
}))
const btns = document.querySelectorAll('.remove-todo')
btns.forEach(btn => btn.addEventListener('click', function(e) {
e.stopPropagation()
const id = btn.dataset.id
todos = removeTodo(id, todos)
updateContainer(container, todos)
}))
}
const updateContainer = (container, todos) => {
container.innerHTML = getTodoListHtml(todos)
registerEventHandlers(container)
}
.todo-item {
cursor: pointer;
}
.todo-item.done {
text-decoration: line-through;
}
<div>
<input type="text" id="input-add-todo" />
<button id="btn-add-todo">ADD TODO</button>
</div>
<div id="container"></div>