JavaScript Notes
Learn to build a full-featured todo list app in JavaScript with add, complete, delete, filter, and localStorage persistence. Perfect beginner JS project.
What You'll Learn
- The core state → render pattern used in every JavaScript app
- How to add, complete, and delete items in an array
- How to filter a list (All / Active / Completed)
- How to use event delegation for dynamically created elements
- How to persist data with
localStorageacross reloads
Project Overview
A todo app is the "Hello World" of JavaScript projects. It demonstrates every fundamental pattern: maintaining an array of objects as state, rendering that array to the DOM, and responding to user actions that mutate the array.
Component Structure
How It Works — Flow Diagram
Step-by-Step Build
Step 1 — HTML Structure
<div class="todo-app">
<h1 class="todo-title">My Tasks</h1>
<form class="todo-form" id="todoForm">
<input type="text" id="todoInput" placeholder="Add a new task..." autocomplete="off">
<button type="submit" class="btn-add">+ Add</button>
</form>
<div class="filter-bar">
<button class="filter-btn active" data-filter="all">All</button>
<button class="filter-btn" data-filter="active">Active</button>
<button class="filter-btn" data-filter="completed">Completed</button>
</div>
<ul class="todo-list" id="todoList"></ul>
<footer class="todo-footer">
<span id="itemsLeft"></span>
<button id="clearCompleted">Clear Completed</button>
</footer>
</div>Step 2 — State
Step 3 — Add a Todo
Step 4 — Toggle & Delete
Step 5 — Render Function
Step 6 — Event Delegation
Step 7 — Filter Tabs
Step 8 — Footer & Persistence
Step 9 — Initialize
render(); // render on page load to show persisted todosConsole Output
// Adding "Buy groceries"
addTodo("Buy groceries")
todos = [{ id: 1749686400000, text: "Buy groceries", completed: false }]
render() → 1 <li> item in list, "1 item left"
// Checking it off
toggleTodo(1749686400000)
todos[0].completed = true
render() → <li class="todo-item completed">, "0 items left"
// Switching to "Active" filter
currentFilter = "active"
render() → getFilteredTodos() returns [] → shows "No tasks to show"
// Adding another task
addTodo("Write code review")
todos.length = 2, 1 active
render() → "Write code review" visible in "Active" filterEdge Cases to Handle
| Situation | Expected Behavior |
|---|---|
| Empty input | trim() check — don't add blank tasks |
| Duplicate text | Allowed (same text, different IDs) |
| XSS in task text | Escape HTML before injecting |
| All completed | "0 items left" shown |
| Clear Completed when none | Button is a no-op, no errors |
Challenge Yourself
- Drag-to-reorder — implement drag-and-drop sorting of tasks
- Due dates — add a date picker to each task and highlight overdue items
- Priority levels — add Low / Medium / High priority with color coding
- Edit task — double-click a task text to edit it in-place
- Search bar — add a search input that filters tasks by keyword
Best Practices
- Always call
render()once at startup to hydrate fromlocalStorage - Use event delegation on the list — never attach listeners to each
<li> - Sanitize user input before inserting it into
innerHTML - Keep
saveTodos()andrender()as the final two lines of every mutation function - Use
Date.now()for IDs in simple projects,crypto.randomUUID()in production
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Build a Todo App in JavaScript - Step by Step Project Tutorial.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this JavaScript Master Course topic.
Search Terms
javascript-complete-guide, javascript master course, javascript, complete, guide, mini, projects, todo
Related JavaScript Master Course Topics