Build a Todo List Website
Introduction
Hello, developers! I'm thrilled to introduce my latest project: a Todo List application. This project is perfect for anyone looking to improve their JavaScript skills by working on a practical and widely-used tool. Whether you're just starting out or looking to refine your skills, building a Todo List is a great way to learn about handling user input, managing data, and dynamically updating the DOM.
Project Overview
The Todo List application is a simple yet powerful tool that allows users to manage their tasks efficiently. It features an intuitive interface where users can add, edit, and delete tasks, mark them as completed, and filter tasks based on their status. This project is a great way to understand the core concepts of web development, including event handling and data persistence using localStorage.
Features
- User-Friendly Interface: A clean and intuitive design that makes task management easy.
- Add, Edit, and Delete Tasks: Fully functional controls to manage your tasks effectively.
- Mark Tasks as Completed: Easily mark tasks as completed and filter them based on their status.
- Persistent Data: All tasks are stored in localStorage, so your list remains intact even after refreshing the page.
- Responsive Design: The layout is responsive and works seamlessly on both desktop and mobile devices.
Technologies Used
- HTML: Structures the web page and input elements.
- CSS: Styles the interface to provide a user-friendly experience.
- JavaScript: Handles the logic for adding, editing, deleting, and filtering tasks, as well as managing data in localStorage.
Project Structure
Here's a quick overview of the project structure:
Todo-List/ ├── index.html ├── styles.css └── script.js
- index.html: Contains the HTML structure for the Todo List application.
- styles.css: Includes CSS styles to enhance the appearance and responsiveness of the Todo List.
- script.js: Manages the application logic, including task management and localStorage operations.
Installation
To get started with the Todo List project, follow these steps:
-
Clone the repository:
git clone https://github.com/abhishekgurjar-in/Todo-List.git
Copy after login -
Open the project directory:
cd Todo-List
Copy after login -
Run the project:
- Open the index.html file in your web browser to start using the Todo List application.
Usage
- Open the website in a web browser.
- Add a task by typing in the input field and pressing "Enter."
- Edit or delete tasks using the provided options.
- Mark tasks as completed by checking the corresponding checkbox.
- Filter tasks by their status using the filter options at the top of the list.
- Clear all tasks using the "Clear All" button to start fresh.
Code Explanation
HTML
The index.html file provides the structure for the Todo List application, including the input field for adding tasks, buttons for filtering tasks, and a list to display the tasks. Here’s a brief overview:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="https://unicons.iconscout.com/release/v4.0.0/css/line.css" /> <link rel="stylesheet" href="style.css" /> <script src="script.js" defer></script> <title>ToDo</title> </head> <body> <div class="main"> <div id="logo"> <img src="./logo/175e8acd1b69064c1fafe52ed5b12019-removebg-preview.png" alt="" /> </div> <div class="wrapper"> <div class="task-input"> <input type="text" placeholder="Add a new task" /> </div> <div class="controls"> <div class="filters"> <span id="all" class="active">All</span> <span id="pending">Pending</span> <span id="completed">Completed</span> </div> <button class="clear-btn">Clear All</button> </div> <ul class="task-box"></ul> </div> </div> <div class="footer"> <p>Made with ❤️ by Abhishek Gurjar</p> </div> </body> </html>
CSS
The styles.css file styles the Todo List application, ensuring a clean and responsive design. Here are some key styles:
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"); * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Poppins", sans-serif; } body { background: #fff; } .main { min-height: 85vh; } #logo { width: 100%; height: 7vh; display: flex; align-items: bottom; justify-content: center; } img { width: 300px; height: 222px; } ::selection { color: #fff; background: #1e293b; } .wrapper { max-width: 405px; background: #64d1ef; margin: 137px auto; padding: 28px 0 30px; border-radius: 7px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.401); } .task-input { height: 52px; padding: 0 25px; position: relative; } .task-input input { height: 100%; width: 100%; outline: none; font-size: 18px; border-radius: 5px; padding: 0 20px 0 10px; border: 1px solid #7a7a7a; } .task-input input:focus, .task-input input.active { padding-left: 10px; border: 2px solid #1e293b; } .task-input input::placeholder { color: #bfbfbf; } .controls, li { display: flex; align-items: center; justify-content: space-between; } .controls { padding: 18px 25px; border-bottom: 1px solid #000000a4; } .filters span { margin: 0 8px; font-size: 17px; color: #444; cursor: pointer; } .filters span:first-child { margin-left: 0; } .filters span.active { color: #101216; } .controls .clear-btn { border: none; opacity: 0.6; outline: none; color: #fff; cursor: pointer; font-size: 13px; padding: 7px 13px; border-radius: 4px; background: #1e293b; letter-spacing: 0.3px; pointer-events: none; transition: transform 0.25s ease; } .clear-btn.active { opacity: 0.9; pointer-events: auto; } .clear-btn:active { transform: scale(0.93); } .task-box { margin-top: 20px; margin-right: 5px; padding: 0 20px 10px 25px; } .task-box.overflow { overflow-y: auto; max-height: 300px; } .task-box::-webkit-scrollbar { width: 5px; } .task-box::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 25px; } .task-box::-webkit-scrollbar-thumb { background: #e6e6e6; border-radius: 25px; } .task-box .task { list-style: none; font-size: 17px; margin-bottom: 18px; padding-bottom: 16px; align-items: flex-start; border-bottom: 1px solid #2c2a2a; } .task-box .task:last-child { margin-bottom: 0; border-bottom: 0; padding-bottom: 0; } .task-box .task label { display: flex; align-items: flex-start; } .task-box label input { margin-top: 7px; accent-color: #1e293b; } .task-box label p { user-select: none; margin-left: 12px; word-wrap: break-word; } .task label p.checked { text-decoration: line-through; } .task-box .settings { position: relative; } .settings :where(i, li) { cursor: pointer; } .settings .task-menu { z-index: 10; right: -5px; bottom: -65px; padding: 5px 0; background: #fff; position: absolute; border-radius: 4px; transform: scale(0); transform-origin: top right; box-shadow: 0 0 6px rgba(0, 0, 0, 0.15); transition: transform 0.2s ease; } .task-box .task:last-child .task-menu { bottom: 0; transform-origin: bottom right; } .task-box .task:first-child .task-menu { bottom: -65px; transform-origin: top right; } .task-menu.show { transform: scale(1); } .task-menu li { height: 25px; font-size: 16px; margin-bottom: 2px; padding: 17px 15px; cursor: pointer; justify-content: flex-start; } .task-menu li:last-child { margin-bottom: 0; } .settings li:hover { background: #f5f5f5; } .settings li i { padding-right: 8px; } .footer { text-align: center; margin: 40px; } @media (max-width: 400px) { body { padding: 0 10px; } .wrapper { padding: 20px 0; } .filters span { margin: 0 5px; } .task-input { padding: 0 20px; } .controls { padding: 18px 20px; } .task-box { margin-top: 20px; margin-right: 5px; padding: 0 15px 10px 20px; } .task label input { margin-top: 4px; } }
JavaScript
The script.js file contains the logic for adding, editing, deleting, and filtering tasks. Here's an overview of the main functions:
const taskInput = document.querySelector(".task-input input"), filters = document.querySelectorAll(".filters span"), clearAll = document.querySelector(".clear-btn"), taskBox = document.querySelector(".task-box"); let editId, isEditTask = false, todos = JSON.parse(localStorage.getItem("todo-list")); // Filter tasks based on status (all, completed, pending) filters.forEach(btn => { btn.addEventListener("click", () => { document.querySelector("span.active").classList.remove("active"); btn.classList.add("active"); showTodo(btn.id); }); }); function showTodo(filter) { let liTag = ""; if (todos) { todos.forEach((todo, id) => { let completed = todo.status == "completed" ? "checked" : ""; if (filter == todo.status || filter == "all") { liTag += `<li class="task"> <label for="${id}"> <input onclick="updateStatus(this)" type="checkbox" id="${id}" ${completed}> <p class="${completed}">${todo.name}</p> </label> <div class="settings"> <i onclick="showMenu(this)" class="uil uil-ellipsis-h"></i> <ul class="task-menu"> <li onclick='editTask(${id}, "${todo.name}")'><i class="uil uil-pen"></i>Edit</li> <li onclick='deleteTask(${id}, "${filter}")'><i class="uil uil-trash"></i>Delete</li> </ul> </div> </li>`; } }); } taskBox.innerHTML = liTag || `<span>You don't have any task here</span>`; let checkTask = taskBox.querySelectorAll(".task"); !checkTask.length ? clearAll.classList.remove("active") : clearAll.classList.add("active"); taskBox.offsetHeight >= 300 ? taskBox.classList.add("overflow") : taskBox.classList.remove("overflow"); } showTodo("all"); // Show all tasks by default // Function to show the menu for task options function showMenu(selectedTask) { let menuDiv = selectedTask.parentElement.lastElementChild; menuDiv.classList.add("show"); document.addEventListener("click", e => { if (e.target.tagName != "I" || e.target != selectedTask) { menuDiv.classList.remove("show"); } }); } // Function to update the status of a task (completed or pending) function updateStatus(selectedTask) { let taskName = selectedTask.parentElement.lastElementChild; if (selectedTask.checked) { taskName.classList.add("checked"); todos[selectedTask.id].status = "completed"; } else { taskName.classList.remove("checked"); todos[selectedTask.id].status = "pending"; } localStorage.setItem("todo-list", JSON.stringify(todos)); } // Function to edit an existing task function editTask(taskId, textName) { editId = taskId; isEditTask = true; taskInput.value = textName; taskInput.focus(); taskInput.classList.add("active"); } // Function to delete a task function deleteTask(deleteId, filter) { isEditTask = false; todos.splice(deleteId, 1); localStorage.setItem("todo-list", JSON.stringify(todos)); showTodo(filter); } // Clear all tasks clearAll.addEventListener("click", () => { isEditTask = false; todos.splice(0, todos.length); localStorage.setItem("todo-list", JSON.stringify(todos)); showTodo(); }); // Add a new task or update an existing one taskInput.addEventListener("keyup", e => { let userTask = taskInput.value.trim(); if (e.key == "Enter" && userTask) { if (!isEditTask) { todos = !todos ? [] : todos; let taskInfo = { name: userTask, status: "pending" }; todos.push(taskInfo); } else { isEditTask = false; todos[editId].name = userTask; } taskInput.value = ""; localStorage.setItem("todo-list", JSON.stringify(todos)); showTodo(document.querySelector("span.active").id); } });
Live Demo
Check out the live demo of the Todo List application here.
Conclusion
Building this Todo List application was an insightful experience, allowing me to deepen my understanding of JavaScript, DOM manipulation, and data persistence. I hope this project serves as an inspiration for you to create your own task management tools. Happy coding!
Credits
This project was developed as part of my ongoing efforts to master web development, focusing on practical applications that enhance everyday productivity.
Author
-
Abhishek Gurjar
- GitHub Profile
The above is the detailed content of Build a Todo List Website. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











Have you ever needed a countdown timer on a project? For something like that, it might be natural to reach for a plugin, but it’s actually a lot more

Everything you ever wanted to know about data attributes in HTML, CSS, and JavaScript.

At the start of a new project, Sass compilation happens in the blink of an eye. This feels great, especially when it’s paired with Browsersync, which reloads

The inline-template directive allows us to build rich Vue components as a progressive enhancement over existing WordPress markup.

One thing that caught my eye on the list of features for Lea Verou's conic-gradient() polyfill was the last item:

Let’s attempt to coin a term here: "Static Form Provider." You bring your HTML

PHP templating often gets a bad rap for facilitating subpar code — but that doesn't have to be the case. Let’s look at how PHP projects can enforce a basic

Every time I start a new project, I organize the code I’m looking at into three types, or categories if you like. And I think these types can be applied to
