Search code examples
javascripthtmlhtml-listsuser-inputcontenteditable

How to make an element go back to being noneditable in JavaScript?


I'm trying to make a user-made list and it does most of what it's supposed to. One thing I noticed, though, was that when I click the edit button on one of the list items, it remains editable for the entirety of the session. I want it to stop being editable when the user clicks on another element other than that edit button or the targeted list item.

HTML:

<ul id="todoList">
  <li v-for="item in items" contenteditable="false" id="item">{{item}}
    <div></div>
      <button id="editButton" contenteditable="false" onclick="edit(event)">Edit</button>

JS:

var editB=document.getElementById("editButton");
var tdList=document.getElementById("todoList");
var listItem = document.getElementById("item");

function edit(event) {
  var button = event.target,
    li = button.parentNode;
  li.setAttribute("contenteditable", true);
}

Solution

  • Assuming you aren't using jQuery, you could listen for mousedown events on the todo list and reset every "editable" item unless you're clicking the button with node.addEventListener:

    var editB=document.getElementById("editButton");
    var tdList=document.getElementById("todoList");
    var listItem = document.getElementById("item");
    
    function contentEditable(node) {
      node.setAttribute("contenteditable", true);
    }
    
    function edit(event) {
      var button = event.target,
        li = button.parentNode;
      contentEditable(li);
    }
    
    tdList.addEventListener('mousedown', function(event) {
      var editable = document.querySelectorAll("li.item");
      var target = event.target;
      var id = target.getAttribute("id");
    
      editable.forEach(function(li){
        li.setAttribute("contenteditable", false);
      })
    
     if(id == "editButton") {edit(event)}
     if(id == "item") {contentEditable(target)}
    })
    

    You also need a way to query for "currently editable" things. I added a selector to the li, and removed the contenteditable attribute from the button:

    <ul id="todoList">
      <li v-for="item in items" class="item" contenteditable="false" id="item">Item
        <div></div>
        <button id="editButton">Edit</button>
      </li>
    </ul>
    

    JSFiddle here to try it out

    I hope this helps!