skip to Main Content

I’m currently working on a clothing website as a personal project only dealing with the frontend, trying to get out of tutorial hell. I am having an issue with increasing the quantity of an item. Everytime I try to increase or decrease the quantity of an item instead of the correct price showing in the cart I get an output of $NaN. I feel like it might be an issue with the updateCartTotal function but I can’t seem to find the exact spot that is causing the error. I haven’t gotten very far into the actual programming part of it but this is the code that I have so far. Any kind of suggestions would be helpful.

// Update the price of cart based on the Quantity of items
const quantityChanged = (event) => {
  const input = event.target;
  if (isNaN(input.value) || input.value <= 0) {
    input.value = 1;
  }
  updateCartTotal();
}

const ready = () => {
  // For loop for removing item from cart
  const removeCartItemButton = document.getElementsByClassName('far fa-times-circle');

  for (i = 0; i < removeCartItemButton.length; i++) {
    let button = removeCartItemButton[i];
    button.addEventListener('click', (event) => {
      event.target.parentElement.parentElement.parentElement.remove();
      updateCartTotal();
    })
  }
  // Get the number of items that the product has in the cart
  const quantityInputs = document.getElementsByClassName('cart-quan-input');
  for (let i = 0; i < quantityInputs.length; i++) {
    const input = quantityInputs[i];
    input.addEventListener('change', quantityChanged);
  }
}

// Check if Dom is loaded so no errors appear
if (document.readyState == 'loading') {
  document.addEventListener('DOMContentLoaded', ready)
} else {
  ready();
}

// Function for updating the cart total
let updateCartTotal = () => {
  const cartItemContainer = document.getElementsByClassName('cart-items')[0];
  const cartRows = cartItemContainer.getElementsByClassName('cart-row');
  let total = 0;
  for (var i = 0; i < cartRows.length; i++) {
    const cartRow = cartRows[i];
    const priceElement = cartRow.getElementsByClassName('cart-price')[0];
    const quantityElement = cartRow.getElementsByClassName('cart-quan-input')[0];
    const price = parseFloat(priceElement.innerText.replace('$', ""));
    const quantity = quantityElement.value;
    total = total + (price * quantity);
  }
  document.getElementById('total-price').innerText = '$' + total;
  document.getElementById('cart-subtotal').innerText = '$' + total;
}

const sendProduct = () => {

}
<script src="https://kit.fontawesome.com/2480d3976a.js" crossorigin="anonymous"></script>

<section class="pro-details">
  <table width="100%">
    <thead>
      <tr>
        <td>Remove</td>
        <td>Image</td>
        <td>Product</td>
        <td>Price</td>
        <td>Quantity</td>
        <td>Subtotal</td>
      </tr>
    </thead>
    <tbody class="cart-items">
      <tr class="cart-row">
        <td><a href="#"><i class="far fa-times-circle"></i></a></td>
        <td><img class="table-img" src="img/north-face-puffer.png"></td>
        <td>South Face Puffer</td>
        <td class="cart-price">$90.00</td>
        <td class="cart-quan-input"><input type="number" value="1"></td>
        <td>$90.00</td>
      </tr>
    </tbody>
  </table>
</section>

<section class="cart-total">
  <h3>Cart Total</h3>
  <table>
    <tr>
      <td>Cart Subtotal</td>
      <td id="cart-subtotal">$95</td>
    </tr>
    <tr>
      <td>Shipping</td>
      <td>Free</td>
    </tr>
    <tr>
      <td>Total</td>
      <td id="total-price">$95</td>
    </tr>
  </table>

  <button type="submit">Checkout</button>
</section>

3

