skip to Main Content

I’m currently working on a simple project, basically an online fruit stall. I’m facing an issue right now is that my current JS function can’t trigger the "Add to cart" button to update the shopping cart table (i.e. when I pressed it, nothing happened).

I really need all of y’all help on this, I tried chatGPT but it doesn’t seem to be giving me the right solution. This is my current work. Do note that I’m trying this function on one of the products, hence why I only post the code of the watermelon one

HTML

 <div class="card">
       <div class="sale-badge" id="saleBadge1">Sale!</div>
       <div class="img"><img src="Images/watermelon.jpg" alt=""></div>
       <div class="title">Watermelon</div>
       <div class="price"><span class="strike">$5</span>$2.50</div>
       <div class="btn-container">
          <button class="btn" id="addToCartBtn1" onclick="addToCart('Watermelon', 2.50)">Add to cart</button>
       </div>                
</div>

shopping.js

/* ADD CELL AFTER PRESSING ADD TO CART */
function addToCart(productName, productPrice) {
    console.log(productName + ', ' + productPrice);
    // Get the table body where cart items will be added
    var cartTableBody = document.querySelector('.shopping-cart');
    console.log(cartTableBody)

    // Create a new row for the cart item
    var newRow = cartTableBody.insertRow();
    console.log(newRow)
    
    // Create cells for product name and price
    var productNameCell = newRow.insertCell(0);
    var productPriceCell = newRow.insertCell(1);
    
    // Set the content of the cells
    productNameCell.textContent = productName;
    productPriceCell.textContent = '$' + productPrice.toFixed(2);
}

Current table created with 1 sample row

 <table class="shopping-cart">
                <tbody>
                    <tr>
                        <th style="width: 40px;"></th>
                        <th style="width: 90px;"></th>
                        <th style="width: 500px;">Product</th>
                        <th style="width: 90px;">Price</th>
                        <th style="width: 160px;">Quantity</th>
                        <th style="width: 90px;">Subtotal</th>
                    </tr>
                    <tr>
                        <td class="cross-symbol">
                            <div class="circle"  onclick="deleteRow(this)">&times;</div>
                        </td>
                        <td class="image-cell">
                            <img src="Images/watermelon.jpg">
                        </td>
                        <td>Watermelon</td>
                        <td>$2.50</td>
                        <td>
                            <div class="quantity">
                                <button class="minus">-</button><input type="text" class="number" value="1" min="1"><button class="plus">+</button>
                            </div>
                        </td>
                    </tr>
                </tbody>

Pictures for reference
press "add to cart"should update table like this. I hardcode it so everyone will know what I want

As you can see from the above two images, what I want is to press the "add to cart" of watermelon, and the content of the cards will be updated in the shopping cart corresponding to the header of the table.

Would really appreciate it if someone could help me with this. You can always DM me to discuss! Thanks!

2

