peter
peter

Reputation: 33

counter value is increasing from other element

I have a problem with the function below. It's taking the data from JSON and it's creating a menu item. The problem is when there are more than 2 menu items, and I try to increase the quantity of the first item then the value of the second item is increasing.

function ShowTheMenu(theCategoryId) {
        var parentEl = document.getElementById("itemlist");
        ClearMenu();
        for (let i = 0; i < data.length; i++) {
            if (data[i].KategorijaBroj == theCategoryId) {
                // MAIN PARENT
                var itemBox = document.createElement("div");
                itemBox.classList.add("itembox");

                var itemImage = document.createElement("img");
                itemImage.classList.add("itemimage");
                itemImage.src = "/menuitemsimages/" + data[i].Image;

                var itemContent = document.createElement("div");
                itemContent.classList.add("itemcontent");

                var itemTitle = document.createElement("h3");
                itemTitle.classList.add("itemtitle");
                itemTitle.innerHTML = data[i].Title;

                var itemPrice = document.createElement("p");
                itemPrice.classList.add("itemprice");
                itemPrice.innerHTML = "$" + data[i].Price;


                var itemQnt = document.createElement("p");
                itemQnt.classList.add("quantity");
                itemQnt.innerHTML = "Quantity";

                var buttonsBox = document.createElement("div");
                buttonsBox.classList.add("divcontrolbtns");

                var itemQuantity = 0;
                var quantityValue = document.createElement("div");
                quantityValue.innerHTML = itemQuantity;

                var increaseBtn = document.createElement("div");
                increaseBtn.classList.add("controlbtns");
                increaseBtn.innerHTML = "+";
                increaseBtn.addEventListener("click", function () {
                    if(itemQuantity < 10) {
                        itemQuantity++;
                    }
                    quantityValue.innerHTML = itemQuantity;
                })

                var decreaseBtn = document.createElement("div");
                decreaseBtn.classList.add("controlbtns");
                decreaseBtn.innerHTML = "-";
                decreaseBtn.addEventListener("click", function () {
                    if(itemQuantity > 0) {
                        itemQuantity--;
                    }
                    quantityValue.innerHTML = itemQuantity;
                })

                
                var itemAddToCart = document.createElement("button");
                itemAddToCart.classList.add("btn-add-to-cart");
                itemAddToCart.textContent = "Add to cart";

                var itemDesc = document.createElement("p");
                itemDesc.classList.add("itemdesc");
                itemDesc.innerHTML = data[i].Description;

               
                itemBox.appendChild(itemImage);

                itemContent.appendChild(itemTitle);
                itemContent.appendChild(itemDesc);
                itemContent.appendChild(itemPrice);
                itemContent.appendChild(itemAddToCart);
                itemContent.appendChild(itemQnt);

                buttonsBox.appendChild(increaseBtn);
                buttonsBox.appendChild(quantityValue);
                buttonsBox.appendChild(decreaseBtn);


                itemContent.appendChild(buttonsBox);

                itemBox.appendChild(itemContent);

                parentEl.appendChild(itemBox);
            }
        }

    }

IMAGE

What should I do in order for the chosen menu item value to be changed?

Upvotes: 2

Views: 114

Answers (2)

Olavo Mello
Olavo Mello

Reputation: 573

Try to do something like this bellow. I try to use same HTML structure that you use but to be honest, I suggest that you change a little bit ;)

      <!DOCTYPE html>
      <html>
        <head>
          <script>
            // Qt
            var quantity = new Array();

            function ShowTheMenu(theCategoryId) {
              // Clear menu
              // ClearMenu();

              // bt+
              increaseBtn = (i) => {
                // Item target
                let item = document.getElementById('item_' + i);
                // Qt target
                let qtSpan = item.getElementsByClassName('qt');
                // Qt
                let qt = parseInt(qtSpan[0].innerHTML);
                // Fix some errors
                if (qt === undefined || !qt) qt = 0;
                // Increase
                if (qt < 10) qt++;
                // Update
                qtSpan[0].innerHTML = qt;
              };
              // bt-
              decreaseBtn = (i) => {
                // Item target
                let item = document.getElementById('item_' + i);
                // Qt target
                let qtSpan = item.getElementsByClassName('qt');
                // Qt
                let qt = parseInt(qtSpan[0].innerHTML);
                // Fix some errors
                if (qt === undefined || !qt) qt = 0;
                // Decrease
                if (qt > 0) qt--;
                // Update
                qtSpan[0].innerHTML = qt;
              };

              //
              var data = new Array();
              data[0] = {
                Image:
                  'https://s2.glbimg.com/WcYUQNaattnUf7d8U8MUBfk7loU=/620x430/e.glbimg.com/og/ed/f/original/2015/10/30/pizza.jpg',
                KategorijaBroj: 1,
                Title: 'Delicious Pizza',
                Price: 10,
                Description: 'Description test',
              };

              for (let i = 0; i < data.length; i++) {
                if (data[i].KategorijaBroj == theCategoryId) {
                  // Img
                  let img = data[i].Image; // '/menuitemsimages/' + data[i].Image;
                  // Title
                  let title = data[i].Title;
                  // Price
                  let price = '$' + data[i].Price;
                  // Description
                  let desc = data[i].Description;
                  // Qtd
                  let qt = 2;

                  // Matriz
                  let newItem = `<div id="item_${i}" class="itembox">
                                      <div class="itemcontent">
                                        <img src="${img}" border=0 width=100/>
                                        <h3 class="itemtitle">${title}</h3>
                                        <p class="itemprice">${price}</p>
                                        <div class="quantity">
                                            <span>Quantity : </span>
                                            <span class="qt">${qt}</span>
                                        </div>
                                        <div class="controlbtns">
                                          <button class="addbtn" onClick="increaseBtn(${i})">+</button>
                                          <button class="removebtn" onClick="decreaseBtn(${i})">-</button>
                                        </div>
                                        <button class="btn-add-to-cart">Add to cart</button>
                                        <p class="description">${desc}</p>
                                      </div>
                                  </div>`;

                  // Get the menulist itens
                  let parentEl = document.getElementById('itemlist');
                  // Add item
                  parentEl.insertAdjacentHTML('beforeend', newItem);
                }
              }
            }
          </script>
        </head>
        <body>
          <div id="itemlist"></div>
          <script>
            ShowTheMenu(1);
          </script>
        </body>
      </html>

Upvotes: 2

Producdevity
Producdevity

Reputation: 882

It's because both items are sharing the same variable, in this case, itemQuantity.

Option 1

If they all should have their own counter I would recommend using an object for tracking this.

const itemQuantity = {
  'item1': 2,
  'item2': 5
}

if you add some unique class or id to the element you can use this in your onclick event to use as a key. (Where I used 'item1' and 'item2')

Option 2

If you create a function that does everything that's inside your for loop and then just call that function it should also work. This works because every function then creates its own scoped variable of itemQuanity.

Go with whatever options feel best for now. How to manage data in your frontend has a lot of different ways and opinions. You'll quickly discover what works best in what scenario.


What Olavo Mello is mentioning in his answer could still make your code better. using string literals for small HTML snippets is often more readable than using document.createElement(). I would recommend fixing your counter issue first and then look if you could improve your code with Olavo Mello's answer in mind. Good luck :)

Upvotes: 1

Related Questions