Answers


  1. How about to set a ID or Name to the ‘< input type="number" value="1" >’ element directly, like ‘cart-quantity’ etc.., then you’d able to read or write the value by document.getElementById(‘cart-quantity’).value

    Login or Signup to reply.
  2. You were not accessing the input field in the selector.

    Please delegate and grab the values by navigating within one row

    The getElementsByTagName or getElementsByClassName are very clumsy compared to the querySelector from the row.

    Note I gave the remove link a class as well as the last cell in the row

    window.addEventListener('DOMContentLoaded', () => {
      const cartItemContainer = document.querySelector('.cart-items'); // tbody
      cartItemContainer.addEventListener('click', (e) => {
        const tgt = e.target.closest('.remove');
        if (!tgt) return; // not the remove button
        tgt.closest('tr').remove(); // remove the row
        updateCartTotal();
      });
      const updateCartTotal = () => { // Function for updating the cart total
        const total = Array.from(cartItemContainer.querySelectorAll('tr'))
          .map(cartRow => {
            const priceElement = cartRow.querySelector('.cart-price');
            const quantityElement = cartRow.querySelector('.cart-quan-input input');
            const subTotalCell =  cartRow.querySelector('.subTotal');
            const price = parseFloat(priceElement.textContent.trim().slice(1));
            console.log(price)
            const quantity = +quantityElement.value; // not really necessary to cast since we multiply
            const subTotal = price * quantity;
            subTotalCell.textContent = '$' + subTotal;
            return subTotal; // for summing
          })
          .reduce((a, b) => a + b); // sum
         
        document.getElementById('cart-subtotal').textContent = '$' + total.toFixed(2);
        document.getElementById('total-price').textContent = '$' + total.toFixed(2); // plus shipping
      };
    
      cartItemContainer.addEventListener('change', updateCartTotal);
    
      updateCartTotal();
    
      const sendProduct = () => {
      }
    
    })
    <script src="https://kit.fontawesome.com/2480d3976a.js" crossorigin="anonymous"></script>
    
    <section class="pro-details">
      <table width="100%">
        <thead>
          <tr>
            <td>Remove</td>
            <td>Image</td>
            <td>Product</td>
            <td>Price</td>
            <td>Quantity</td>
            <td>Subtotal</td>
          </tr>
        </thead>
        <tbody class="cart-items">
          <tr class="cart-row">
            <td><a href="#" class="remove"><i class="far fa-times-circle"></i></a></td>
            <td><img class="table-img" src="img/south-face-puffer.png"></td>
            <td>South Face Puffer</td>
            <td class="cart-price">$90.00</td>
            <td class="cart-quan-input"><input type="number" value="1"></td>
            <td class="subTotal">$0.00</td>
          </tr>
          <tr class="cart-row">
            <td><a href="#" class="remove"><i class="far fa-times-circle"></i></a></td>
            <td><img class="table-img" src="img/north-face-puffer.png"></td>
            <td>North Face Puffer</td>
            <td class="cart-price">$100.00</td>
            <td class="cart-quan-input"><input type="number" value="1"></td>
            <td class="subTotal">$0.00</td>
          </tr>
        </tbody>
      </table>
    </section>
    
    <section class="cart-total">
      <h3>Cart Total</h3>
      <table>
        <tr>
          <td>Cart Subtotal</td>
          <td id="cart-subtotal">$0.00</td>
        </tr>
        <tr>
          <td>Shipping</td>
          <td>Free</td>
        </tr>
        <tr>
          <td>Total</td>
          <td id="total-price">$0.00</td>
        </tr>
      </table>
    
      <button type="submit">Checkout</button>
    </section>
    Login or Signup to reply.
  3. You are dealing with HTML collection when using getElementsByClassName. Your quantityElement is a td that contains your input so you need to get your input value as well ( I added console.log(quantityElement) FYI. In order to get the input value you need to select it again with let theQuantity = quantityElement.querySelector(‘input’).value (I console.log it as well)

    // Update the price of cart based on the Quantity of items
    const quantityChanged = (event) => {
      const input = event.target;
      if (isNaN(input.value) || input.value <= 0) {
        input.value = 1;
      }
      updateCartTotal();
    }
    
    const ready = () => {
      // For loop for removing item from cart
      const removeCartItemButton = document.getElementsByClassName('far fa-times-circle');
    
      for (i = 0; i < removeCartItemButton.length; i++) {
        let button = removeCartItemButton[i];
        button.addEventListener('click', (event) => {
          event.target.parentElement.parentElement.parentElement.remove();
          updateCartTotal();
        })
      }
      // Get the number of items that the product has in the cart
      const quantityInputs = document.getElementsByClassName('cart-quan-input');
      for (let i = 0; i < quantityInputs.length; i++) {
        const input = quantityInputs[i];
        input.addEventListener('change', quantityChanged);
      }
    }
    
    // Check if Dom is loaded so no errors appear
    if (document.readyState == 'loading') {
      document.addEventListener('DOMContentLoaded', ready)
    } else {
      ready();
    }
    
    // Function for updating the cart total
    let updateCartTotal = () => {
      const cartItemContainer = document.getElementsByClassName('cart-items')[0];
      const cartRows = cartItemContainer.getElementsByClassName('cart-row');
      let total = 0;
      for (var i = 0; i < cartRows.length; i++) {
        const cartRow = cartRows[i];
        const priceElement = cartRow.getElementsByClassName('cart-price')[0];
        const quantityElement = cartRow.getElementsByClassName('cart-quan-input')[0];
        console.log(quantityElement)
        let theQuantity = quantityElement.querySelector('input').value
        console.log(theQuantity)
        const price = parseFloat(priceElement.innerText.replace('$', ""));
      
      
    
        total = total + (price * theQuantity);
        console.log(total)
      }
      document.getElementById('total-price').innerText = '$' + total;
      document.getElementById('cart-subtotal').innerText = '$' + total;
    }
    
    const sendProduct = () => {
    
    }
    <section class="pro-details">
        <table width="100%">
          <thead>
            <tr>
              <td>Remove</td>
              <td>Image</td>
              <td>Product</td>
              <td>Price</td>
              <td>Quantity</td>
              <td>Subtotal</td>
            </tr>
          </thead>
          <tbody class="cart-items">
            <tr class="cart-row">
              <td><a href="#"><i class="far fa-times-circle"></i></a></td>
              <td><img class="table-img" src="img/north-face-puffer.png"></td>
              <td>South Face Puffer</td>
              <td class="cart-price">$90.00</td>
              <td class="cart-quan-input"><input type="number" value="1"></td>
              <td>$90.00</td>
            </tr>
          </tbody>
        </table>
      </section>
      
      <section class="cart-total">
        <h3>Cart Total</h3>
        <table>
          <tr>
            <td>Cart Subtotal</td>
            <td id="cart-subtotal">$95</td>
          </tr>
          <tr>
            <td>Shipping</td>
            <td>Free</td>
          </tr>
          <tr>
            <td>Total</td>
            <td id="total-price">$95</td>
          </tr>
        </table>
      
        <button type="submit">Checkout</button>
      </section>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search