skip to Main Content

I am creating a website where the user can add items to a To Do list. It is possible to add items and also delete them, i did that using JavaScript. But now I want to save the current items of the list when the page is refreshed.

I want the To Do list to save the current items, including the ones added by the user, so that when the page is reloaded the list doesn’t go back to its initial form but still maintains the items added. I don’t know how to do it, any help would be appreciated as I’m currently learning HTML, CSS and JavaScript.

// Create a "close" button and append it to each list item
var myNodelist = document.getElementsByTagName("LI");
var i;
for (i = 0; i < myNodelist.length; i++) {
  var span = document.createElement("SPAN");
  var txt = document.createTextNode("u00D7");
  span.className = "close";
  span.appendChild(txt);
  myNodelist[i].appendChild(span);
}

// Click on a close button to hide the current list item
var close = document.getElementsByClassName("close");
var i;
for (i = 0; i < close.length; i++) {
  close[i].onclick = function() {
    var div = this.parentElement;
    div.style.display = "none";
  }
}

// Add a "checked" symbol when clicking on a list item
var list = document.querySelector('ul');
list.addEventListener('click', function(ev) {
  if (ev.target.tagName === 'LI') {
    ev.target.classList.toggle('checked');
  }
}, false);

// Create a new list item when clicking on the "Add" button
function newElement() {
  var li = document.createElement("li");
  var inputValue = document.getElementById("myInput").value;
  var t = document.createTextNode(inputValue);
  li.appendChild(t);
  if (inputValue === '') {
    alert("You must write something!");
  } else {
    document.getElementById("myUL").appendChild(li);
  }
  document.getElementById("myInput").value = "";

  var span = document.createElement("SPAN");
  var txt = document.createTextNode("u00D7");
  span.className = "close";
  span.appendChild(txt);
  li.appendChild(span);

  for (i = 0; i < close.length; i++) {
    close[i].onclick = function() {
      var div = this.parentElement;
      div.style.display = "none";
    }
  }
}
#myUL {
    position: absolute;
    width: 30rem;
    margin-left: 72rem;
    margin-top: 21rem;
    padding: 0;
    list-style-type: none;
}
  
#myUL li {
    font-family: 'Montserrat', sans-serif;
    cursor: pointer;
    position: relative;
    padding: 12px 8px 12px 40px;
    background: #eee;
    font-size: 18px;
    transition: 0.2s;
  
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
  
#myUL li:nth-child(odd) {
    background: #f9f9f9;
}
  
#myUL li:hover {
    background: #ddd;
}
  
#myUL li.checked {
    background: #888;
    color: #fff;
    text-decoration: line-through;
}
  
#myUL li.checked::before {
    content: '';
    position: absolute;
    border-color: #fff;
    border-style: solid;
    border-width: 0 2px 2px 0;
    top: 10px;
    left: 16px;
    transform: rotate(45deg);
    height: 15px;
    width: 7px;
}
  
.close {
    position: absolute;
    right: 0;
    top: 0;
    padding: 12px 16px 12px 16px;
}
  
.close:hover {
    background-color: #f44336;
    color: white;
}
  
.to-do-header {
    position: absolute;
    width: 30rem;
    margin-top: 13.5rem;
    margin-left: 72rem;
    padding: 1rem 1rem 1rem 1rem;
    background-color: #9fa77f;
    color: white;
    text-align: center;
    border-top-left-radius: 20px;
    border-top-right-radius: 20px;
}
  
.to-do-header:after {
    content: "";
    display: table;
    clear: both;
}

.table-title {
    margin-bottom: 0.6rem;
    font-family: 'Quicksand', sans-serif;
}
  
#myInput {
    font-family: 'Montserrat', sans-serif;
    padding: 0.6rem;
    margin: 0;
    border: none;
    border-radius: 0;
    width: 75%;
    padding: 10px;
    float: left;
    font-size: 16px;
}
  
.addBtn {
    font-family: 'Quicksand', sans-serif;
    padding: 0.6rem;
    width: 25%;
    background: #d9d9d9;
    color: #555;
    float: left;
    text-align: center;
    font-size: 16px;
    cursor: pointer;
    transition: 0.3s;
    border-radius: 0;
}
  
.addBtn:hover {
    background-color: #bbb;
}
<div id="myDIV" class="to-do-header">
    <h2 class="table-title">To Do</h2>
    <input type="text" id="myInput" placeholder="What do you want to do?">
    <span onclick="newElement()" class="addBtn">Add</span>
  </div>
  
  <ul id="myUL">
    <li>Wake up</li>
    <li>Meeting with the team</li>
    <li>Have an amazing lunch</li>
    <li>Finsish the project</li>
    <li>Get some pizza</li>
    <li>Go to sleep</li>
  </ul>

2

