0

If there is an item already, and the same item is added again then it should show "2 now" beside that grocery item. This number should increase every time the same item is added to the grocery list. Please help me solve this issue. This is my code:

const groceries = document.getElementsByClassName("groceries")[0];
const deleteall=document.getElementById("deleteall");
const allitems=document.getElementById("allitems");
const userinput=document.getElementById("userinput");

deleteall.addEventListener("click",function(){
    allitems.innerHTML="";
})

userinput.addEventListener("keydown",function(event){
    if(event.key == "Enter")
    additem();
})

function additem(){
    var h2= document.createElement("h2");
    h2.innerHTML="-"+ userinput.value;
    if (userinput.value == "") {
        alert("Enter some item");
        return false;
      }
    h2.addEventListener("click",function(){
        if (h2.style.color === "black") {
            h2.style.color = "red";
          } else {
            h2.style.color = "black";
          }
      })
 allitems.insertAdjacentElement("beforeend",h2);
 userinput.value="";
}
ashi kaur
  • 1
  • 2
  • 1
    Keep an array of items separately from your HTML. Then generate the h2 elements (li would be better) from that array. It will then be much easier to solve your problem. – see sharper Apr 19 '21 at 07:05
  • sir, can you please explain it with the help of code? – ashi kaur Apr 19 '21 at 07:20

2 Answers2

2

I would recommend storing everything as objects inside an array and create a render() function that will be called every time a new object is added.

// your code ...
const list = [];

function addItem() {
  list.append({
    name: userinput.value,
    count: 1,
  });
}

function render() {
  const groceries = document.getElementsByClassName("groceries")[0];
  groceries.innerHTML = "";

  for (i in list) {
     const grocery = document.createElement('li');
     grocery.appendChild(document.createTextNode(i.count < 2 ? i.name : `${i.count} ${i.name}s`));
     groceries.appendChild(grocery);
  }
}
motoquick
  • 108
  • 1
  • 7
  • It is highly `inefficient` since you are going to clear DOM and then creating again and again. Why not to update only the selected one. – DecPK Apr 19 '21 at 07:54
0

EFFICIENTLY UPDATE DOM: Why delete all item and then create new elements for each cart item insertion when you can update only the selected/duplicate item in cart ##.

If you'd like to efficiently update the DOM only the matching shopping item then

Set a uuid for each element so that we can search in DOM and update only that particular item not all.

const groceries = document.getElementsByClassName("groceries")[0];
const deleteall = document.getElementById("deleteall");
const allitems = document.getElementById("allitems");
const userinput = document.getElementById("userinput");

function uuidv4() {
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
    var r = (Math.random() * 16) | 0,
      v = c == "x" ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}

const data = [];

function clearData(arr) {
  allitems.innerHTML = "";
}

function createAndAppendListItem({
  text,
  qty,
  uuid
}) {
  const li = document.createElement("li");
  li.dataset.id = uuid;
  li.textContent = `${text} - ${qty}`;
  allitems.appendChild(li);
}

function findParticularNodeAndRepaceData(obj) {
  obj.qty += 1;
  const {
    text,
    qty,
    uuid
  } = obj;
  const element = document.querySelector(`[data-id="${uuid}"]`);
  element.textContent = `${text} - ${qty}`;
}

function additem() {
  if (userinput.value === "") {
    alert("Enter some item");
  } else {
    const text = userinput.value;
    const isExist = data.find((el) => el.text === text);
    if (!isExist) {
      const obj = {
        text,
        qty: 1,
        uuid: uuidv4(),
      };
      data.push(obj);
      createAndAppendListItem(obj);
    } else {
      findParticularNodeAndRepaceData(isExist);
    }
  }
  userinput.value = "";
}

deleteall.addEventListener("click", function() {
  data.splice(0, data.length);
  clearData();
});

userinput.addEventListener("keydown", function(event) {
  if (event.key == "Enter") additem();
});
<h1 class="groceries">SHOPPING LIST</h1>

<input id="userinput" type="text" />
<button id="deleteall">delete all</button>

<h2>All Items</h2>

<ul id="allitems">

</ul>
DecPK
  • 24,537
  • 6
  • 26
  • 42