Project: A Homework List

Project: A Homework List

Combine a form, array state and DOM rendering into a homework list. Treat the list data as the source of truth, then render text safely after each update.

Before this topic, review Display Untrusted Text Safely if its terms are unfamiliar.

What you’ll learn

  • Explain project: a homework list through the school example.
  • Trace the shown operations and distinguish their result from displayed output.
  • Make the practice change and explain its consequence: Submission stores and displays the edited homework text.

Work through the school example

This is JavaScript in a browser. Read the initial values, then follow each operation to its displayed result. A declaration names a value, a function call performs an operation, and console.log displays its arguments.

Create this markup in a separate index.html, then place the JavaScript in a script after these elements. Use this isolated practice page so the selectors refer to its markup.

<form id="add"><label>Homework <input name="task" value="Read chapter 2"></label><button>Add</button></form><ul id="tasks"></ul>

JavaScript · browser · complete script for the supplied markup

const tasks = [];
const form = document.querySelector("#add");
form.addEventListener("submit", (event) => {
  event.preventDefault();
  const text = form.elements.task.value.trim();
  if (!text) return;
  tasks.push(text);
  const item = document.createElement("li");
  item.textContent = text;
  document.querySelector("#tasks").append(item);
  form.reset();
});
form.requestSubmit();
console.log(tasks.length);
console.log(tasks[0]);

Expected output

1
Read chapter 2

Overview

In this project, you will build a console-based To-Do List App using pure JavaScript. This app will allow users to add tasks, list them, mark them as done, and delete tasks — all from the console (browser or Node.js).

Why This Project?

  • Strengthens your understanding of arrays and objects
  • Practices modular code writing
  • Introduces real-world task state management

Step-by-Step Implementation

Step 1: Define the Task List Structure

We start by defining an empty array that will hold all our tasks. Each task will be an object with id, description, and completed status.

let tasks = [];
let taskId = 1;

Step 2: Add a Task

This function adds a new task to the list with a unique ID.

function addTask(description) {
  tasks.push({ id: taskId++, description, completed: false });
  console.log("Task added successfully.");
}
addTask("Buy groceries");
addTask("Finish JavaScript course");

Q: What happens if I add two tasks with the same description?

A: That’s allowed. Each task has a unique id to differentiate them.

Step 3: View All Tasks

This function lists all tasks in a readable format.

function listTasks() {
  if (tasks.length === 0) {
    console.log("No tasks found.");
    return;
  }
  tasks.forEach(task => {
    console.log(`[${task.completed ? "x" : " "}] ${task.id}: ${task.description}`);
  });
}
[x] 1: Buy groceries
[ ] 2: Finish JavaScript course

Step 4: Mark a Task as Completed

This function changes the completed status of a task by ID.

function completeTask(id) {
  const task = tasks.find(t => t.id === id);
  if (task) {
    task.completed = true;
    console.log(`Task ${id} marked as completed.`);
  } else {
    console.log("Task not found.");
  }
}

Q: What if I enter an invalid ID?

A: The function will simply tell you "Task not found."

Step 5: Delete a Task

This function removes a task by its ID using filter().

function deleteTask(id) {
  const initialLength = tasks.length;
  tasks = tasks.filter(task => task.id !== id);
  if (tasks.length < initialLength) {
    console.log(`Task ${id} deleted.`);
  } else {
    console.log("Task not found.");
  }
}
deleteTask(1);

Step 6: Clear All Completed Tasks

This is a bonus feature to remove tasks that are already marked as done.

function clearCompleted() {
  const cleared = tasks.filter(t => t.completed);
  tasks = tasks.filter(t => !t.completed);
  console.log(`${cleared.length} completed task(s) removed.`);
}

Full Example: Run in Browser Console or Node.js

// Initialize task list
let tasks = [];
let taskId = 1;

function addTask(description) {
  tasks.push({ id: taskId++, description, completed: false });
  console.log("Task added successfully.");
}

function listTasks() {
  if (tasks.length === 0) {
    console.log("No tasks found.");
    return;
  }
  tasks.forEach(task => {
    console.log(`[${task.completed ? "x" : " "}] ${task.id}: ${task.description}`);
  });
}

