Hey Devs! π
I recently created a robust ToβDo List app using only HTML, CSS, and Vanilla JavaScript. It turned out to be one of the most satisfying ways to solidify DOM skills and understand localStorage
deeply.
π Part of My Learning Journey: Learning Curve Showcase
π Live Demo
π§ What I Wanted to Practice
This project was part of my hands-on DOM journey. My aim was to get practical experience with:
- Selecting and manipulating DOM elements
- Handling user input and interactions
- Creating an editable task system
- Saving user data with
localStorage
- Building CRUD functionality without any libraries
π‘ Key Features
- β Add Task (using button or Enter key)
- βοΈ Edit Task inline with contentEditable
- β Mark Task as Done with a checkbox
- β Delete Individual Task
- π§Ή Clear All Tasks in one click
- πΎ Auto-Save with
localStorage
This makes the app fully functional and persistent even after refreshing the page.
π Behind the Scenes: The JavaScript
Hereβs how I built the features step by step:
π DOM Selection
const input = document.getElementById('task-input');
const addBtn = document.getElementById('add-btn');
const clearBtn = document.getElementById('clear-btn');
const list = document.getElementById('task-list');
ποΈ Creating & Adding New Tasks
function addTask(text, done = false) {
const li = document.createElement('li');
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = done;
const span = document.createElement('span');
span.textContent = text;
span.contentEditable = true;
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Γ';
li.append(checkbox, span, deleteBtn);
list.appendChild(li);
updateLocalStorage();
}
βοΈ Enable Inline Editing
span.addEventListener('input', () => {
updateLocalStorage();
});
βοΈ Marking Task as Done
checkbox.addEventListener('change', () => {
span.classList.toggle('completed', checkbox.checked);
updateLocalStorage();
});
β Delete Button and Clear All
deleteBtn.addEventListener('click', () => {
li.remove();
updateLocalStorage();
});
clearBtn.addEventListener('click', () => {
list.innerHTML = '';
localStorage.removeItem('tasks');
});
πΎ Saving and Loading with localStorage
function updateLocalStorage() {
const tasks = [];
list.querySelectorAll('li').forEach(li => {
const text = li.querySelector('span').textContent;
const done = li.querySelector('input[type="checkbox"]').checked;
tasks.push({ text, done });
});
localStorage.setItem('tasks', JSON.stringify(tasks));
}
window.addEventListener('DOMContentLoaded', () => {
const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
tasks.forEach(task => addTask(task.text, task.done));
});
π οΈ What Iβd Add Next
- π Add filtering (All, Active, Completed)
- π Optional toast notifications (task saved, deleted)
π§ͺ What I Learned
-
contentEditable
makes editing simple and intuitive - Even a small project teaches DOM, events, and storage
- Clean structure helps scalability
- Pure JS is still powerful without React or frameworks
π Try It Out
π Live Demo
π Source Code on GitHub
Thanks for reading! Feel free to drop your thoughts or suggestions.
β Mohit Sharma
Top comments (0)