Beginner JavaScript project: a to-do list in 4 steps
Your goal: add a task, mark it as done and remove it. Separate data from rendering, test each behavior and keep a file that runs in a browser. Prerequisites: variables, functions, arrays and basic HTML elements.
Published by Projet Carthage · Updated
Try the finished project
This preview and its downloadable source work without an account, installation or external service.
Open the downloaded file in your browser. To edit it, use a text editor. The task list intentionally resets on reload.
Concepts & Theory
1. Model the data. A task is an object with id, title and done. The tasks array contains every task. Its identifier stays stable after deletion: using the array position as identity would target the wrong item after reordering.
2. Add without accepting empty input. addTask trims the title, rejects empty titles or reused identifiers, then returns a new array. Outside spaces disappear while the task text stays intact. Before building the interface, test this function with an empty list and the title ‘ Read the lesson ’.
3. Complete and remove. toggleTask uses map to copy the array and invert done only for the target task. removeTask uses filter to keep the other tasks. A missing identifier must not remove another task. These three functions never mutate their input arrays.
4. Connect the interactions. The form listens for submit and calls preventDefault to avoid reloading. A checkbox calls toggleTask; a button calls removeTask. After each change, render rebuilds the list and counter from tasks. Data determines the display instead of a separately maintained counter.
Display input as text. The complete file uses textContent for titles and createElement for elements. A task containing <b>Read</b> must display those characters instead of creating an HTML element. This prevents input from being interpreted as markup.
Check behavior before adding features. Try empty input, two different tasks, two identically named tasks, checking and unchecking, and deletion. Identifiers distinguish duplicate titles. The counter must always match unfinished tasks. Reloading intentionally resets the demonstration; it does not promise permanent storage.
Consolidate your understanding: add a ‘To do’ filter, then write the test proving that hiding completed tasks does not delete them. Once the distinction is clear, MAX projects introduce more constraints, cumulative stages and server-side tests.
Code Example
Try this examplefunction addTask(tasks, title, id) {
const clean = title.trim();
if (!clean || tasks.some(task => task.id === id)) return tasks;
return [...tasks, { id, title: clean, done: false }];
}
function toggleTask(tasks, id) {
return tasks.map(task =>
task.id === id ? { ...task, done: !task.done } : task
);
}
function removeTask(tasks, id) {
return tasks.filter(task => task.id !== id);
}
const first = addTask([], " Lire ", 1);
const done = toggleTask(first, 1);
console.log(first[0].title); // Lire
console.log(first[0].done); // false
console.log(done[0].done); // true
console.log(removeTask(done, 1).length); // 0Documentation used to check the concepts
Common Pitfalls & Mistakes
✗ Deleting the wrong item
tasks.splice(tasks.findIndex(task => task.id === id), 1);const remaining = tasks.filter(task => task.id !== id);findIndex returns -1 when no task matches. splice(-1, 1) would delete the last task and mutate the original array. filter directly states what should remain.
✗ Confusing title and identity
tasks.filter(task => task.title !== title);tasks.filter(task => task.id !== id);Two tasks may have identical titles. Removing by identifier deletes only the intended one.
Frequently Asked Questions
Do I need React or Node.js?▾
No. The downloadable HTML file includes its styles and JavaScript. Open it in a recent browser. Neither React nor Node.js is required.
Does this project require MAX?▾
No. The guide, demo and source file are free without an account. MAX projects are separate tracks with saved work, cumulative stages and evaluation.
Do tasks survive a reload?▾
No, this first project stores data in memory. Persistence using localStorage is a possible extension, including invalid data and storage error handling.
Master JavaScript with interactive exercises
Complete hands-on code challenges in your browser with real-time feedback and progressive hints.