function completeTask(id) {
  const task = tasks.find(t => t.id === id);
  if (task) {
    task.completed = true;
    console.log(`Task ${id} marked as completed.`);
  } else {
    console.log("Task not found.");
  }
}

function deleteTask(id) {
  const initialLength = tasks.length;
  tasks = tasks.filter(task => task.id !== id);
  if (tasks.length < initialLength) {
    console.log(`Task ${id} deleted.`);
  } else {
    console.log("Task not found.");
  }
}

function clearCompleted() {
  const cleared = tasks.filter(t => t.completed);
  tasks = tasks.filter(t => !t.completed);
  console.log(`${cleared.length} completed task(s) removed.`);
}

Conclusion

This To-Do List App is a solid first project to apply your JavaScript basics in a meaningful way. It teaches you how to manage dynamic data, use common array methods like push(), find(), and filter(), and interact with logic-driven functions.

Try It Yourself

  • Add priority to tasks
  • Implement due dates
  • Save tasks in localStorage (if using in browser)

Recognize the important boundary

This first version demonstrates adding a task. The preserved project sections cover removal; extend the state and rendering together instead of updating only the visible DOM.

Apply form-input validation and safe text insertion when accepting homework typed by a student.

Try a small variation

JavaScript · original source for practice

const tasks = [];
const form = document.querySelector("#add");
form.addEventListener("submit", (event) => {
  event.preventDefault();
  const text = form.elements.task.value.trim();
  if (!text) return;
  tasks.push(text);
  const item = document.createElement("li");
  item.textContent = text;
  document.querySelector("#tasks").append(item);
  form.reset();
});
form.requestSubmit();
console.log(tasks.length);
console.log(tasks[0]);

Your task: Replace Read chapter 2 with Finish maths. Predict the result before running the edited program.

The source is repeated here. If the edit targets the HTML rather than the script, use the markup repeated below; the worked answer also repeats the changed markup.

Markup used by this section:

<form id="add"><label>Homework <input name="task" value="Read chapter 2"></label><button>Add</button></form><ul id="tasks"></ul>

Worked answer and reasoning

Submission stores and displays the edited homework text.

Markup for this edited program:

<form id="add"><label>Homework <input name="task" value="Finish maths"></label><button>Add</button></form><ul id="tasks"></ul>

JavaScript · complete worked variation

const tasks = [];
const form = document.querySelector("#add");
form.addEventListener("submit", (event) => {
  event.preventDefault();
  const text = form.elements.task.value.trim();
  if (!text) return;
  tasks.push(text);
  const item = document.createElement("li");
  item.textContent = text;
  document.querySelector("#tasks").append(item);
  form.reset();
});
form.requestSubmit();
console.log(tasks.length);
console.log(tasks[0]);

Expected output

1
Finish maths

Predict the original program

JavaScript · original program for this question

const tasks = [];
const form = document.querySelector("#add");
form.addEventListener("submit", (event) => {
  event.preventDefault();
  const text = form.elements.task.value.trim();
  if (!text) return;
  tasks.push(text);
  const item = document.createElement("li");
  item.textContent = text;
  document.querySelector("#tasks").append(item);
  form.reset();
});
form.requestSubmit();
console.log(tasks.length);
console.log(tasks[0]);

Markup used by this section:

<form id="add"><label>Homework <input name="task" value="Read chapter 2"></label><button>Add</button></form><ul id="tasks"></ul>
In the browser, what does the original JavaScript example display, in order?
Choose one answer. You can try again.

Answer and explanation

1 → Read chapter 2

Combine a form, array state and DOM rendering into a homework list. Treat the list data as the source of truth, then render text safely after each update. This first version demonstrates adding a task. The preserved project sections cover removal; extend the state and rendering together instead of updating only the visible DOM.

Keep the useful idea

Combine a form, array state and DOM rendering into a homework list. Treat the list data as the source of truth, then render text safely after each update.

Check your variation against this explanation: Submission stores and displays the edited homework text.

Use the JavaScript array reference library for individual array operations and boundary tests to check a rule independently.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Project: A School Weather Report →