I_love_vegetables
I_love_vegetables

Reputation: 1341

How to update created elements?

I have this simple function that will create a paragraph.

function appendElements() {
  const input = document.getElementById("myInput");
  const createDiv = document.createElement("div");
  createDiv.classList.add("myDiv");
  const createP = document.createElement("P");
  createP.classList.add("myParagraph");
  createP.innerHTML = input.value;
  createDiv.appendChild(createP);
  const div = document.getElementById("examplediv");
  div.appendChild(createDiv);
}

And another function that will sum the innerHTML of the divs, and create a div element for the result.

function calculateSum() {
  let div = document.getElementsByClassName("myParagraph");
  let array = new Array;
  for (var i = 0; i <div.length; i++) {
    array.push(div[i].innerHTML);
  }

  let numberedArray = array.map((i) => Number(i));

  const sumArray = numberedArray.reduce(function(a, b){
        return a + b;
      }, 0);
  
  const createElement = document.createElement("div");
  createElement.innerHTML = sumArray;
  document.getElementById("divForAvg").appendChild(createElement);
}

And the last function that will change the innerHTML of the paragraph element when clicked.

function editELement() {
  const input2 = document.getElementById("myInput2")
    let items = document.getElementsByClassName("myParagraph");
        for(var i = 0; i < items.length; i++){
            items[i].onclick = function(){
            items[i].innerHTML = input2.value;
          }
        }
}

So basically when I create some paragraphs and execute the second function, the second function will calculate the sum of the paragraphs and create a div with the sum inside.

What I want is when I remove one of the paragraph elements or edit them, I want the previously created divs to update(recalculate the sum), I have literally no idea on how to do this.

Upvotes: 0

Views: 868

Answers (2)

KooiInc
KooiInc

Reputation: 123016

Let's try this using event delegation. I have interpreted what I think you are looking for (note: it's exemplary, but it may give you an idea for your code) and reduced your code a bit for the example. Note the 2 different ways to create new elements (insertAdjacentHTML and Object.assign).

You can play with the code @Stackblitz.com.

document.addEventListener("click", handle);

function handle(evt) {
  if (evt.target.id === "create") {
    return appendInputValueElement();
  }
  if (evt.target.classList.contains("remove")) {
    return removeThis(evt.target);
  }
  if (evt.target.id === "clear") {
    document.querySelector("#accumulated ul").innerHTML = "";
    return true;
  }
}

function appendInputValueElement() {
  const input = document.querySelector(".myInput");
  const div = document.querySelector("#exampleDiv");
  exampleDiv.insertAdjacentHTML("beforeEnd", `
    <div class="myDiv">
      <button class="remove">remove</button>
      <span class="myParagraph">${input.value || 0}</span>
    </div>  
  `);
  calculateSum();
}

function removeThis(elem) {
  elem.closest(".myDiv").remove();
  calculateSum();
}

function calculateSum() {
  const allParas = [...document.querySelectorAll(".myParagraph")];
  const sum = allParas.reduce( (acc, val) => acc + +val.textContent, 0);
  document.querySelector("#accumulated ul")
    .append(Object.assign(document.createElement("li"), {textContent: sum}));
  document.querySelector(".currentSum").dataset.currentSum = sum;
  
  if (sum < 1) {
    document.querySelector("#accumulated ul").innerHTML = "";
  }
}
.currentSum::after {
  content: ' 'attr(data-current-sum);
  color: green;
  font-weight: bold;
}

.myParagraph {
  color: red;
}

.accSums, .currentSum, .myDiv {
  margin-top: 0.3rem;
}
<div>
 A number please: <input class="myInput" type="number" value="12">
 <button id="create">create value</button>
</div>
<div class="currentSum" data-current-sum="0">*Current sum</div>
<p id="exampleDiv"></p>
<div id="accumulated">
  <div class="accSums">*Accumulated sums</div>
  <ul></ul>
  <button id="clear">Clear accumulated</button>
</div>

Upvotes: 3

Fakt309
Fakt309

Reputation: 861

i've changed calculateSum you can call it when you edited paragraph. If summParagraph doesn't exists then we create it.

function calculateSum() {
  let div = document.getElementsByClassName("myParagraph");
  let array = new Array;
  for (var i = 0; i <div.length; i++) {
    array.push(div[i].innerHTML);
  }

  let numberedArray = array.map((i) => Number(i));

  const sumArray = numberedArray.reduce(function(a, b){
        return a + b;
      }, 0);
  
  if (!document.getElementById("summParagraph")) {
    const createElement = document.createElement("div");
    createElement.setAttribute("id", "summParagraph");
    document.getElementById("divForAvg").appendChild(createElement);
  }
  
  document.getElementById("summParagraph").innerHTML = summArray;
}

Upvotes: 1

Related Questions