0

I'm trying to achieve the following:

  1. Initial view is a simple definition list
  2. Clicking on the Edit button converts to input fields and shows Save and Cancel buttons
  3. Clicking the Save button will
  • save to local storage and
  • display as original with updated information
  • and cancel will revert back to point 1 (initial view)
  1. Save to localStorage

I've managed to get achieve points 1 & 2 and can't figure out 3 & 4

I've created Codepen here https://codepen.io/saidcc/pen/JjrZegb

<div class="container mx-auto my-4" id="accountDetail">
  <dl>
    <dt>Website</dt>
    <dd id="website">www.some-website.com</dd>
    <dt>Email</dt>
    <dd id="email">contact@4some-website.com</dd>
    <dt>Phone</dt>
    <dd id="phone">999 999 999</dd>
  </dl>
  <dl>
    <dt>Site Address</dt>
    <dd id="siteAddress">
      123 Address Parade<br>
      City State, 0000<br>
      Country
    </dd>
    <dt>Postal Address</dt>
    <dd id="postalAddress">
      345 Address Esplanade<br>
      City State, 0000<br>
      Country
    </dd>
  </dl>
  <button class="account-details edit btn btn-primary">Edit</button>
  <button class="account-details save btn btn-primary d-none">Save</button>
  <button class="account-details cancel btn btn-outline-primary d-none" type="reset">Cancel</button>
</div>

const editAccountDetails = document.querySelector(".edit")
  const saveAccountDetails = document.querySelector(".save")
  const cancelButton = document.querySelector(".cancel")
  const editableItems = document.querySelectorAll("#accountDetail dd")
  const updatedItems = document.querySelectorAll("#accountDetail .form-control")

  // Show hide save & cancel buttons
  // Get Details to Edit
  // Edit Account Details convert to input tag

  editAccountDetails.addEventListener("click", () => {
    if (editAccountDetails.classList.contains("edit")) {
      editAccountDetails.classList.add('d-none')
      saveAccountDetails.classList.remove('d-none')
      cancelButton.classList.remove('d-none')
    }
    else {
      editAccountDetails.textContent = "Edit Account Details";
    }
    for (let i = 0; i < editableItems.length; i++) {
      let fieldID = editableItems[i].getAttribute('id')
      let fieldValue = editableItems[i].textContent.replace(/ +/g, " ")
      editableItems[i].innerHTML = `
    <input class="form-control" type="text" id="edit-${fieldID}" value="${fieldValue}">
    `
    }
  })

  // Save Account Details & Revert to Original Formating
  saveAccountDetails.addEventListener("click", () => {
    if (saveAccountDetails.classList.contains("save")) {
      saveAccountDetails.classList.add('d-none')
      editAccountDetails.classList.remove('d-none')
      cancelButton.classList.add('d-none')
    } else {
      saveAccountDetails.textContent = "Save";
    }
    
    for (let i = 0; i < updatedItems.length; i++) {
      let updatedValue = updatedItems[i].value
      updatedItems[i].innerHTML = `
      <dd>${updatedValue}</dd>
        `
    }
  })

Said
  • 186
  • 2
  • 13
  • This might help if you wanne bind something, https://stackoverflow.com/questions/16483560/how-to-implement-dom-data-binding-in-javascript. – Maxime C. Jan 06 '22 at 11:00

1 Answers1

0

First approach

I would ignore the convert to input fields, what i would do is make a copy of the form (How to copy).

This will allow for easyer handling. If the user doesn't press save, your original will not be altered. This will also allow for easy mapping (mapping dom collection).

  • Edit pressed => create copy of the form and change to inputs.
  • Cancel pressed => Remove the copy
  • Save pressed => Map the copy to the orignal form, then local storage save it (How to save in localstorage). I suggest you make a class for this (How to create a class).

I'm guessing point 4 is when you reload the page, you want the form to get the info from the local storage. If you have done the mapping correctly, you can use the same method for this (Check if localstorage key exist).

Second approach

You will need to create a temp objects where you save the old versions of the form. When cancel is pressed you revert them by mapping them back to the form.

Common uses

  1. class objects with the properties from your form
  2. mapping method where the parameter is an object of type <your_class>
  3. Checking if local storage exist and if so to map with point 2.
  4. Saving the object in the local storage.

Third approach

This will be a little bit more difficult and too complex for this, you could bind the object to your form. This will allow you to not update anything. This will be done for you (How to data-bind dom elements).

Maxime C.
  • 37
  • 11
  • 1
    Thanks @Maxime. very insighful and thorough. I'll need to up my skills on all those options :) and see what is going to work best. – Said Jan 06 '22 at 23:49