Answers


  1. The code starts by selecting all elements with class "card" and setting a "click" event handler for each card.
    The cart and total are obtained via document.getElementById.
    Created a selectedItems object to track selected items with their quantity and price.
    The handleCardClick function handles clicks on cards, adding the selected items to the selectedItems object or increasing their number.
    The updateCart, addItem and removeItem functions update the cart contents and total when adding/removing items.
    Inside the updateCart function, list elements are created to display the selected products in the cart, as well as “+” and “-” buttons that allow you to change the number of products in the cart. Finally, the forEach loop applies an event handler to each card on the page so that users can add products to their cart, and the cart and total interface automatically updates as they do so.

    const cards = document.querySelectorAll('.card');
            const cart = document.getElementById('cart');
            const totalElement = document.getElementById('total'); 
            const selectedItems = {};
    
            function handleCardClick(event) {
                const card = event.currentTarget;
                const itemId = card.id;
                const itemName = card.querySelector('h2').textContent;
                const itemPrice = parseFloat(card.querySelector('.price').textContent); 
    
                if (selectedItems[itemId]) {
                    selectedItems[itemId].count++;
                } else {
                    selectedItems[itemId] = {
                        name: itemName,
                        price: itemPrice,
                        count: 1,
                    };
                }
    
                updateCart();
            }
    
            function updateCart() {
                cart.innerHTML = '';
                let total = 0; 
    
                for (const itemId in selectedItems) {
                    const item = selectedItems[itemId];
                    const listItem = document.createElement('li');
                    const quantityContainer = document.createElement('div'); 
                    const quantityText = document.createElement('span'); 
                    const addButton = document.createElement('button');
                    const subtractButton = document.createElement('button');
    
                    addButton.textContent = '+';
                    subtractButton.textContent = '-';
    
                    quantityText.textContent = item.count; 
    
                    addButton.addEventListener('click', () => {
                        addItem(itemId);
                    });
    
                    subtractButton.addEventListener('click', () => {
                        removeItem(itemId);
                    });
    
                    const hr = document.createElement('hr');
    
                    quantityContainer.appendChild(subtractButton); 
                    quantityContainer.appendChild(quantityText); 
                    quantityContainer.appendChild(addButton); 
                    quantityContainer.appendChild(hr); 
    
                    listItem.textContent = `${item.name} - $${item.price * item.count}`;
                    listItem.appendChild(quantityContainer); 
                    cart.appendChild(listItem);
    
                    total += item.price * item.count; 
                }
    
                totalElement.textContent = `Общая сумма: $${total.toFixed(2)}`; 
            }
    
            function addItem(itemId) {
                if (selectedItems[itemId]) {
                    selectedItems[itemId].count++;
                }
                updateCart();
            }
    
            function removeItem(itemId) {
                if (selectedItems[itemId]) {
                    selectedItems[itemId].count--;
                    if (selectedItems[itemId].count <= 0) {
                        delete selectedItems[itemId];
                    }
                }
                updateCart();
            }
    
            cards.forEach((card) => {
                card.addEventListener('click', handleCardClick);
            });
     * {
          box-sizing: border-box;
          font-family: sans-serif;
      }
    
      body {
          margin: 0;
          padding: 0;
      }
    
      .container {
          display: grid;
          grid-template-columns: 300px 1fr;
          gap: 10px;
          margin: 0 auto;
          padding: 10px;
          max-width: 1100px;
          min-height: 100vh;
      }
    
      aside,
      main {
          border: 1px solid grey;
          padding: 10px;
      }
    
      .cards {
          display: flex;
          flex-direction: row;
          justify-content: space-evenly;
          flex-wrap: wrap;
      }
    
      .card {
          text-align: center;
      }
    <div class="container">
            <aside>
                <aside>
                    <h2>Product Basket</h2>
                    <ul id="cart"></ul>
                    <div id="total">Total Amount: $0</div>
                </aside>
            </aside>
            <main>
                <div class="cards">
                    <div class="card" id="apple1">
                        <img src="http://surl.li/lstbr" alt="apple">
                        <h2>Apple</h2>
                        <p><mark><span class="price">8</span>$</mark></p>
                        <button>Add to cart</button>
                    </div>
                    <div class="card" id="apple2">
                        <img src="http://surl.li/lstby" alt="apple">
                        <h2>Apple</h2>
                        <p><mark><span class="price">9</span>$</mark></p>
                        <button>Add to cart</button>
                    </div>
                    <div class="card" id="banana1">
                        <img src="http://surl.li/lstch" alt="banan">
                        <h2>Banan</h2>
                        <p><mark><span class="price">10</span>$</mark></p>
                        <button>Add to cart</button>
                    </div>
                    <div class="card" id="banana2">
                        <img src="http://surl.li/lstch" alt="banan">
                        <h2>Banan</h2>
                        <p><mark><span class="price">11</span>$</mark></p>
                        <button>Add to cart</button>
                    </div>
                    <div class="card" id="banana3">
                        <img src="http://surl.li/lstch" alt="banan">
                        <h2>Banan</h2>
                        <p><mark><span class="price">12</span>$</mark></p>
                        <button>Add to cart</button>
                    </div>
                    <div class="card" id="cherry1">
                        <img src="http://surl.li/lstco" alt="cherry">
                        <h2>Cherry</h2>
                        <p><mark><span class="price">13</span>$</mark></p>
                        <button>Add to cart</button>
                    </div>
                    <div class="card" id="cherry2">
                        <img src="http://surl.li/lstco" alt="cherry">
                        <h2>Cherry</h2>
                        <p><mark><span class="price">8</span>$</mark></p>
                        <button>Add to cart</button>
                    </div>
                    <div class="card" id="cherry3">
                        <img src="http://surl.li/lstco" alt="cherry">
                        <h2>Cherry</h2>
                        <p><mark><span class="price">8</span>$</mark></p>
                        <button>Add to cart</button>
                    </div>
                    <div class="card" id="grape1">
                        <img src="http://surl.li/lstct" alt="grape">
                        <h2>Grape</h2>
                        <p><mark><span class="price">8</span>$</mark></p>
                        <button>Add to cart</button>
                    </div>
                    <div class="card" id="grape2">
                        <img src="http://surl.li/lstct" alt="grape">
                        <h2>Grape</h2>
                        <p><mark><span class="price">8</span>$</mark></p>
                        <button>Add to cart</button>
                    </div>
                    <div class="card" id="grape3">
                        <img src="http://surl.li/lstct" alt="grape">
                        <h2>Grape</h2>
                        <p><mark><span class="price">8</span>$</mark></p>
                        <button>Add to cart</button>
                    </div>
                </div>
    
    
            </main>
        </div>
    Login or Signup to reply.
  2. Here is an alternative to Dovgal’s solution. I used template strings to generate new DOM elements instead of document.createElement() calls and I also re-used the global prods object to keep track of the ordered quantities in the cart. Apart from that I used delegated event handling within the #cart and #products DOM elements to trigger the calling of the prod2cart() function which adds or removes an item from the cart depending on the value of inc.

    const prods={apples1:["br","Apples 🍏",2.49,0],apples2:["by","Apples 🍎",2.99,0],bananas1:["ch","Bananas 🍌", 3.99,0],cherries1:["co","Cherries 🍒",5.99,0],grapes1:["ct","Grapes 🍇", 4.49,0],grapes2:["ct","Grapes 🍇🍇", 5.99,0]};
    const [cart,products,sum]=["cart","products","sum"].map(id=>document.getElementById(id));
    products.innerHTML=Object.entries(prods).map(([id,[pic,name,price]])=>`<div data-id="${id}"><h2>${name}</h2><img src="http://surl.li/lst${pic}"><br>
    price per kg: ${price}$</div>`).join("<hr>");
    function prod2cart(id,inc){
      let [pic,name,price,qty]=prods[id],
          n=(prods[id][3]+=inc)
          tr=document.getElementById(id);
      if(tr)
       if(!n) tr.remove();
       else {
        tr.querySelector(".qty").textContent=n;
        tr.querySelector(".subttl").textContent=(n*price).toFixed(2);
       }
      else {
       cart.insertAdjacentHTML("beforeend",`<tr id="${id}"><td><img src="https://surl.li/lst${pic}"></td>
       <td>${name}</td>
       <td>${price}</td>
       <td><button data-inc="-1">-</button><span class="qty">${n}</span><button data-inc="1">+</button></div></td>
       <td class="subttl">${(price*n).toFixed(2)}</td>
      </tr>`);
      }
      let total=Object.values(prods).reduce((a,[_,__,pr,n])=>a+pr*n,0);
      sum.textContent=total?`Total: ${total.toFixed(2)}$`:"";
    }
    cart.addEventListener("click",ev=>{
     if(ev.target.tagName!="BUTTON") return;
     let inc=+ev.target.dataset?.inc;
     if (inc) prod2cart(ev.target.closest("tr").id,inc); 
    });
    products.addEventListener("click",ev=>{
      let id=ev.target.closest("div").dataset?.id;
      if(id) prod2cart(id,1);
    })
    #products img {width:100px}
    #cart img {width: 50px}
    input {width:12px}
    #cart, #products {display:inline-block}
    <h1>Shopping cart</h1>
    <table id="cart">
     <thead>
      <tr>
       <th></th>
       <th>Product</th>
       <th>Price</th>
       <th>Quantity</th>
       <th>Subtotal</th>
      </tr>
     </thead>
     <tbody></tbody>
    </table>
    <span id="sum"></span>
    <h1>Products</h1>
    <div id="products">
    </div>

    This implementation does not recreate the whole shopping cart, whenever a single item is changed. Instead it will only recalculate the changed quantities and display them in their allocated spaces.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search