30 Days of JavaScript: Building a Simple ToDo App with JavaScript — Day 8

30 Days of Javascript Series by DopeThemes

Welcome back, JavaScript buddies! Today, we’ll tackle a practical project—creating a simple ToDo app. This hands-on exercise will reinforce your skills and provide a functional, real-world example. Let’s dive in!

Planning and Structuring Your App

Before we start coding, it’s essential to plan and structure our ToDo app. Let’s break it down into three core components:

  1. Input field for adding new tasks
  2. Task list for displaying tasks
  3. Buttons for editing and deleting tasks

With this structure in mind, we’ll use HTML, CSS, and JavaScript to create a visually appealing and functional app.

Implementing CRUD Operations

CRUD operations (Create, Read, Update, and Delete) are fundamental for any app that handles data. Let’s implement them in our ToDo app:

Create

First, we’ll create an input field and a button to add new tasks. Here’s the HTML:

<input type="text" id="task-input" placeholder="Enter a task">
<button id="add-task-btn">Add Task</button>

Now, let’s add an event listener to the button to create new tasks:

const taskInput = document.getElementById('task-input');
const addTaskBtn = document.getElementById('add-task-btn');

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

To display tasks, we’ll create an unordered list in our HTML:

<ul id="task-list"></ul>

Next, we’ll create a function to display tasks:

const taskList = document.getElementById('task-list');

function createTask(text) {
  const listItem = document.createElement('li');
  listItem.textContent = text;
  taskList.appendChild(listItem);
}
Update and Delete

For updating and deleting tasks, let’s add edit and delete buttons to each task:

function createTask(text) {
  // ...previous code

  const editBtn = document.createElement('button');
  editBtn.textContent = 'Edit';
  listItem.appendChild(editBtn);

  const deleteBtn = document.createElement('button');
  deleteBtn.textContent = 'Delete';
  listItem.appendChild(deleteBtn);

  // ...previous code
}

Now, let’s add event listeners for the edit and delete buttons:

editBtn.addEventListener('click', () => {
  const updatedText = prompt('Edit the task', listItem.textContent);
  if (updatedText !== null && updatedText.trim() !== '') {
    listItem.textContent = updatedText.trim();
  }
});

deleteBtn.addEventListener('click', () => {
  if (confirm('Are you sure you want to delete this task?')) {
    listItem.remove();
  }
});

LocalStorage for Data Persistence

To ensure our tasks persist even after a page refresh, we’ll use LocalStorage to store the data. First, let’s create a function to save tasks:

function saveTasks() {
  const tasks = [];
  const listItems = taskList.getElementsByTagName('li');
  for (let item of listItems) {
    tasks.push(item.textContent);
  }
  localStorage.setItem('tasks', JSON.stringify(tasks));
}

Call this function whenever a task is created, updated, or deleted:

// After creating a task
createTask(taskText);
saveTasks();

// After updating a task
listItem.textContent = updatedText.trim();
saveTasks();

// After deleting a task
listItem.remove();
saveTasks();

Finally, we’ll load tasks from LocalStorage when the page loads:

function loadTasks() {
  const tasks = JSON.parse(localStorage.getItem('tasks'));
  if (tasks) {
    tasks.forEach(task => createTask(task));
  }
}

document.addEventListener('DOMContentLoaded', loadTasks);

Now, our ToDo app will remember tasks even if the user refreshes the page or closes their browser.

Wrapping Up

Here’s the complete code for the ToDo app:

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;Simple ToDo App&lt;/title&gt;
    &lt;style&gt;
        /<em> Add your custom styles here </em>/
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Simple ToDo App&lt;/h1&gt;
    &lt;form id=&quot;task-form&quot;&gt;
        &lt;input type=&quot;text&quot; id=&quot;task-input&quot; placeholder=&quot;Enter a task&quot;&gt;
        &lt;button type=&quot;submit&quot;&gt;Add Task&lt;/button&gt;
    &lt;/form&gt;
    &lt;ul id=&quot;task-list&quot;&gt;&lt;/ul&gt;
    &lt;script&gt;
        const taskForm = document.getElementById('task-form');
        const taskInput = document.getElementById('task-input');
        const taskList = document.getElementById('task-list');

        taskForm.addEventListener('submit', addTask);

        function addTask(e) {
            e.preventDefault();
            const taskText = taskInput.value.trim();

            if (taskText) {
                createTask(taskText);
                saveTask(taskText);
            }

            taskInput.value = '';
        }

        function createTask(text) {
            const li = document.createElement('li');
            li.textContent = text;

            const deleteButton = document.createElement('button');
            deleteButton.textContent = 'Delete';
            deleteButton.addEventListener('click', () =&gt; {
                deleteTask(li);
            });

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

        function saveTask(text) {
            let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
            tasks.push(text);
            localStorage.setItem('tasks', JSON.stringify(tasks));
        }

        function deleteTask(taskElement) {
            const index = [...taskList.children].indexOf(taskElement);
            taskElement.remove();

            let tasks = JSON.parse(localStorage.getItem('tasks'));
            tasks.splice(index, 1);
            localStorage.setItem('tasks', JSON.stringify(tasks));
        }

        function loadTasks() {
            const tasks = JSON.parse(localStorage.getItem('tasks'));
            if (tasks) {
                tasks.forEach(task =&gt; createTask(task));
            }
        }

        document.addEventListener('DOMContentLoaded', loadTasks);
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

Congratulations! You’ve built a simple yet functional ToDo app using JavaScript. We’ve covered essential concepts like planning and structuring your app, implementing CRUD operations, and using LocalStorage for data persistence. This project serves as a solid foundation for you to build upon and enhance with more advanced features.

Keep practicing and experimenting with different ideas to refine your JavaScript skills further. Remember, the key to mastering any programming language is practice and persistence.

In the next tutorial, we’ll explore more exciting topics to expand your JavaScript repertoire. Stay tuned, and happy coding!

Next: 30 Days of JavaScript: Regular Expressions in JavaScript — Day 9


Stay in the loop with our web development newsletter - no spam, just juicy updates! Join us now. Join our web development newsletter to stay updated on the latest industry news, trends, and tips. No spam, just juicy updates delivered straight to your inbox. Don't miss out - sign up now!


We’ve tried our best to explain everything thoroughly, even though there’s so much information out there. If you found our writing helpful, we’d really appreciate it if you could buy us a coffee as a token of support.

Also, if you’re interested in learning more about WordPress, Javascript, HTML, CSS, and programming in general, you can subscribe to our MailChimp for some extra insights.

Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.