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

  1. Save your HTML as index.html and JavaScript as app.js.
  2. Open the index.html file in your browser.
  3. Test the application by:
    • Adding tasks.
    • Marking tasks as completed.
    • Deleting tasks.

6. Additional Features (Optional)

Enhance your to-do list with these features:

  1. Persist Tasks: Save tasks to localStorage so they persist when the page is refreshed.
  2. Edit Tasks: Add an "Edit" button to allow users to update a task.
  3. 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);