How to Build a To-Do App with Vanilla JavaScript

How to Build a To-Do App with Vanilla JavaScript

Creating a to-do app is an excellent way to practice and enhance your JavaScript skills. It’s a beginner-friendly project that covers essential concepts like DOM manipulation, event handling, and local storage. In this blog post, we’ll guide you through how to build a to-do app with vanilla JavaScript. By the end of this tutorial, you’ll have a fully functional app that allows users to add, delete, and mark tasks as complete.

Why Build a To-Do App with Vanilla JavaScript?

Using vanilla JavaScript (without frameworks or libraries) helps you:

  • Understand Core Concepts: Learn how JavaScript works under the hood.
  • Improve Problem-Solving Skills: Build logic and functionality from scratch.
  • Enhance Portfolio: Add a practical project to your portfolio.
  • Lightweight App: Avoid unnecessary dependencies for a simple app.

Features of the To-Do App

Our to-do app will include the following features:

  1. Add Tasks: Users can add new tasks to the list.
  2. Delete Tasks: Users can remove tasks they no longer need.
  3. Mark Tasks as Complete: Users can mark tasks as completed.
  4. Persist Data: Tasks will be saved in the browser’s local storage.

Step-by-Step Guide to Building the To-Do App

1. Set Up the Project

Create a basic HTML file and include a script.js file for JavaScript and a style.css file for styling.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>To-Do App</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="container">
    <h1>To-Do App</h1>
    <input type="text" id="taskInput" placeholder="Add a new task">
    <button id="addTaskBtn">Add Task</button>
    <ul id="taskList"></ul>
  </div>
  <script src="script.js"></script>
</body>
</html>

2. Style the App

Add basic styling to make the app visually appealing.

body {
  font-family: Arial, sans-serif;
  background-color: #f4f4f4;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
}

.container {
  background-color: #fff;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  width: 300px;
  text-align: center;
}

h1 {
  margin-bottom: 20px;
}

input {
  width: 100%;
  padding: 10px;
  margin-bottom: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

button {
  padding: 10px 20px;
  background-color: #28a745;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background-color: #218838;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  border-bottom: 1px solid #ccc;
}

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

li button {
  background-color: #dc3545;
  border: none;
  color: #fff;
  padding: 5px 10px;
  border-radius: 4px;
  cursor: pointer;
}

li button:hover {
  background-color: #c82333;
}

3. Add JavaScript Functionality

a. Add Tasks

Use JavaScript to add tasks to the list when the user clicks the “Add Task” button.

const taskInput = document.getElementById('taskInput');
const addTaskBtn = document.getElementById('addTaskBtn');
const taskList = document.getElementById('taskList');

addTaskBtn.addEventListener('click', () => {
  const taskText = taskInput.value.trim();
  if (taskText !== '') {
    addTask(taskText);
    taskInput.value = '';
    saveTasks();
  }
});

function addTask(taskText) {
  const li = document.createElement('li');
  li.textContent = taskText;

  const deleteBtn = document.createElement('button');
  deleteBtn.textContent = 'Delete';
  deleteBtn.addEventListener('click', () => {
    taskList.removeChild(li);
    saveTasks();
  });

  li.appendChild(deleteBtn);
  taskList.appendChild(li);
}

b. Mark Tasks as Complete

Add functionality to mark tasks as completed when clicked.

taskList.addEventListener('click', (e) => {
  if (e.target.tagName === 'LI') {
    e.target.classList.toggle('completed');
    saveTasks();
  }
});

c. Save Tasks to Local Storage

Use local storage to persist tasks even after the page is refreshed.

function saveTasks() {
  const tasks = [];
  taskList.querySelectorAll('li').forEach(li => {
    tasks.push({
      text: li.textContent.replace('Delete', '').trim(),
      completed: li.classList.contains('completed')
    });
  });
  localStorage.setItem('tasks', JSON.stringify(tasks));
}

function loadTasks() {
  const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
  tasks.forEach(task => {
    const li = addTask(task.text);
    if (task.completed) {
      li.classList.add('completed');
    }
  });
}

document.addEventListener('DOMContentLoaded', loadTasks);

Complete JavaScript Code

Here’s the complete JavaScript code for the to-do app:

const taskInput = document.getElementById('taskInput');
const addTaskBtn = document.getElementById('addTaskBtn');
const taskList = document.getElementById('taskList');

// Add Task
addTaskBtn.addEventListener('click', () => {
  const taskText = taskInput.value.trim();
  if (taskText !== '') {
    addTask(taskText);
    taskInput.value = '';
    saveTasks();
  }
});

function addTask(taskText) {
  const li = document.createElement('li');
  li.textContent = taskText;

  const deleteBtn = document.createElement('button');
  deleteBtn.textContent = 'Delete';
  deleteBtn.addEventListener('click', () => {
    taskList.removeChild(li);
    saveTasks();
  });

  li.appendChild(deleteBtn);
  taskList.appendChild(li);
}

// Mark Task as Complete
taskList.addEventListener('click', (e) => {
  if (e.target.tagName === 'LI') {
    e.target.classList.toggle('completed');
    saveTasks();
  }
});

// Save Tasks to Local Storage
function saveTasks() {
  const tasks = [];
  taskList.querySelectorAll('li').forEach(li => {
    tasks.push({
      text: li.textContent.replace('Delete', '').trim(),
      completed: li.classList.contains('completed')
    });
  });
  localStorage.setItem('tasks', JSON.stringify(tasks));
}

// Load Tasks from Local Storage
function loadTasks() {
  const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
  tasks.forEach(task => {
    const li = addTask(task.text);
    if (task.completed) {
      li.classList.add('completed');
    }
  });
}

document.addEventListener('DOMContentLoaded', loadTasks);

Summary of Features

Feature Description Implementation
Add Tasks Users can add new tasks to the list. addTask() function
Delete Tasks Users can remove tasks they no longer need. Delete button with event listener
Mark Tasks as Complete Users can mark tasks as completed. Toggle completed class on click
Persist Data Tasks are saved in local storage. saveTasks() and loadTasks() functions

Debugging Tips for Your To-Do App

  1. Check Console for Errors: Use console.log() to debug issues.
  2. Validate Input: Ensure the task input is not empty before adding it.
  3. Test Local Storage: Verify tasks are saved and loaded correctly.
  4. Inspect DOM: Use browser developer tools to inspect elements and event listeners.

Enhancements for Future Versions

  1. Edit Tasks: Allow users to edit existing tasks.
  2. Due Dates: Add due dates and prioritize tasks.
  3. Categories: Organize tasks into categories or projects.
  4. Dark Mode: Add a toggle for dark mode.

Conclusion

Building a to-do app with vanilla JavaScript is a fantastic way to practice core JavaScript concepts and improve your coding skills. By following this tutorial, you’ve created a functional app that allows users to add, delete, and mark tasks as complete, with data persistence using local storage.

This project is a great addition to your portfolio and serves as a foundation for more complex applications. Keep experimenting and adding new features to enhance your app further. Happy coding!

Ready to take your JavaScript skills to the next level? Enroll in our JavaScript Training in Vizag and learn from industry experts!

© 2023 Softenant. All rights reserved.

Leave a Comment

Your email address will not be published. Required fields are marked *