Skip to content
Snippets Groups Projects

Adding toDo app functionability

Merged Jesus Galaz Reyes requested to merge 2-build-javascript-core-functionality into main
Files
2
+ 161
2
// Obtener referencia a los elementos del DOM
// Get reference to DOM elements
const taskList = document.querySelector('.task-list ul');
const newTaskForm = document.querySelector('form');
@@ -14,4 +14,163 @@ document.getElementById('logout-btn').addEventListener('click', async () => {
} catch (err) {
console.error('Error during logout:', err);
}
});
\ No newline at end of file
});
// Function to check if the currently processed task belongs to user account
async function isValidTask(taskId) {
try {
const res = await fetch("/api/todos");
const todos = await res.json();
let valid = false;
todos.forEach(todo => {
if (todo._id == taskId)
valid = true;
});
return valid;
} catch (err) {
console.error("Error loading tasks:", err);
}
}
// Load every task when the page is initialzed
document.addEventListener('DOMContentLoaded', async () => {
try {
const res = await fetch('/api/todos');
const todos = await res.json();
renderTasks(todos);
} catch (err) {
console.error('Error loading tasks:', err);
}
});
// Function to render tasks in the DOM
function renderTasks(todos) {
taskList.innerHTML = '';
todos.forEach(todo => {
const taskItem = createTaskElement(todo);
taskList.appendChild(taskItem);
});
}
// Create an element in the DOM
function createTaskElement(todo) {
const li = document.createElement('li');
li.className = 'task';
li.dataset.id = todo._id;
if (todo.isDone) {
li.classList.add('completed');
}
li.innerHTML = `
<p>${todo.description}</p>
<div class="task-actions">
<button class="hide-btn" data-id="${todo._id}">Done</button>
<button class="edit-btn" data-id="${todo._id}">Edit</button>
<button class="delete-btn" data-id="${todo._id}">Delete</button>
</div>
`;
// Button Button assigns
li.querySelector('.hide-btn').addEventListener('click', () => markAsDone(todo._id, todo.isDone));
li.querySelector('.delete-btn').addEventListener('click', () => deleteTask(todo._id));
li.querySelector('.edit-btn').addEventListener('click', () => editTask(todo));
return li;
}
// Add new task
newTaskForm.addEventListener('submit', async (e) => {
e.preventDefault();
const input = newTaskForm.querySelector('input[name="task"]');
const description = input.value.trim();
if (description === '') return;
try {
const res = await fetch('/api/todos', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ description })
});
const newTodo = await res.json();
taskList.appendChild(createTaskElement(newTodo));
input.value = ''; // Clear input field
} catch (err) {
console.error('Error adding task:', err);
}
});
// Mark task as completed
async function markAsDone(taskId, isDone) {
// Input sanitation
if (isNaN(parseInt(taskId, 10)) && typeof(isDone) === 'boolean' && isValidTask(taskId)) {
console.error('Invalid task ID, task status is invalid or task does not belong to account');
return;
}
try {
const res = await fetch(`/api/todos/${taskId}/done`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ isDone: !isDone })
});
if (res.ok) {
const taskElement = document.querySelector(`li[data-id="${taskId}"]`);
taskElement.classList.toggle('completed');
}
} catch (err) {
console.error('Error marking task as done:', err);
}
}
// Erase task
async function deleteTask(taskId) {
// Input sanitation
if (isNaN(parseInt(taskId, 10))) {
console.error('Invalid task ID');
return;
}
try {
const res = await fetch(`/api/todos/${taskId}`, {
method: 'DELETE'
});
if (res.ok) {
const taskElement = document.querySelector(`li[data-id="${taskId}"]`);
taskElement.remove();
} else {
console.error('Failed to delete task from server');
}
} catch (err) {
console.error('Error deleting task:', err);
}
}
// Edit task
async function updateTask(taskId, newDescription) {
// Input sanitation
if (isNaN(parseInt(taskId, 10)) && typeof(newDescription) === 'string' && isValidTask(taskId)) {
console.error('Invalid task ID, task status is invalid or task does not belong to account');
return;
}
try {
const res = await fetch(`/api/todos/${taskId}/description`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ description: newDescription })
});
if (res.ok) {
const updatedTask = await res.json();
const taskElement = document.querySelector(`li[data-id="${taskId}"]`);
taskElement.querySelector('p').textContent = updatedTask.todo.description;
}
} catch (err) {
console.error('Error updating task:', err);
}
}
Loading