Project: a to-do list that remembers
Time to build something real with everything you've learned: variables, conditions, functions, arrays, objects, the DOM and events. You'll add a to-do list to your website. And not just any to-do list. This one remembers your tasks, even after you close the browser.
What you'll build
A section on your site where you can:
- Type a task and add it with a button or the enter key
- See all your tasks in a list
- Mark a task as done by clicking a checkbox
- Delete a task
- Close the browser, come back and find your tasks still there
One new thing: localStorage
To remember tasks, you need somewhere to save them. Browsers have a small storage space for every website called localStorage. It keeps data on the visitor's computer, even after the browser is closed.
It only stores strings, so you use the JSON functions from the arrays and objects lesson:
// Save
localStorage.setItem('tasks', JSON.stringify(tasks));
// Load
const saved = localStorage.getItem('tasks');
const tasks = saved ? JSON.parse(saved) : [];getItem returns null if nothing has been saved yet, so the second line says "if there's something saved, parse it, otherwise start with an empty array". That ? : is a short way to write an if and else, called a ternary.
A couple of things to know: localStorage is per browser and per device, so tasks you add on your laptop won't show up on your phone. And visitors can clear it anytime, so it's great for preferences and small personal things, not for anything important.
The HTML
Add a new section to your page:
<section id="todo">
<h2>My to-do list</h2>
<form id="todo-form">
<label for="todo-input">New task</label>
<input id="todo-input" type="text" required>
<button type="submit">Add</button>
</form>
<ul id="todo-list"></ul>
</section>Using a form means the enter key works for free, and required stops empty tasks.
A plan for the code
When you're building something with several parts, it helps to plan before you type. Here's a good structure:
- The data: an array of task objects, like
{ text: 'Buy milk', done: false }, loaded from localStorage - A
save()function that writes the array to localStorage - A
render()function that clears the list on the page and builds it again from the array - Event handlers that change the array, then call
save()andrender()
That last idea is the key to keeping things simple: the array is the truth, and the page is just a picture of it. You never change the list on the page directly. You change the array and redraw. Professional tools like React are built on exactly the same idea.
A starting point
Here's the beginning to get you going. Your job is to finish it:
const form = document.querySelector('#todo-form');
const input = document.querySelector('#todo-input');
const list = document.querySelector('#todo-list');
const saved = localStorage.getItem('tasks');
const tasks = saved ? JSON.parse(saved) : [];
function save() {
localStorage.setItem('tasks', JSON.stringify(tasks));
}
function render() {
list.textContent = '';
tasks.forEach((task, index) => {
const item = document.createElement('li');
item.textContent = task.text;
// TODO: add a checkbox for done and a delete button
list.append(item);
});
}
form.addEventListener('submit', (event) => {
event.preventDefault();
tasks.push({ text: input.value.trim(), done: false });
input.value = '';
save();
render();
});
render();forEach can give you each item's index as a second parameter. You'll need it to know which task a checkbox or delete button belongs to. Removing an item from an array by index looks like this: tasks.splice(index, 1);
Requirements
Your to-do list should:
- Add a task with the button or the enter key, and never add empty tasks
- Show every task in the list
- Let you mark a task as done with a checkbox, and style done tasks differently, for example with a line through them
- Let you delete a task with a button
- Keep all tasks after reloading the page
- Use
textContent, notinnerHTML, for task text - Work with the keyboard, with labels on the input and the checkboxes
Hand in your to-do list. Paste the full contents of your script.js file and the HTML for your to-do section, then answer:
- Explain in your own words what your render function does and why it clears the list first
- What was the hardest bug you ran into, and how did you find it?
- Bonus: what would you add next to make the list better?
Your to-do list is complete when the code adds tasks on submit with preventDefault and ignores empty input, shows each task with a checkbox that marks it done and a delete button, saves the array to localStorage with JSON.stringify and loads it with JSON.parse when the page opens, uses textContent for task text and has a label for the text input. The feedback will explain anything that's missing and suggest one improvement to your code.
Resources:
- Tasks disappearing on reload? Check that save() is called after every change. See "Arrays and objects" for JSON.
- Page reloading when you add a task? You need event.preventDefault() in the submit handler. See "Events: reacting to clicks and typing".
- Not sure how to build elements in a loop? See "The DOM: changing the page with code".
Upload your solution
Log in to submit this assignment.