Search code examples
javascripthtmldomupdatescrud

Element text not changing when passing selected textContent and new value to an update function


I'm creating a CRUD page where the user can add, delete and edit text, but I have an issue in updating the text after I select it for edit.

In editText function when I click the edit button the text that was added will pop up inside the input field. When I click on the update button (triggering the updateText function), I can see the text in console log but the corresponding html is not updated.

HTML

<div class="main">
  <form>
    <input type="text" placeholder="search">
  </form>
  <ul></ul>
  <div>
    <input class="add-text" type="text" placeholder="Add Text">
    <button id="add">Add</button>
    <button id="update">update</button>
  </div>
</div>

Javascript

const inputsearch = document.querySelector('form input');
const addInputBtn = document.querySelector('#add');
const update = document.querySelector('#update');

addInputBtn.addEventListener('click', addtext);

function addtext(){
  let li = document.createElement('li');
  let inputadd = document.querySelector('.add-text');
  let addedtext = inputadd.value;
  let h1Tag = '<h1 id="text">'+addedtext+'</h1>';
  let tags = h1Tag + '<button id="delete">Delete</button><button id="edit">Edit</button>';

  if(addedtext == ''){
    alert('please add some text');
    return;
  }else{
    li.innerHTML = tags;
    document.querySelector('ul').appendChild(li);
  }
  li.querySelectorAll('#delete')[0].addEventListener('click', deleteText);
  li.querySelectorAll('#edit')[0].addEventListener('click', editText);
  getlist(li, h1Tag);
  inputadd.value = '';
}


function deleteText(e) {
  e.target.parentNode.remove();
  document.querySelector('.add-text').value = '';
}

function editText(e) {
  let currentText = e.target.parentNode.firstChild.textContent;
  let currentValue = document.querySelector('.add-text');
  currentValue.value = currentText;
  getupdate(currentText, currentValue);

}

function getupdate(currentText, currentValue) {
  update.addEventListener('click', updateText);
  function updateText() {
    currentText = currentValue.value
    console.log(currentText = currentValue.value);
  }
}


function getlist(li, h1Tag) {
inputsearch.addEventListener('keyup', serchText);

  function serchText(e) {
    let typetext = e.target.value.toLowerCase();
    if(h1Tag.toLowerCase().indexOf(typetext) != -1){
      li.style.display = 'block';
    }else{
      li.style.display = 'none';
    }
  }
}

Solution

  • To solve the issue without changing your overall approach, your edit button click needs to get the corresponding element (not just its textContent) and pass it to your getupdate() function to be updated when your update button is clicked. Relatively minor changes to your current functions:

    function editText(e) {
      const currentText = e.target.parentNode.firstChild;
      const currentValue = document.querySelector('.add-text');
      currentValue.value = currentText.textContent;
      getupdate(currentText, currentValue);
    }
    
    function getupdate(currentText, currentValue) {
      update.addEventListener('click', updateText);
      function updateText() {
        currentText.textContent = currentValue.value;
      }
    }
    

    There are some other issues with your code, particularly the creation of multiple elements with the same id (which is malformed and will likely become problematic as you add additional features). Following is a snippet that addresses that issue as well as simplifying some of your functions and fixing the search.

    const search = document.querySelector('form input');
    const input = document.querySelector('.add-text');
    const container = document.querySelector('ul');
    let items = null;
    let currentItem = null;
    const searchItems = (event) => {
      if (items) {
        const s = event.currentTarget.value.toLowerCase();
        for (const item of items) {
          if (item.firstChild.textContent.toLowerCase().indexOf(s) !== -1) {
            item.style.display = 'block';
          } else {
            item.style.display = 'none';
          }
        }
      }
    };
    
    const deleteItem = (event) => {
      currentItem = null;
      event.currentTarget.parentNode.remove();
    };
    
    const editItem = (event) => {
      currentItem = event.currentTarget.parentNode.firstChild;
      input.value = currentItem.textContent;
    };
    
    const updateItem = () => {
      if (currentItem) {
        currentItem.textContent = input.value;
      }
    };
    
    const addItem = () => {
      let val = input.value
      if (val) {
        const li = document.createElement('li');
        let inner = '<h1 class="text">' + val + '</h1>';
        inner += '<button class="delete">Delete</button>';
        inner += '<button class="edit">Edit</button>';
        li.innerHTML = inner;
        container.appendChild(li);
        val = '';
        currentItem = li.firstChild;
        items = document.querySelectorAll('li');
        for (let del of document.querySelectorAll('.delete')) {
          del.addEventListener('click', deleteItem);
        }
        
        for (let edit of document.querySelectorAll('.edit')) {
          edit.addEventListener('click', editItem);
        }
      } else {
        alert('please add some text');
        return;
      }
    };
    
    search.addEventListener('keyup', searchItems);
    document.querySelector('#add').addEventListener('click', addItem);
    document.querySelector('#update').addEventListener('click', updateItem);
    <div class="main">
      <form>
        <input type="text" placeholder="Search">
      </form>
      <ul></ul>
      <div>
        <input class="add-text" type="text" placeholder="Add Text">
        <button id="add">Add</button>
        <button id="update">Update</button>
      </div>
    </div>