JavaScript Tutorial: Building a To-Do List App

Create an illustration of a simple, clean to-do list app interface developed using JavaScript. The image should feature an unbranded, generic digital device showing the interface with straightforward functionality: a list of tasks with checkboxes, each awaiting to be ticked. There should be a responsive button for adding new tasks. Remember, no text should be evident within the interface on the device's screen or on the device itself, nor should there be human figures or any branded elements. The background should be a gradient to bring focus to the digital device and the user interface it displays.

Why Build a To-Do List App?

Building a to-do list app is a great way to strengthen your JavaScript skills.

It’s a simple project, but it incorporates essential concepts like DOM manipulation, event handling, and local storage.

TL;DR: How to Build a To-Do List App in JavaScript

Follow these steps to build a basic to-do list app:


// HTML Structure



To-Do List

To-Do List




    // JavaScript (todo.js)
    document.getElementById('add-task-button').addEventListener('click', function() {
    let task = document.getElementById('new-task').value;
    if (task) {
    let li = document.createElement('li');
    li.textContent = task;
    document.getElementById('task-list').appendChild(li);
    document.getElementById('new-task').value = '';
    }
    });

    With this code, you can create a simple to-do list app.

    Core Concepts to Understand

    Before diving into the code, it’s important to understand some core JavaScript concepts.

    These include DOM manipulation, event handling, and local storage.

    Understanding DOM Manipulation

    DOM manipulation refers to the process of changing the structure, style, or content of a web page.

    In our to-do list app, we will manipulate the DOM to add, remove, and edit tasks.

    Event Handling in JavaScript

    Event handling is essential to make your app interactive.

    In our example, the click event on the “Add Task” button triggers the function to add new tasks to the list.

    Using Local Storage

    Local storage is a way to store data locally within the user’s browser.

    With local storage, you can save the to-do list so that it persists even after the browser is closed.

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

    Let’s break down the implementation into simple steps.

    Step 1: Create the HTML Structure

    Start with a basic HTML structure.





    To-Do List

    To-Do List





      This provides a simple UI to interact with your to-do list.

      Step 2: Capture User Input

      Next, capture the task input from the user.

      Add an event listener to the “Add Task” button.


      document.getElementById('add-task-button').addEventListener('click', function() {
      let task = document.getElementById('new-task').value;
      if (task) {
      let li = document.createElement('li');
      li.textContent = task;
      document.getElementById('task-list').appendChild(li);
      document.getElementById('new-task').value = '';
      }
      });

      This code adds the new task to the list and clears the input field.

      Step 3: Style the To-Do List

      Add styles to make your to-do list look better.

      Use CSS to style the list items, buttons, and input fields.

      This CSS gives the app a simple but clean look.

      Step 4: Implement Task Removal

      Allow users to remove tasks once they are completed.

      Add an event listener to each list item for the ‘click’ event.


      document.getElementById('task-list').addEventListener('click', function(event) {
      if (event.target.tagName === 'LI') {
      event.target.remove();
      }
      });

      This code will remove a task when it is clicked.

      Step 5: Add Local Storage

      To save the tasks, use local storage.

      First, save the tasks to local storage whenever a task is added or removed.


      function saveTasks() {
      let tasks = [];
      document.querySelectorAll('#task-list li').forEach(li => tasks.push(li.textContent));
      localStorage.setItem('tasks', JSON.stringify(tasks));
      }
      document.getElementById('add-task-button').addEventListener('click', function() {
      /* existing code to add task */
      saveTasks();
      });
      document.getElementById('task-list').addEventListener('click', function(event) {
      /* existing code to remove task */
      if (event.target.tagName === 'LI') {
      event.target.remove();
      saveTasks();
      }
      });

      This code saves the tasks array to local storage whenever tasks are changed.

      Step 6: Load Tasks from Local Storage

      Load the saved tasks when the page loads.

      Read the tasks from local storage and add them to the list on page load.


      window.addEventListener('load', function() {
      let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
      tasks.forEach(task => {
      let li = document.createElement('li');
      li.textContent = task;
      document.getElementById('task-list').appendChild(li);
      });
      });

      This code loads and displays the tasks from local storage when the page is loaded.

      Frequently Asked Questions

      How do I clear all tasks at once?

      Add a new button to your HTML for clearing all tasks.

      Then, add the accompanying JavaScript to remove all tasks and update local storage.



      document.getElementById('clear-tasks-button').addEventListener('click', function() {
      document.getElementById('task-list').innerHTML = '';
      localStorage.removeItem('tasks');
      });

      Can I edit a task once it is added?

      Yes, you can implement an edit feature by adding an ‘edit’ button next to each task.

      When clicked, it can replace the task text with an input box for editing.

      How do I improve the app’s user interface?

      Use CSS frameworks like Bootstrap for a more polished look.

      You can also add more styles and animations for a better user experience.

      Can I add deadline or priority to each task?

      Yes, you can extend the app by adding input fields for deadline and priority.

      Store these in local storage and display them alongside each task.

      Step 7: Add Task Editing

      To make the to-do list more functional, let’s add a task editing feature.

      You will need to allow users to click on a task and modify its text.


      document.getElementById('task-list').addEventListener('dblclick', function(event) {
      if (event.target.tagName === 'LI') {
      let li = event.target;
      let currentText = li.textContent;
      let input = document.createElement('input');
      input.type = 'text';
      input.value = currentText;
      li.innerHTML = '';
      li.appendChild(input);
      input.focus();

      input.addEventListener('blur', function() {
      li.textContent = input.value || currentText;
      saveTasks();
      });
      }
      });

      This code enables users to double-click on a task to edit its text and save the changes when the input loses focus.

      Step 8: Add Task Prioritization

      You can also add a feature to prioritize tasks.

      Allow each task to have a priority level that users can set and display.


      document.getElementById('add-task-button').addEventListener('click', function() {
      let task = document.getElementById('new-task').value;
      let priority = document.getElementById('task-priority').value;

      if (task) {
      let li = document.createElement('li');
      li.dataset.priority = priority;
      li.textContent = `${task} - Priority: ${priority}`;
      document.getElementById('task-list').appendChild(li);
      document.getElementById('new-task').value = '';
      saveTasks();
      }
      });

      Make sure to add an input for task priority in your HTML structure:



      This approach helps users visually discern task importance.

      Step 9: Add Task Sorting

      To make your to-do list even more useful, add a sort feature based on priority.

      Let users sort tasks by their priority levels.


      document.getElementById('sort-tasks-button').addEventListener('click', function() {
      let tasks = Array.from(document.querySelectorAll('#task-list li'));
      tasks.sort((a, b) => a.dataset.priority - b.dataset.priority);
      document.getElementById('task-list').innerHTML = '';
      tasks.forEach(task => document.getElementById('task-list').appendChild(task));
      });

      Add a button to trigger the sorting:



      This code sorts tasks in ascending order of priority when the button is clicked.

      Step 10: Enhance UI with CSS Framework

      For a more polished look, let’s use a CSS framework like Bootstrap.

      Start by including Bootstrap in your HTML:

      Now, update your HTML and CSS classes to use Bootstrap styles:





      To-Do List

      To-Do List








        These changes improve the user interface and user experience.

        Step 11: Implement Task Completion

        Mark tasks as completed by clicking on them and striking through the text.

        Add a class to style completed tasks:

        Update your event listener to toggle the completed status:


        document.getElementById('task-list').addEventListener('click', function(event) {
        if (event.target.tagName === 'LI') {
        event.target.classList.toggle('completed');
        saveTasks();
        }
        });

        This code strikes through a task when clicked, indicating completion.

        Step 12: Add a Task Filtering Option

        Finally, add a feature to filter tasks based on their completion status.

        Allow users to show only completed or only incomplete tasks:


        document.getElementById('filter-tasks-button').addEventListener('change', function() {
        let filter = event.target.value;
        let tasks = document.querySelectorAll('#task-list li');

        tasks.forEach(task => {
        switch (filter) {
        case 'all':
        task.style.display = '';
        break;
        case 'completed':
        task.style.display = task.classList.contains('completed') ? '' : 'none';
        break;
        case 'incomplete':
        task.style.display = task.classList.contains('completed') ? 'none' : '';
        break;
        }
        });
        });

        Add a select element for filtering in your HTML:



        This code provides a way to filter and display tasks based on the selected option.

        Frequently Asked Questions

        Can I use a framework other than Bootstrap for styling?

        Yes, you can use any CSS framework or custom styles that you prefer.

        Popular alternatives include Tailwind CSS, Bulma, and Materialize.

        How can I debug issues with the app?

        Use the browser’s developer tools to inspect elements and debug JavaScript code.

        Console logs and breakpoints can help you identify and fix issues.

        Is it possible to add more functionalities?

        Yes, you can extend the app with features like due dates, recurring tasks, or task categories.

        Build upon the existing structure and add new elements and event listeners as needed.

        Can I deploy this app online?

        Yes, you can deploy it using services like GitHub Pages, Netlify, or Vercel.

        Upload your project files and follow the deployment steps provided by the service.

        Shop more on Amazon