Building an Enhanced To-Do List App Using HTML, CSS, and JavaScript with Local Storage
In this tutorial, we'll create an enhanced To-Do list app using HTML, CSS, and JavaScript, incorporating local storage to save our tasks. This project is perfect for beginners looking to improve their web development skills.
What You Will Learn
- Creating a basic To-Do list interface
- Adding, editing, and deleting tasks
- Saving tasks to local storage
- Styling the application with CSS
Your Folder Structure
Your project folder should look like this:
enhanced-todo-app/
├── index.html
├── style.css
├── script.js
└── images/
├── delete.svg
└── editbutton.svg
GitHub Repository
For the complete source code, you can check out the GitHub repository: Enhanced To-Do List App Source Code.
Step 1: HTML Structure
We'll start with the basic HTML structure for our To-Do list app. Create an HTML file named index.html
and add the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Enhanced To-Do List App</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>To-Do List</h1>
<input type="text" placeholder="Enter a new Task" id="input-task">
<button id="add-task">Add Task</button>
<ul id="tasks-list"></ul>
</div>
<script src="script.js"></script>
</body>
</html>
Step 2: CSS Styling
Next, create a CSS file named style.css
to style our application:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
display: flex;
align-items: center;
justify-content: center;
background-color: black;
}
.container {
width: 500px;
background-color: grey;
margin-top: 10vh;
padding: 30px;
color: white;
border-radius: 30px;
}
.container h1 {
font-size: 60px;
color: rgb(0, 0, 0);
text-align: center;
margin-bottom: 20px;
}
#input-task {
padding: 20px;
border-radius: 50px;
width: 70%;
font-size: 18px;
border: none;
outline: none;
}
#input-task:focus {
outline: 2px solid green;
}
#add-task {
padding: 20px;
border-radius: 50px;
border: none;
font-size: 18px;
background-color: green;
color: white;
font-weight: bold;
cursor: pointer;
}
#tasks-list {
font-size: 18px;
}
ul li {
position: relative;
margin-top: 22px;
list-style-type: none;
background-color: rgb(46, 46, 49);
padding: 20px 40px;
border-radius: 50px;
display: flex;
align-items: center;
}
.completed {
text-decoration: line-through;
color: rgb(180, 175, 175);
}
Step 3: JavaScript Functionality
Create a JavaScript file named script.js
and add the following code to handle task addition, editing, and deletion:
let input = document.getElementById("input-task");
let add = document.getElementById("add-task");
let taskList = document.getElementById("tasks-list");
input.addEventListener('keypress', (e) => {
if (e.key === "Enter") {
add.click();
}
});
// Add task to task list when add task button is clicked
add.addEventListener('click', () => {
let inputText = input.value.trim();
if (inputText === "") {
alert("Please Enter a Task");
} else {
addTaskToList(inputText, false); // New tasks are not completed by default
saveTasks();
}
input.value = "";
});
addTaskToList=(inputText, isCompleted = false)=> {
let li = document.createElement("li");
let span = document.createElement("span");
span.textContent = inputText;
if (isCompleted) {
span.classList.add("completed");
}
// Toggle completed class when clicked
span.addEventListener('click', () => {
span.classList.toggle("completed");
saveTasks();
});
// Delete button
let deleteButton = document.createElement("img");
deleteButton.src = "images/delete.svg";
deleteButton.addEventListener('click', () => {
li.remove();
saveTasks();
});
// Edit button
let editButton = document.createElement("img");
editButton.src = "images/editbutton.svg";
editButton.addEventListener('click', () => {
let div = document.createElement("div");
div.classList = "editbox";
let textarea = document.createElement("input");
textarea.value = span.textContent;
textarea.addEventListener('keypress', (e) => {
if (e.key === "Enter") {
updateButton.click();
}
});
let updateButton = document.createElement("button");
updateButton.innerHTML = "Update";
updateButton.id = "update-task";
updateButton.addEventListener('click', () => {
span.textContent = textarea.value;
div.remove();
saveTasks();
});
div.appendChild(textarea);
div.appendChild(updateButton);
li.appendChild(div);
});
li.appendChild(span);
li.appendChild(editButton);
li.appendChild(deleteButton);
taskList.appendChild(li);
}
// Save tasks to local storage with completion status
function saveTasks() {
const tasks = [];
document.querySelectorAll("#tasks-list li").forEach((task) => {
tasks.push({
text: task.querySelector("span").textContent,
completed: task.querySelector("span").classList.contains("completed")
});
});
localStorage.setItem("tasks", JSON.stringify(tasks));
}
// Load tasks from local storage with completion status
function loadTasks() {
const tasks = JSON.parse(localStorage.getItem("tasks")) || [];
tasks.forEach((task) => addTaskToList(task.text, task.completed));
}
// Initial load
loadTasks();
Step 4: Testing Your App
Once you've set up all the files, open index.html
in your browser. You should be able to add tasks, mark them as complete, edit them, and delete them. Your tasks will be saved even when you refresh the page!
JavaScript Functionality Explained
The JavaScript code behind the Enhanced To-Do List App provides the interactive functionality that allows users to manage their tasks effectively. Here’s a breakdown of the key components:
1. Event Listeners
The app uses event listeners to handle user interactions:
- Enter Key Press: The app listens for the "Enter" key press on the task input field. When detected, it triggers the same function as clicking the "Add Task" button, allowing users to add tasks quickly.
- Add Task Button: When the user clicks the "Add Task" button, the app retrieves the text from the input field, validates it, and adds it to the task list.
2. Adding Tasks
The function addTaskToList
creates a new list item for each task. It takes two parameters: the task text and its completion status. Inside this function:
- A new
li
element is created to represent the task. - A
span
element is used to display the task text, and it is styled to show completion status when clicked. - Buttons for editing and deleting the task are also created and appended to the list item.
3. Editing and Deleting Tasks
The app allows users to edit or delete tasks:
- Edit Functionality: Clicking the edit button creates an input field pre-filled with the current task text, allowing users to make changes. An "Update" button saves the changes.
- Delete Functionality: The delete button removes the task from the list entirely.
4. Completing Tasks
When a user clicks on a task's text, it toggles the "completed" class, which visually indicates that the task is done by applying a strikethrough effect.
5. Local Storage
To ensure task persistence, the app uses the browser's local storage:
- The
saveTasks
function collects all tasks and their completion statuses, storing them as a JSON string in local storage. - The
loadTasks
function retrieves tasks from local storage upon app initialization, ensuring users see their saved tasks when they revisit the app.
This robust use of JavaScript not only enhances user experience but also makes the app fully functional and reliable for task management.
Conclusion
Congratulations! You've successfully built an enhanced To-Do list application. This project not only helps you practice your HTML, CSS, and JavaScript skills but also gives you a practical tool to manage your tasks. Keep experimenting with new features and improve your coding skills further!