Answers


  1. As long as you are not interested to use your(any) backend, you could definitely utilize localStorage.

    Source: Mozilla docs

    Basic example:

    const tasks = [{id:1,title:'save the world', description:'today'},...]
    
    localStorage.setItem('tasks', JSON.stringify(tasks)); // save the tasks
    
    const savedTasks = JSON.parse(localStorage.getItem('tasks')) || []; // load the tasks
    
    Login or Signup to reply.
  2. As others have suggested, the simplest approach is to store the list contents as a string in localStorage. You would update the string in localStorage any time the list is altered and when the page initially loads, you’d check localStorage to see if there is a list there to restore.

    Now, beyond this, you have several other lines of code that "work", but are not considered the modern approach to coding.

    Keep in mind that the following snippet won’t work here at Stack Overflow due to sandboxing, but it will work on a real page as shown in this Fiddle. So go to the Fiddle and alter the list in some way. Then, close your browser and go back to the Fiddle. You’ll see your latest list is restored.

    See comments in ALL CAPS below:

    // WHEN THE PAGE IS READY FOR INTERACTION, CHECK TO SEE IF
    // A LIST IS PRESENT IN LOCALSTORAGE AND, IF SO, RESTORE IT.
    const theList = document.querySelector("#myUL");
    let ls = localStorage.getItem("list");
    if(ls){
      myUL.innerHTML = ls; // Restore the list from localStorage
    }
    
    // DO YOUR EVENT BIDNING IN JAVASCRIPT, NOT WITH HTML EVENT ATTRIBUTES LIKE ONCLICK
    document.querySelector("span.addBtn").addEventListener("click", newElement);
    
    
    // Create a "close" button and append it to each list item
    // >>>> DON'T USE GETELEMENTSBYTAGNAME as it an old legacy API
    // >>>> USE QUERYSELECTORALL WHICH ALLOWS FOR FOREACH LOOPING
    document.querySelectorAll("LI").forEach(function(element){
      const span = document.createElement("SPAN");
      span.classList.add("close");
      span.textContent = "u00D7";
      element.appendChild(span);
    });
    
    // Click on a close button to hide the current list item
    const close = document.querySelectorAll(".close");
    close.forEach(function(element){
      element.addEventListener("click", function(){
        // YOU SHOULD BE REMOVING THE ELEMENT NOT JUST HIDING IT
        this.parentElement.remove();
        // UPDATE LOCAL STORAGE 
        localStorage.setItem("list", myUL.innerHTML);
      });
    });
    
    // Add a "checked" symbol when clicking on a list item
    document.querySelector('ul').addEventListener('click', function(ev) {
      if (ev.target.tagName === 'LI') {
        ev.target.classList.toggle('checked');
      }
    });  //  >>> THE SECOND ARGUMENT (FALSE) IS THE DEFAULT
    
    const theInput = document.getElementById("myInput");
    
    // Create a new list item when clicking on the "Add" button
    function newElement() {
      var li = document.createElement("li");
      // NO NEED TO EXPLICITLY CREATE A TEXT NODE AND THEN APPEND IT.
      // JUST SET THE TEXTCONTENT PROPERTY AND BE DONE.
      if (theInput.value === '') {
        alert("You must write something!");
      } else {
        li.textContent = theInput.value;
        theList.appendChild(li);
        // UPDATE LOCAL STORAGE 
        localStorage.setItem("list", myUL.innerHTML);
      }
      theInput.value = "";
    
      const span = document.createElement("SPAN");
      span.classList.add("close");
      span.textContent = "u00D7";
      li.appendChild(span);
    }
    /* Avoid inline styles just add/remove the following
       class when something needs to be hidden/shown  */
    .hidden { display:none; }
    
    #myUL {
        position: absolute;
        width: 32rem;
        margin-left: 10rem;
        margin-top: 24rem;
        padding: 0;
        list-style-type: none;
    }
      
    #myUL li {
        font-family: 'Montserrat', sans-serif;
        cursor: pointer;
        position: relative;
        padding: 12px 8px 12px 40px;
        background: #eee;
        font-size: 18px;
        transition: 0.2s;
      
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
    }
      
    #myUL li:nth-child(odd) {
        background: #f9f9f9;
    }
      
    #myUL li:hover {
        background: #ddd;
    }
      
    #myUL li.checked {
        background: #888;
        color: #fff;
        text-decoration: line-through;
    }
      
    #myUL li.checked::before {
        content: '';
        position: absolute;
        border-color: #fff;
        border-style: solid;
        border-width: 0 2px 2px 0;
        top: 10px;
        left: 16px;
        transform: rotate(45deg);
        height: 15px;
        width: 7px;
    }
      
    .close {
        position: absolute;
        right: 0;
        top: 0;
        padding: 12px 16px 12px 16px;
    }
      
    .close:hover {
        background-color: #f44336;
        color: white;
    }
      
    .to-do-header {
        position: absolute;
        width: 30rem;
        margin-top: 13.5rem;
        margin-left: 10rem; 
        padding: 1rem 1rem 1rem 1rem;
        background-color: #9fa77f;
        color: white;
        text-align: center;
        border-top-left-radius: 20px;
        border-top-right-radius: 20px;
    }
      
    .to-do-header:after {
        content: "";
        display: table;
        clear: both;
    }
    
    .table-title {
        margin-bottom: 0.6rem;
        font-family: 'Quicksand', sans-serif;
    }
      
    #myInput {
        font-family: 'Montserrat', sans-serif;
        padding: 0.6rem;
        margin: 0;
        border: none;
        border-radius: 0;
        width: 75%;
        padding: 10px;
        float: left;
        font-size: 16px;
    }
      
    .addBtn {
        font-family: 'Quicksand', sans-serif;
        padding: 0.6rem;
        width: 25%;
        background: #d9d9d9;
        color: #555;
        float: left;
        text-align: center;
        font-size: 16px;
        cursor: pointer;
        transition: 0.3s;
        border-radius: 0;
    }
      
    .addBtn:hover {
        background-color: #bbb;
    }
    <div id="myDIV" class="to-do-header">
      <h2 class="table-title">To Do</h2>
      <input id="myInput" placeholder="What do you want to do?">
      <span class="addBtn">Add</span>
    </div>
      
    <ul id="myUL">
      <li>Wake up</li>
      <li>Meeting with the team</li>
      <li>Have an amazing lunch</li>
      <li>Finsish the project</li>
      <li>Get some pizza</li>
      <li>Go to sleep</li>
    </ul>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search