Javascript Simple Todo Project for Beginners

Hey guys in this post, we will create a simple Javascript Todo List project step-by-step. Follow this post till the end to learn about the Javascript basics. The project is already live on the internet.

Topics covered


This application involves the following topics –

  • Arrays
  • DOM Manipulation
  • Event Listeners
  • Nested Functions
  • Local Storage API

Complete source code


The below image shows you the project structure –

Screenshot-2021-06-07-at-12-29-09-PM

Add styles to the application


Create a main.css file and add the following content –

:root {
  --mainWhite: #f5f5f5;
  --mainGreen: #80cfa9;
  --mainBlack: #333333;
  --mainRed: #d62828;
  --mainBlue: #11b5e4;
}
body {
  background: var(--mainWhite);
  color: #333333;
}
.btn-green {
  border-color: var(--mainGreen);
  background: transparent;
  color: var(--mainGreen);
}
.btn-green:hover {
  background: var(--mainGreen);
  color: var(--mainBlack);
}
.form-control {
  border-color: var(--mainGreen) !important;
}

.feedback {
  display: none;
}
.item {
  display: flex;
  justify-content: space-between;
}
.item-icon {
  font-size: 1.2rem;
  cursor: pointer;
}
.complete-item {
  color: var(--mainGreen);
}
.complete-item:hover {
  color: var(--mainGreen);
}
.edit-item {
  color: var(--mainBlue);
}
.edit-item:hover {
  color: var(--mainBlue);
}
.delete-item {
  color: var(--mainRed);
}
.delete-item:hover {
  color: var(--mainRed);
}
.completed {
  text-decoration: line-through;
  opacity: 0.5;
}
.visibility {
  opacity: 0.5;
}
.showItem {
  display: block;
}

Add scripts to the application


Create an app.js file and add the following content –

//add an eventListener to the from
const form = document.querySelector('#itemForm'); // select form
const itemInput = document.querySelector('#itemInput'); // select input box from form
const itemList = document.querySelector('.item-list');
const feedback = document.querySelector('.feedback');
const clearButton = document.querySelector('#clear-list');

let todoItems = [];

const handleItem = function(itemName){

    const items = itemList.querySelectorAll('.item');
 
    items.forEach(function(item){
        
        if(item.querySelector('.item-name').textContent === itemName){
            //complete event listener
            item.querySelector('.complete-item').addEventListener('click', function(){
                item.querySelector('.item-name').classList.toggle('completed');
                this.classList.toggle('visibility');
            });
            //edit event listener
            item.querySelector('.edit-item').addEventListener('click', function(){
                itemInput.value = itemName;
                itemList.removeChild(item);

                todoItems = todoItems.filter(function(item){
                    return item !== itemName;
                });
            });
            // delete event listener
            item.querySelector('.delete-item').addEventListener('click', function(){
                debugger;
                itemList.removeChild(item);

                todoItems = todoItems.filter(function(item){
                    return item !== itemName;
                });

                showFeedback('item delete', 'success');
            })
        }
    })
}

const removeItem = function(item){
    console.log(item);
    const removeIndex = (todoItems.indexOf(item));
    console.log(removeIndex);
    todoItems.splice(removeIndex, 1);
}

const getList = function(todoItems){
    itemList.innerHTML = '';

        todoItems.forEach(function(item){
            itemList.insertAdjacentHTML('beforeend', `<div class="item my-3"><h5 class="item-name text-capitalize">${item}</h5><div class="item-icons"><a href="#" class="complete-item mx-2 item-icon"><i class="far fa-check-circle"></i></a><a href="#" class="edit-item mx-2 item-icon"><i class="far fa-edit"></i></a><a href="#" class="delete-item item-icon"><i class="far fa-times-circle"></i></a></div></div>` );

            handleItem(item);
        });
}

const getLocalStorage = function(){

    const todoStorage = localStorage.getItem('todoItems');
    if (todoStorage === 'undefined' || todoStorage === null){
        todoItems = [];
    } else {
        todoItems = JSON.parse(todoStorage);
        getList(todoItems);
    }
}

const setLocalStorage = function(todoItems){
    localStorage.setItem('todoItems', JSON.stringify(todoItems));
}

// get local storage from page
getLocalStorage();

//add an item to the List, including to local storage
form.addEventListener('submit', function(e){ 
    e.preventDefault();
    const itemName = itemInput.value;
    
    if (itemName.length === 0){
        feedback.innerHTML = 'Please Enter Valid Value';
        feedback.classList.add('showItem', 'alert-danger');
        setTimeout(
            function(){
                feedback.classList.remove('showItem');
                }, 3000);
    } else {
        todoItems.push(itemName);
        setLocalStorage(todoItems);
        getList(todoItems);
        //add event listeners to icons;
        //handleItem(itemName);
    }
    
    itemInput.value = '';

    });

    //clear all items from the list
clearButton.addEventListener('click', function(){
    todoItems = [];
    localStorage.clear();
    getList(todoItems);
})

Add HTML to the application


Create an index.html file and add the following content –

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <!-- bootstrap css -->
 <link rel="stylesheet" href="css/bootstrap.min.css">
 <!-- main css -->
 <link rel="stylesheet" href="css/main.css">
 <!-- google fonts -->
 <link href="https://fonts.googleapis.com/css?family=Courgette" rel="stylesheet">

 <!-- font awesome -->
 <link rel="stylesheet" href="css/all.css">
 <title>Grocery Item</title>
 <style>
 </style>
</head>

<body>
 <div class="container">
  <div class="row">
   <div class="col mx-auto col-md-8 mt-3 text-center">
    <div class="alert text-capitalize feedback">
     write value for item
    </div>
    <!-- form -->
    <form id="itemForm" class="my-3">
     <h3 class="text-capitalize mb-4">to do list</h3>
     <div class="input-group">
      <input type="text" class="form-control text-capitalize" id="itemInput" placeholder="name...">
      <div class="input-group-append">
       <button class="btn btn-green text-capitalize" type="submit">add item</button>
      </div>
     </div>
    </form>
    <div class="item-container">
     <!-- end of form  -->
     <div class="item-list my-5">
      <!-- single item -->
      <!-- <div class="item my-3">
      <h5 class="item-name text-capitalize">laundry</h5>
      <div class="item-icons">
       <a href="#" class="complete-item mx-2 item-icon"><i class="far fa-check-circle"></i></a>
       <a href="#" class="edit-item mx-2 item-icon"><i class="far fa-edit"></i></a>
       <a href="#" class="delete-item item-icon"><i class="far fa-times-circle"></i></a>
      </div>
     </div> -->
      <!-- end of single item -->
     </div>
     <button type="button" class="btn btn-green my-3 text-capitalize" id="clear-list">clear items</button>
    </div>
   </div>
  </div>
 </div>




 <!-- jquery -->
 <script src="js/jquery-3.3.1.min.js"></script>
 <!-- bootstrap js -->
 <script src="js/bootstrap.bundle.min.js"></script>
 <!-- script js -->
 <script src="js/app.js"></script>
</body>

</html>

Screenshots


Screenshot-2021-06-07-at-12-49-57-PM
Note: Make sure to download the bootstrap.css, bootstrap.js, and jquery.js library from the internet add them to the respective folders. You can download the images from the Github repository.

Download the complete source code from github repository

Original source https://jsbeginners.com/todo-list-javascript-project-v1/

Bushan Sirgur

Hey guys, I am Bushan Sirgur from Banglore, India. Currently, I am working as an Associate project in an IT company.

Leave a Reply