Introduction:
Creating a task manager is an excellent way to improve your JavaScript skills. This project allows you to add, edit, delete, and check tasks off a to-do list while dynamically updating the task count. By the end of this tutorial, you will have a fully functional task management app with interactive features.
Things You Will Learn:
- Handling user input with JavaScript
- Dynamically updating DOM elements
- Using event listeners for interactivity
- Managing dynamic elements with JavaScript
Video Tutorial:
Here is the video tutorial for this project. If you like the tutorial subscribe to my YouTube channel. I post new projects based on HTML, CSS and Javascript on my channel regularly.
Project Folder Structure:
Before we start coding we take a look at the project folder structure. We start by creating a folder called – ‘To do list’. Inside this folder we have 3 files. These files are :
- index.html
- style.css
- script.js
HTML:
We begin with the HTML code. Copy the code below and paste it into your HTML document.
<!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>To Do List New</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" /> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet" /> <link rel="stylesheet" href="style.css" /> </head> <body> <div class="app"> <div class="container"> <div id="wrapper"> <input type="text" placeholder="Task to be done.." /> <button id="add-btn">Add</button> </div> <div id="tasks"> <p id="pending-tasks"> You have <span class="count-value">0</span> task(s) to complete. </p> </div> </div> <p id="error">Input cannot be empty!</p> <script src="script.js"></script> </div> </body> </html>
CSS:
Enhance the visual look by pasting the CSS code below into your stylesheet.
*, *:before, *:after { padding: 0; margin: 0; box-sizing: border-box; } body { height: 100vh; background: linear-gradient(#ffd55c 50%, #5a95ff 50%); } .app { font-family: "Poppins", sans-serif; width: min(95vw, 500px); position: absolute; margin: auto; left: 0; right: 0; top: 30px; } .container { padding: 30px 40px; background-color: #f1f8fb; box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3); border-radius: 0.8em; } #wrapper { position: relative; border-radius: 5px; display: grid; grid-template-columns: 8fr 4fr; gap: 1em; } #wrapper input { width: 100%; font-family: "Poppins", sans-serif; background-color: transparent; color: #111111; font-size: 0.9em; border: none; border-bottom: 2px solid #d1d3d4; padding: 1em 0.5em; } #wrapper input:focus { outline: none; border-color: #5a95ff; } #wrapper button { position: relative; border-radius: 5px; font-family: "Poppins", sans-serif; font-weight: 500; font-size: 1em; background-color: #5a95ff; border: none; color: #ffffff; cursor: pointer; outline: none; } #tasks { margin-top: 1em; border-radius: 10px; width: 100%; position: relative; padding: 1em 0.5em; } .task { background-color: #ffffff; padding: 0.8em 1em; display: grid; grid-template-columns: 1fr 8fr 2fr 2fr; gap: 1em; border-radius: 0.5em; box-shadow: 0 0.5em 1em rgba(0, 0, 0, 0.05); align-items: center; cursor: pointer; } .task:not(:first-child) { margin-top: 1em; } .task input[type="checkbox"] { position: relative; appearance: none; height: 20px; width: 20px; border-radius: 50%; border: 2px solid #e1e1e1; } .task input[type="checkbox"]:before { content: ""; position: absolute; transform: translate(-50%, -50%); top: 50%; left: 50%; } .task input[type="checkbox"]:checked { background-color: #5a95ff; border-color: #5a95ff; } .task input[type="checkbox"]:checked:before { position: absolute; content: "\f00c"; color: #ffffff; font-size: 0.8em; font-family: "Font Awesome 5 Free"; font-weight: 900; } .task span { font-size: 15px; font-weight: 400; word-break: break-all; } .task button { color: #ffffff; width: 100%; padding: 1em 0; border-radius: 5px; border: none; cursor: pointer; outline: none; } .edit { background-color: #5a95ff; } .delete { background-color: #ff5c5c; } #pending-tasks span { color: #5a95ff; } .completed { text-decoration: line-through; color: #a0a0a0; } #error { text-align: center; display: none; background-color: #ffffff; color: #ff5c5c; margin-top: 1.5em; padding: 1em 0; border-radius: 0.5em; }
JS:
Finally, we add functionality using Javascript. For this once again copy the code below and paste it into your script file.
const addBtn = document.querySelector("#add-btn"); const newTaskInput = document.querySelector("#wrapper input"); const tasksContainer = document.querySelector("#tasks"); const error = document.getElementById("error"); const countValue = document.querySelector(".count-value"); let taskCount = 0; const displayCount = (taskCount) => { countValue.innerText = taskCount; }; const addTask = () => { const taskName = newTaskInput.value.trim(); error.style.display = "none"; if (!taskName) { setTimeout(() => { error.style.display = "block"; }, 200); return; } const task = ` <div class="task"> <input type="checkbox" class="task-check"> <span class="taskname">${taskName}</span> <button class="edit"><i class="fas fa-edit"></i></button> <button class="delete"><i class="far fa-trash-alt"></i></button> </div> `; tasksContainer.insertAdjacentHTML("beforeend", task); const deleteButtons = document.querySelectorAll(".delete"); deleteButtons.forEach((button) => { button.onclick = () => { button.parentNode.remove(); taskCount -= 1; displayCount(taskCount); }; }); const editButtons = document.querySelectorAll(".edit"); editButtons.forEach((editBtn) => { editBtn.onclick = (e) => { let targetElement = e.target; if (!(e.target.className == "edit")) { targetElement = e.target.parentElement; } newTaskInput.value = targetElement.previousElementSibling?.innerText; targetElement.parentNode.remove(); taskCount -= 1; displayCount(taskCount); }; }); const tasksCheck = document.querySelectorAll(".task-check"); tasksCheck.forEach((checkBox) => { checkBox.onchange = () => { checkBox.nextElementSibling.classList.toggle("completed"); if (checkBox.checked) { taskCount -= 1; console.log("checked"); } else { taskCount += 1; } displayCount(taskCount); }; }); taskCount += 1; displayCount(taskCount); newTaskInput.value = ""; }; addBtn.addEventListener("click", addTask); window.onload = () => { taskCount = 0; displayCount(taskCount); newTaskInput.value = ""; };
Â
Conclusion:
You built a task manager with JavaScript, learning to manage DOM elements dynamically, handle user interactions, and update the interface in real time. Extend this project by adding features like task categorization or local storage to save tasks between sessions. Happy coding!