Vincent A Saulys' Blog
"Click to Edit" in Vanilla Javascript
Tags: javascript
April 13, 2021

Click-to-edit is a simple functional pattern that's not so straightforward to implement. Below is a snippet to do that.

<html>
  <body>
    <div id="title-container" class="is-inline" status="not-active">
      <span class="title" id="title">Fresh Links</span>
    </div>
  </body>
  <script>
  const titleContainer = document.querySelector("#title-container")
  titleContainer.addEventListener("click", e => {
    if (titleContainer.getAttribute("status") === "not-active") {
      const currentTitle = titleContainer.querySelector("span.title").innerHTML;
      titleContainer.innerHTML = `
        <input id="edit-title" name="" type="text" value="${currentTitle}"/>
      `;
      titleContainer.setAttribute("status", "active");
      // submit change
      document.querySelector("#edit-title").addEventListener("keypress", e => {
        if (e.key === "Enter") {
          titleContainer.innerHTML = `<span class="title" id="title">${e.target.value}</span>`;
          titleContainer.setAttribute("status", "not-active");
        } 
      });
      document.addEventListener('keyup', e => {
        if (e.keyCode == 27) {
          titleContainer.innerHTML = `<span class="title" id="title">${currentTitle}</span>`;
          titleContainer.setAttribute("status", "not-active");
        }
      });
    }
  });
  </script>
</html>

(note that this is excised from a much longer code block but should work as-is)

The event flow is as follows:

  1. click on #title-container div tag

  2. get the current title from the inner html

  3. replace the inner html with an input tag

  4. attach listeners to that input tag to listen for "enter" or "escape" -- act correctly.

  5. if enter is typed, replace the input tag with a new title tag with the new entered title.

  6. if escape is typed, replace the input tag with a new title tag with the old title (currentTitle).

Enter is straightforward. e.target.value gest the value of the input tag that triggered the event. Simple create a new span tag.

The escape listener is weird. You need to make sure its remove a class or setting an attribute to "not-active." Many snippets will use ".toggle" but this will make it difficult to interface with other elements on a page that may also want to be hidden on escape.

If you have a lot of functionality like this, it's probably a better idea to use ReactJS frankly. It's meant to do this and encapsulate the logic on a component-by-component basis. This is much easier to work on without having to think about the scope of the entire page. ReactJS also helps you to encapsulate click-to-edit into resuable components. There may be a future post with information on how to do that.

Share on...