Shopping Cart Quantity

I’m trying to make a shopping cart and I’ve created the code that was supposed to update the price of total when I update quantity like when I add more quantity like 2,3 or more, but price doesn’t update automatically and I have created function in JavaScript so if you try to put like -1 instead of 1, which is the minimum doesn’t work and i do not know where’s the problem.

Common theme throughout your code is not knowing difference between document.querySelector and document.querySelectorAll.


You have a few problems.

let quantityInputs = document.querySelector(".quantity-input");

quantityInputs is not a NodeList. It is just an element object.

You have a similar issue with the following line:

let cartRows = cartItemContainer.querySelector(".cart-row");

Once you resolve those two issues, then you have a completely different issue. If you notice, your existing HTML has a div with class=“cart-row” (seen below):

        <div class="cart-row">
            <span class="cart-item cart-header cart-column">ITEM</span>
            <span class="cart-price cart-header cart-column">PRICE</span>
            <span class="cart-quantity cart-header cart-column">QUANTITY</span>
       </div>

So, inside the for loop, the following line makes no sense:

let priceElement = cartRow.querySelector(".shop-price");

None of those span elements have a class = “shop-price”.

For that first div you currently have added class=“cart-row”, I suggest changing it to something like class="cart-header-row" and then you will need to use a different selector all together you capture what appears to be a div with class=“olp” (see below). That div holds and div which holds the span elements with classes of “shop-price” and “quantity-input”.

<div class="olp">
  <div class="lakn">
    <img class="shop-item-cart" src="https://www.gettyimages.ca/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg">
    <span class="shop-title">Product 1</span>
    <span class="shop-price">$19.99</span>
    <input class="quantity-input" type="number" value="1">
    <button class="delete-cart">X</button>
  </div>
</div>

You just need to make sure you are targeting the correct elements.

Suggestion: I would learn to use Codepen’s Tidy HTML feature, to format your code with proper indentations. It will make your code easier to read by you and others helping you.

  1. let quantityInputs is not a NodeList. It is just an element object.
    ------ I still don’t know how to solve this, is problem with my CSS class or variable ?
  2. You have a similar issue with the following line:
    let cartRows = cartItemContainer.querySelector(".cart-row");
    ----- I have created this variable where I have created Item,Price,Quantity so it would loop these 3 classes
  3. Once you resolve those two issues, then you have a completely different issue. If you notice, your existing HTML has a div with class=“cart-row” (seen below):
        <div class="cart-row">
            <span class="cart-item cart-header cart-column">ITEM</span>
            <span class="cart-price cart-header cart-column">PRICE</span>
            <span class="cart-quantity cart-header cart-column">QUANTITY</span>
       </div>

So, inside the for loop, the following line makes no sense:

let priceElement = cartRow.querySelector(".shop-price");

------ “shop-price” class I have selected that class from the product example “Product 1” I have added and I was thinking if I choose “cart-price” class then there was no price to calculate only text" Price".

Or could you update my Codepen code with your solution so I would know more easier what you changed if you don’t mind?

You need to add some console.log statements throughout your code, so you can get an idea of what you are and are not selecting with querySelector and querySelectorAll.

If this is for a real world application, there are some security issues you need to keep in mind.

While it’s nice to see the subtotals and totals get updated in real-time on your browser when you adjust quantities, you must/need to do a re-calculation when the cart is submitted to the backend, retrieving item prices from your database.

If you’re only relying on the computed totals on the html form, that’s a bad idea. Someone can fill up their cart, change the item prices and totals on the html form before submitting to your server, and you/your client just lost money.

If this is just an academic exercise, carry on… :slight_smile:

Yeah that’s a good suggestion, but right now I’m only trying with HTML&CSS and JavaScript as a beginner

Because there is no such method as getElementByClassName. There is a getElementsByClassName, which are using successfully already in your project.

Also, you will find another error after fixing this one, because append is only available in jQuery. There is an appendChild method, but it is only applicable to an element and not a NodeList like cartItems.

@RandellDawson


Replaced one line getElementByClassName with getElementsByClassName and the rest are all getElementsByClassName.
— Looks like it’s working after changing that you suggested and Console Log it’s showing me price so looks good for now thank you :slight_smile:
Btw @RandellDawson any idea why my input button doesn’t work when I try add more than 1 quantity like 2,3 and more it doesn’t update the price and if I remove the product it doesn’t update the price too and it doesn’t show any errors in Console Log when I try to check for any errors to solve?
This was working before I started adding code for to add products in cart when I click Add To Cart

Anyone can try and help me why button remove “X” doesn’t work for product when i add from button “Add to Cart”, but when I remove from current cart it works and it doesn’t work too when I try to update quantity?

Inside addItemToCart, you never add an event listener to the “X” button which would call removeCartItem

Related to the reason I gave above.

1 Like

@RandellDawson
I tried to add event listener to function addItemToCart but now it doesn’t add product to cart when i click button Add To Cart, am I doing wrong ?

function addItemToCart(title, price, imageSrc) {
    let cartRow = document.createElement('div');
    cartRow.classList.add('lakn');
    cartRow.innerText = title;
    let cartItems = document.getElementsByClassName('cart-row-item')[0];
    let cartItemNames = cartItems.getElementsByClassName('shop-item-title');
    for (let i = 0; i < cartItemNames.length; i++) {
        if (cartItemNames[i].innerText === title ) {
     alert ('This product is already added')
    return 
    }
}
button.addEventListener('click', removeCartItem)

That will not add the event listener to the button nested in the cartRow element. Since you need to add the event listener when the item is added to the cart, then you must first realize the code to add the event listener must reside inside the addItemToCart function.

You also want to add the event listener after the button code is added to the cartRow element. Where does that happen?

Finally, think about how you could use querySelector here to target a button element inside the cartRow element you created inside the function.

Yeah finally made it and problem solved, but i have 2 last questions if you or anyone else could help me.

  1. I want to remove current product called “Product 1”, from cart so then cart would be empty and I would add product “Album 1” to appear only when I add from button “Add to Cart” and the current product to be removed? Tried to remove entire html elements from product “Product 1”, but then it showed me errors .
  2. When I add 2 product from “Add to Cart button” with 2 products it doesn’t go out of the height of cart box, but when I add another 3 or more it goes down and doesn’t use height of cart ?
    So I would like when I add 2,3 or more products to not go out from height of cart and use blue background of cart, any idea what should i add in CSS or JavaScript ?
    https://codepen.io/beh4r/pen/eXwVbz

If you don’t want any items to appear in the cart, then just remove them from the HTML. Your current code adds a div with class=“lakn”, so remove that div.

Your current click-cart class selector has a fixed width of 245px. You could try using the min-height property and still use the 245px if you wanted.

On a side note, on a smaller screen, the cart overlaps the Album 1 item in case you were not aware. It is because of the way you are using position: absolute inside the cart class selector.

I removed the “lakn” class but looks i removed and different elements and now cart is empty thanks.
Changed height to min-height and it 3 or more products are using cart height so that’s good, but any idea about button “Checkout” “Clear”, and total to make it show always at the bottom of each new product line ? Will it work with sticky position ?