Search code examples
javascriptlocal-storagejavascript-objectscontenteditable

How do I store multiple user changes locally with efficient Javascript?


On my static webpage, users should be able to edit multiple texts and store changes locally to continue editing later. I put this together from code snippets by others (I myself am not a very competent user of Javascript).

https://jsfiddle.net/x2thdrw3/54/

window.onload = function() {

  if (localStorage.getItem('userContent01')) {
    document.querySelector('#userContent01').innerHTML = localStorage.getItem('userContent01');
  }

  if (localStorage.getItem('userContent02')) {
    document.querySelector('#userContent02').innerHTML = localStorage.getItem('userContent02');
  }


}

let editBtn01 = document.querySelector('#userContent01_edit');
let content01 = document.querySelector('#userContent01');

editBtn01.addEventListener('click', () => {
  localStorage.setItem('userContent01', content01.innerHTML);
});

let editBtn02 = document.querySelector('#userContent02_edit');
let content02 = document.querySelector('#userContent02');

editBtn02.addEventListener('click', () => {
  localStorage.setItem('userContent02', content02.innerHTML);
});
.userContent {
  border: ridge 2px;
  padding: 15px;
  width: 100%;
  min-height: 2em;
  overflow: auto;
}
<div class="userContent" , id="userContent01" contenteditable="true">
  Edit this first text and then click save to store your changes for later.
</div>

<button id="userContent01_edit">Store changes to the first text locally</button>


<div class="userContent" , id="userContent02" contenteditable="true">
  Edit this second text and then click save to store your changes for later.
</div>

<button id="userContent02_edit">Store changes to the second text locally</button>

<br>
<br>

<input type="button" value="Reload and keep local storage" onClick="location.reload()">

<input type="button" value="Reload and clear local storage" onClick="localStorage.clear() + location.reload()">

The example is not efficient because the Javascript code would grow with each additional text.

What would be a more efficient way to have multiple of these editable and storable divs on my webpage?

On the webpage, the divs do not occur one after the other, like in the example, but with other noneditable content in between.

P.S.: The code works on jsfiddle but stackoverflow throws a security error. I do not understand why. (Clarified by J. Titus in the comments.)

P.P.S.: I am aware that I am asking a rather specific question. Thank you for your help.


Solution

  • A very compact implementation. (Looks lengthy because of all the comments.)

    window.onload = function () {
      //Get all userContent elements
      let userContent_els = document.querySelectorAll(".user-content");
      
      //Loop over each userContent element
      userContent_els.forEach((el) => {
        // easy access using the id of the user content as key
        let key = el.id;
        let value = localStorage.getItem(key);
    
        if(value)
          el.innerText = value;
      });
    };
    
    //Get all button elements
    let editButton_els = document.querySelectorAll(".edit-button");
    
    //Loop over each button
    editButton_els.forEach((button) => {
      let buttonId = button.id;
    
      button.addEventListener("click", () => {
        /* Storage key is a combination of 'content-' and the button 'id'.
           This combination is intentional as to make it easier getting the data later as we 
           just have to get the content 'id' which is set to 'content-01', 'content-02' etc..*/
    
        // Get corresponding userContent element
        let content_el = document.querySelector(`#content-${buttonId}`);
    
        localStorage.setItem(
         "content-" + buttonId,
         content_el.innerText
        );
      });
    });
    

    HTML

    <div class="user-content" , id="content-01" contenteditable="true">
      Edit this first text and then click save to store your changes for later.
    </div>
    
    <button class="edit-button" id="01">Store changes to the first text locally</button>
    
    <div class="user-content" , id="content-02" contenteditable="true">
      Edit this second text and then click save to store your changes for later.
    </div>
    
    <button class="edit-button" id="02">Store changes to the second text locally</button>
    
    <br>
    <br>
    
    <input type="button" value="Reload and keep local storage" onClick="location.reload()">
    
    <input type="button" value="Reload and clear local storage" onClick="localStorage.clear() + location.reload()">