Todo App using JavaScript, HTML, and CSS

Creating a simple Todo App is a fantastic project for beginners and intermediate JavaScript developers. This project encompasses DOM manipulation, event handling, and local storage, which are fundamental concepts in web development. This blog post will guide you through building a minimalistic yet functional Todo App that lets users add, complete, and delete tasks.

Step 1: Setting Up Your Workspace

Create a Project Folder: Name it todo-app. This directory will contain all your project files.

File Structure: Inside the todo-app, create three files:
  • index.html - for the app structure.
  • style.css - for styling the app.
  • script.js - for the app's functionality.

Step 2: Building the App Structure (index.html)

Start with a simple HTML5 template. Incorporate a <form> with an <input> field for new todos and a <ul> element where the todo items will be listed. This structure allows users to type their todo item and submit it, adding the item to the list.
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>ToDo App</title>
        <link rel="stylesheet" href="style.css" />
        <script src="script.js" defer></script>
    </head>
    <body>
        <h1>todos</h1>
        <form id="form">
            <input
                type="text"
                id="input"
                class="input"
                placeholder="Enter your todo"
                autocomplete="off"
            />
            <ul class="todos" id="todos"></ul>
        </form>
        <small
            >Left click to toggle complete. <br />Right click to delete the
            todo.</small
        >
    </body>
</html>

Step 3: Styling Your App (style.css) 

Use CSS to make your app visually appealing. This step is crucial for enhancing user experience. 

Let's open the style.css file and add the following CSS code it:
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;400;600&display=swap");

* {
    box-sizing: border-box;
}

body {
    background-color: #f5f5f5;
    color: #444;
    display: flex;
    align-items: center;
    flex-direction: column;
    font-family: "Poppins", sans-serif;
    margin: 0;
    min-height: 100vh;
}

h1 {
    color: rgb(179, 131, 226);
    font-size: 10rem;
    text-align: center;
    opacity: 0.4;
}

form {
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
    max-width: 100%;
    width: 400px;
}

.input {
    border: none;
    color: #444;
    font-size: 2rem;
    padding: 1rem 2rem;
    display: block;
    width: 100%;
}

.input::placeholder {
    color: #d5d5d5;
}

.todos {
    background-color: #fff;
    padding: 0;
    margin: 0;
    list-style-type: none;
}

.todos li {
    border-top: 1px solid #e5e5e5;
    cursor: pointer;
    font-size: 1.5rem;
    padding: 1rem 2rem;
}

.todos li.completed {
    color: #b6b6b6;
    text-decoration: line-through;
}

small {
    color: #b5b5b5;
    margin-top: 3rem;
    text-align: center;
}

Step 4: Adding Interactivity with JavaScript (script.js) 

Your JavaScript code will bring the app to life, handling user interactions and updating the DOM. 

Variables and Event Listeners: Start by selecting your DOM elements and setting up an event listener for the form submission. 

Creating Todos: Implement a function to create new todo elements. This function should be called when the form is submitted. 

Completing and Deleting Todos: Add functionality to toggle the completion state of a todo and to remove a todo item from the list on specific events (e.g., left-click to complete, right-click to delete).

Local Storage: Utilize local storage to save and retrieve the todo list, ensuring that user data persists between sessions.

Let's open the script.js file and add the following code to it:
 
const form = document.getElementById("form");
const input = document.getElementById("input");
const todosUL = document.getElementById("todos");

const todos = JSON.parse(localStorage.getItem("todos"));

if (todos) {
    todos.forEach((todo) => {
        addTodo(todo);
    });
}

form.addEventListener("submit", (e) => {
    e.preventDefault();

    addTodo();
});

function addTodo(todo) {
    let todoText = input.value;

    if (todo) {
        todoText = todo.text;
    }

    if (todoText) {
        const todoEl = document.createElement("li");
        if (todo && todo.completed) {
            todoEl.classList.add("completed");
        }

        todoEl.innerText = todoText;

        todoEl.addEventListener("click", () => {
            todoEl.classList.toggle("completed");

            updateLS();
        });

        todoEl.addEventListener("contextmenu", (e) => {
            e.preventDefault();

            todoEl.remove();

            updateLS();
        });

        todosUL.appendChild(todoEl);

        input.value = "";

        updateLS();
    }
}

function updateLS() {
    const todosEl = document.querySelectorAll("li");

    const todos = [];

    todosEl.forEach((todoEl) => {
        todos.push({
            text: todoEl.innerText,
            completed: todoEl.classList.contains("completed"),
        });
    });

    localStorage.setItem("todos", JSON.stringify(todos));
}

Step 5: Open index.html in Browser 

After completing these steps, open index.html in your browser to see your Todo App in action. As you become more comfortable with these basics, consider adding features like filtering for completed tasks, editing existing todos, or categorizing tasks. 

This project serves not only as a practical application of JavaScript, HTML, and CSS but also as a foundation upon which you can build more complex web applications. Enjoy coding!

Comments