How To Build a Todo List App Using HTML, CSS, and JavaScript
Tags: javascript, webdev, beginners, programming
Published: 2023-11-13 06:19:00

## Overview:
**Welcome to our JavaScript Todo List App Coding Tutorials.**

In this article, we'll walk you through a step-by-step guide to building a fully functional to-do list application from scratch using **HTML**, **CSS**, and, of course, **JavaScript**.

You'll learn how to implement essential **CRUD** Operations (Create, Read, Update, and Delete) to manage your tasks effectively. This will include functionalities like reading data from the list, adding tasks, marking them as completed, editing existing tasks, and removing tasks from the list and we have a cool 😍 animation for the above operations.

💫 Watch Live Preview 👉 [Todo List App](https://youtu.be/oMt3U1zfoe0)

Throughout this video, we'll cover key concepts such as DOM manipulation, event handling, and local storage integration, enabling you to save and retrieve your tasks seamlessly.

📝 Todo App with Local Storage using JavaScript 👇
{% embed https://youtu.be/oMt3U1zfoe0 %}
By the end of this video, you'll have a powerful To-Do list app that you can customize and use for your daily task management effortlessly.

## Important Note:
`In the Todo App tutorial, we have stored our data list in local storage. The localStorage object allows you to save key/value pairs in the browser. The data is not deleted when the browser is closed/refreshed and is available for future sessions.
`

Let's get started on creating your own JavaScript-powered to-do list app now! HAPPY CODING!

**You might like this:** [How should a beginner start programming?](https://dev.to/sharathchandark/how-should-a-beginner-start-programming-3hom)

## Introduction:
Todo list apps are a fantastic way to boost productivity are a great way to stay organized and manage your tasks effectively. In this quick guide, we'll walk you through the steps to create your very own todo list app

## Prerequisites:
Basic knowledge of HTML, CSS, and JavaScript.
A code editor of your choice.

**Step 1: Set Up Your Project:**
Create a new folder for your project, _project name as per your wish i have created project name called_ `Todo App` and inside it, create three files: **`index.html`**, **`style.css`**, and **`script.js`**. These files will serve as the foundation for your to-do list app. Otherwise, if you want clone my [Project-Structure-Example](https://github.com/sharathchandar-k/Project-Structure-Example) and start working with me.

**Step 2: Build the Basic HTML Structure:**
In the **`index.html`** file, create the HTML structure for your app and will add the HTML Boilerplate with linking files (`style.css`, `script.js`) into an HTML file.
```
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>To Do Application - By Sharathchandar.K</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <script type="text/javascript" src="script.js"></script>
  </body>
</html>
```

First, will add the `div` with class `container` inside the body element. The div tag defines a division or a section in an HTML document.

```
<div class="container">
<!-- Inside the container will add an input field for adding tasks, a list to display the tasks, and buttons for adding and removing tasks.-->
</div>
```

**Step 3: Style Your Todo App with CSS:**
In the **`style.css`** file, add CSS rules to make your app visually appealing.

We are setting all elements to have zero margins, and zero padding, thus making them look the same in all browsers. with the help of `*` and my favorite font-family `Poppins`.

```
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap");
* {
  margin: 0;
  padding: 0;
  font-family: "Poppins", sans-serif;
  box-sizing: border-box;
}
```
Now will set all the HTML elements in to center of the screen, for that will add styles to the `body` and `.container`.

```
body {
  background: #78c1f3;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.container {
  background: #ffffff;
  padding: 25px;
  width: 550px;
  border-radius: 10px;
}
```

![todocontainer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tn7fep2pybk1rlieftn8.png)

**Step 4: Implement the Todo Header & Body:**
Now we will add the HTML element for Todo Header inside the container.
```
<div class="todo-header">
     <h2>ToDo List</h2>
     <img src="/images/notebook.gif" height="50px" />
</div>
```

```
.todo-header {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
  padding-left: 5px;
  justify-content: center;
}
```

![todoheader](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rqwa7rtl4o9t0zsho3ew.png)

Now we will add the HTML element for Todo Body inside the container below todo header, You'll need an input field for adding tasks, a list to display the tasks, and buttons for adding and removing tasks.

```
<div class="todo-body">
<input
    type="text"
    id="todoText"
    class="todo-input"
    placeholder="Add your items"
/>
<img
    src="/images/plus.png"
    alt="+"
    id="AddUpdateClick"
    onclick="CreateToDoItems();"
/>
</div>
```

```
.todo-body {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: #edeef0;
  border-radius: 30px;
  padding-left: 20px;
  margin-bottom: 25px;
}

.todo-body input {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  padding: 15px 0;
  font-size: 20px;
}

.todo-body img {
  cursor: pointer;
  border-radius: 40px;
  height: 55px;
  width: 55px;
  padding: 15px;
  background: limegreen;
}
```

![todobody](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9n3fvgzqe25y0dh3ymyf.png)

**Step 5: Create a List with Validation to display Todo information :**
Here will add `h5` tag to show the validation of what activity done by users. Ex: Adding, Updating, Completing or Deleting Todo by User, and then will add the `ul` unordered list to add the list of data with information added by the user.

```
<h5 id="Alert"></h5>
<ul id="list-items" class="list-items"></ul>
```

```
ul li {
  list-style: none;
  font-size: 18px;
  cursor: pointer;
  padding: 10px;
}

li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: #edeef0;
  margin-bottom: 10px;
  border-radius: 5px;
}

h5 {
  text-align: center;
  margin-bottom: 10px;
  color: green;
}

.todo-controls {
  width: 25px;
  height: 25px;
  padding: 3px;
  margin-right: 5px;
}
```

**Step 6: Implement the JavaScript Functionality:**
In the **`script.js`** file, and write JavaScript code to make your app interactive. Create functions for adding tasks, removing tasks, and clearing the entire list. You can use the Document Object Model (DOM) to manipulate elements in your HTML.

First will declare all the declarations with the help of `document` object, the document object represents the owner of all other objects on your web page.

```
const todoValue = document.getElementById("todoText");
const todoAlert = document.getElementById("Alert");
const listItems = document.getElementById("list-items");
const addUpdate = document.getElementById("AddUpdateClick");
```

Next will declare the `localstorage` object with the help of `key:todo-list`.
```
let todo = JSON.parse(localStorage.getItem("todo-list"));
if (!todo) {
  todo = [];
}
```

Next will add the `functions` for **CREATE**, **READ**, **UPDATE** & **DELETE**
The function is a block of code designed to perform a particular task. A JavaScript function is executed when "something" invokes it (calls it).

_This below function will help to **CREATE** new tasks into the list and some additional features:_
1. The first tool will check if the user has entered a task or not, if without typing if the user tries to add tool will display the error message called **“Please enter your todo text!”**.
2. If the user enters any task on the textbox and hits the button next to it tool will automatically add to the list as well as in `localstorage`.
3. If the user adds the same task already present in the list then the tool will notify **“This item is already present in the list!”**.
4. Adding a task is unique because if adding the same take is already present there is no use to add it again so the tool will notify the alert.
5. Once the user added a task into the list tool will show the response message **“Todo item Created Successfully!”**;
6. In the list user can able to see the list with two options one is 🖉 Edit and another one is 🗑️ Delete. (this is explained with the function below)

```
function CreateToDoItems() {
  if (todoValue.value === "") {
    todoAlert.innerText = "Please enter your todo text!";
    todoValue.focus();
  } else {
    let IsPresent = false;
    todo.forEach((element) => {
      if (element.item == todoValue.value) {
        IsPresent = true;
      }
    });

    if (IsPresent) {
      setAlertMessage("This item already present in the list!");
      return;
    }

    let li = document.createElement("li");
    const todoItems = `<div title="Hit Double Click and Complete" ondblclick="CompletedToDoItems(this)">${todoValue.value}</div><div>
                    <img class="edit todo-controls" onclick="UpdateToDoItems(this)" src="/images/pencil.png" />
                    <img class="delete todo-controls" onclick="DeleteToDoItems(this)" src="/images/delete.png" /></div></div>`;
    li.innerHTML = todoItems;
    listItems.appendChild(li);

    if (!todo) {
      todo = [];
    }
    let itemList = { item: todoValue.value, status: false };
    todo.push(itemList);
    setLocalStorage();
  }
  todoValue.value = "";
  setAlertMessage("Todo item Created Successfully!");
}
```

![createtodo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mc1jr3shzcy0sr9qpr02.png)

_This below function helps us to **READ** data from localstorage and display in the todo list some additional features:_
1. In the list, the user can able to list all the data added to the task app. It as retrieved from `localstorage`.
2. If the user refreshes the browser or closes the browser `localstorage` will persist data and display again all the time.
3. In the list user can able to see a list with two options one is 🖉 Edit and another one is 🗑️ Delete. (this is explained with the function below)
```
function ReadToDoItems() {
  todo.forEach((element) => {
    let li = document.createElement("li");
    let style = "";
    if (element.status) {
      style = "style='text-decoration: line-through'";
    }
    const todoItems = `<div ${style} title="Hit Double Click and Complete" ondblclick="CompletedToDoItems(this)">${
      element.item
    }
    ${
      style === ""
        ? ""
        : '<img class="todo-controls" src="/images/check-mark.png" />'
    }</div><div>
    ${
      style === ""
        ? '<img class="edit todo-controls" onclick="UpdateToDoItems(this)" src="/images/pencil.png" />'
        : ""
    }
    <img class="delete todo-controls" onclick="DeleteToDoItems(this)" src="/images/delete.png" /></div></div>`;
    li.innerHTML = todoItems;
    listItems.appendChild(li);
  });
}
ReadToDoItems();
```

![createread](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qsenixupx6pt7raluy46.png)

_This below function will help to **UPDATE** the task added by the user into the same list with some additional features:_
1. Users can able to modify the todo data already present in the list with the help of 🖉 the pencil icon Edit option on the list.
2. Once the user clicks this 🖉 tool will get the selected task value and assign it to the text box and button icon change to update.
3. If the user changes anything on the task and hits update it will update in the list as well as `localstorage` too.
4. Without changing anything and the user tries to hit update, the tool will show the alert message **“This item is already present in the list!”**.
5. Once the user changes and hits update tool will send the response message as **“Todo item Updated Successfully!”**

![updatetodo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4i4enedoyk55uh93yyxh.png)

```
function UpdateToDoItems(e) {
  if (
    e.parentElement.parentElement.querySelector("div").style.textDecoration ===
    ""
  ) {
    todoValue.value =
      e.parentElement.parentElement.querySelector("div").innerText;
    updateText = e.parentElement.parentElement.querySelector("div");
    addUpdate.setAttribute("onclick", "UpdateOnSelectionItems()");
    addUpdate.setAttribute("src", "/images/refresh.png");
    todoValue.focus();
  }
}

function UpdateOnSelectionItems() {
  let IsPresent = false;
  todo.forEach((element) => {
    if (element.item == todoValue.value) {
      IsPresent = true;
    }
  });

  if (IsPresent) {
    setAlertMessage("This item already present in the list!");
    return;
  }

  todo.forEach((element) => {
    if (element.item == updateText.innerText.trim()) {
      element.item = todoValue.value;
    }
  });
  setLocalStorage();

  updateText.innerText = todoValue.value;
  addUpdate.setAttribute("onclick", "CreateToDoItems()");
  addUpdate.setAttribute("src", "/images/plus.png");
  todoValue.value = "";
  setAlertMessage("Todo item Updated Successfully!");
}
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ily1dq54bddytj8dp10a.png)

_This below function helps to **DELETE** a task data from the list as well as `localstorage` with some additional features:_
1. If the user clicks 🗑️ Delete icon in the list tool will show a confirm alert message **"Are you sure. Due you want to delete this $TaskName"**.
2. If user says OK on the confirm window tool will automatically delete the task data from the list with `localstorage` too.
3. If user says cancel nothing will change. this confirmation message shows user awareness for clicking the correct event.

```
function DeleteToDoItems(e) {
  let deleteValue =
    e.parentElement.parentElement.querySelector("div").innerText;

  if (confirm(`Are you sure. Due you want to delete this ${deleteValue}!`)) {
    e.parentElement.parentElement.setAttribute("class", "deleted-item");
    todoValue.focus();

    todo.forEach((element) => {
      if (element.item == deleteValue.trim()) {
        todo.splice(element, 1);
      }
    });

    setTimeout(() => {
      e.parentElement.parentElement.remove();
    }, 1000);

    setLocalStorage();
  }
}
```

![deleteconfirm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n13tbp3mkbku6803mx1x.png)

_This below function helps to change the status of the task if it's **COMPLETE** ✔ or not with some additional features:_
1. once a user completes the task he wants this task on the list without being deleted, so we came up with an idea to change the styles and set as completed icon ✔ to that task.
2. So once a user completes the task he/she can double-click the task, tool will change the style to line-through and add a checkmark ✔ icon next to it.
3. Once the user completes the task he/she can’t able to 🖉 edit user need to confirm before setting it to complete.
4. Only one option will be displayed to the user, he/she can able to 🗑️ delete the task.

```
function CompletedToDoItems(e) {
  if (e.parentElement.querySelector("div").style.textDecoration === "") {
    const img = document.createElement("img");
    img.src = "/images/check-mark.png";
    img.className = "todo-controls";
    e.parentElement.querySelector("div").style.textDecoration = "line-through";
    e.parentElement.querySelector("div").appendChild(img);
    e.parentElement.querySelector("img.edit").remove();

    todo.forEach((element) => {
      if (
        e.parentElement.querySelector("div").innerText.trim() == element.item
      ) {
        element.status = true;
      }
    });
    setLocalStorage();
    setAlertMessage("Todo item Completed Successfully!");
  }
}
```

![completetodo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/32evlupssczb9d6f1qd6.png)

_This below function will help to set `localstorage` item, i have segregated this as separate function and invoked this on **CREATE**, **UPDATE** and **DELETE** functions, with the help of this we are not using same code at multiple places._

```
function setLocalStorage() {
  localStorage.setItem("todo-list", JSON.stringify(todo));
}
```

_This below function will help to set the alert messages based on user activity in the app, based on user function call will send and reserve messages into the parameter, will set the alert into an HTML element with the help of innerText._
```
function setAlertMessage(message) {
  todoAlert.removeAttribute("class");
  todoAlert.innerText = message;
  setTimeout(() => {
    todoAlert.classList.add("toggleMe");
  }, 1000);
}
```

**Step 6: Implementing Animation on Create & Delete To-do's and Hide Alert Message :**
_This below code will help to set the animation on the To-do's._

```
li {
  opacity: 0;
  animation: new-item-animation 0.3s linear forwards;
}

@keyframes new-item-animation {
  from {
    opacity: 0;
    transform: translateY(-400px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

li.deleted-item {
  animation: removed-item-animation 1s cubic-bezier(0.55, -0.04, 0.91, 0.94)
    forwards;
  transform-origin: 0% 100%;
}

@keyframes removed-item-animation {
  0% {
    opacity: 1;
    transform: rotateZ(0);
  }

  100% {
    opacity: 0;
    transform: translateY(600px) rotateZ(90deg);
  }
}
```

_This below code will hide the messages slowly once user complete there activity on the list._
```
.toggleMe {
  animation: hideMe 5s forwards;
}
@keyframes hideMe {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}
```

**Step 7: Test and Customize:**
Open your **`index.html`** file in a web browser to test your todo list app. Add tasks, remove them, and clear the list to ensure everything works as expected. You can further customize and enhance your app by adding features like task prioritization, due dates, or data persistence with local storage.

> Conclusion:
> Congratulations! You've successfully created a basic todo list app using HTML, CSS, and JavaScript. This project is an excellent starting point for learning web development and can be expanded with additional features to suit your needs. Happy coding!

Join our ever-growing community on [YouTube](https://www.youtube.com/@SharathchandarK), where we explore [Full Stack development](https://www.youtube.com/watch?v=dyRYpFaOgT8&t=4s), learn, and have fun together. **Your subscription is a vote of confidence**, and it enables us to keep producing high-quality, informative videos that you can enjoy and share with your friends and family.

So, if you haven’t already, please hit that subscribe button, click the notification bell, and be a part of our YouTube family. Let’s continue learning, growing, and sharing knowledge in exciting and innovative ways.

Thank you once again for your support, and we look forward to seeing you on our YouTube channel!