Module 12: Mini Project - Interactive To-Do List
Objective: Build an interactive to-do list using everything you've learned: DOM manipulation, events, functions, objects, arrays, and modern ES6 features.
1. Project Overview
We’ll create a simple web-based to-do list application where users can:
- Add tasks.
- Mark tasks as completed.
- Remove tasks.
2. HTML Structure
Create the basic HTML structure.
Example:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>To-Do List</title> <style> body { font-family: Arial, sans-serif; margin: 20px; } .completed { text-decoration: line-through; color: gray; } </style> </head> <body> <h1>To-Do List</h1> <input type="text" id="taskInput" placeholder="Enter a task"> <button id="addTask">Add Task</button> <ul id="taskList"></ul> <script src="app.js"></script> </body> </html>
3. JavaScript Code
In the app.js
file, we’ll write the logic to make the to-do list interactive.
Step 1: Select Elements
Start by selecting the necessary DOM elements.
const taskInput = document.getElementById("taskInput"); const addTaskButton = document.getElementById("addTask"); const taskList = document.getElementById("taskList");
Step 2: Add Tasks
When the user clicks the Add Task button, a new task should appear in the list.
addTaskButton.addEventListener("click", () => { const taskText = taskInput.value.trim(); // Get input value and trim whitespace if (taskText === "") return; // Prevent empty tasks const taskItem = document.createElement("li"); taskItem.textContent = taskText; // Add buttons for completing and deleting tasks const completeButton = document.createElement("button"); completeButton.textContent = "Complete"; completeButton.addEventListener("click", () => { taskItem.classList.toggle("completed"); // Toggle completed style }); const deleteButton = document.createElement("button"); deleteButton.textContent = "Delete"; deleteButton.addEventListener("click", () => { taskList.removeChild(taskItem); // Remove task from list }); // Append buttons to the task item taskItem.appendChild(completeButton); taskItem.appendChild(deleteButton); // Add task to the list taskList.appendChild(taskItem); // Clear the input field taskInput.value = ""; });
Step 3: Handle Task Completion
The completeButton
toggles the completed
class on the task item.
Step 4: Handle Task Deletion
The deleteButton
removes the task item from the list.
4. Full JavaScript Code
Here’s the complete code for app.js
:
const taskInput = document.getElementById("taskInput"); const addTaskButton = document.getElementById("addTask"); const taskList = document.getElementById("taskList"); addTaskButton.addEventListener("click", () => { const taskText = taskInput.value.trim(); if (taskText === "") return; const taskItem = document.createElement("li"); taskItem.textContent = taskText; const completeButton = document.createElement("button"); completeButton.textContent = "Complete"; completeButton.addEventListener("click", () => { taskItem.classList.toggle("completed"); }); const deleteButton = document.createElement("button"); deleteButton.textContent = "Delete"; deleteButton.addEventListener("click", () => { taskList.removeChild(taskItem); }); taskItem.appendChild(completeButton); taskItem.appendChild(deleteButton); taskList.appendChild(taskItem); taskInput.value = ""; });
5. Running the Project
- Save your HTML as
index.html
and JavaScript asapp.js
. - Open the
index.html
file in your browser. - Test the application by:
- Adding tasks.
- Marking tasks as completed.
- Deleting tasks.
6. Additional Features (Optional)
Enhance your to-do list with these features:
- Persist Tasks: Save tasks to
localStorage
so they persist when the page is refreshed. - Edit Tasks: Add an "Edit" button to allow users to update a task.
- Sort Tasks: Sort tasks alphabetically or by completion status.
Example: Persisting Tasks with localStorage
function saveTasks() { const tasks = []; document.querySelectorAll("#taskList li").forEach(taskItem => { tasks.push({ text: taskItem.firstChild.textContent, completed: taskItem.classList.contains("completed") }); }); localStorage.setItem("tasks", JSON.stringify(tasks)); } function loadTasks() { const tasks = JSON.parse(localStorage.getItem("tasks")) || []; tasks.forEach(task => { const taskItem = document.createElement("li"); taskItem.textContent = task.text; if (task.completed) { taskItem.classList.add("completed"); } const completeButton = document.createElement("button"); completeButton.textContent = "Complete"; completeButton.addEventListener("click", () => { taskItem.classList.toggle("completed"); saveTasks(); }); const deleteButton = document.createElement("button"); deleteButton.textContent = "Delete"; deleteButton.addEventListener("click", () => { taskList.removeChild(taskItem); saveTasks(); }); taskItem.appendChild(completeButton); taskItem.appendChild(deleteButton); taskList.appendChild(taskItem); }); } // Load tasks when the page loads loadTasks(); // Save tasks after any update addTaskButton.addEventListener("click", saveTasks);