Skip to content

changing cart items quantity in shopping cart using vanilla javascript

I am building an eCommerce website with Django and I am trying to change the quantity of items in my shopping cart using pure JavaScript.

I have been able to select and click on the increase and decrease buttons using a query selector, but when I click on any of those buttons only the first item in the cart updates. The remaining buttons do not increase the quantity of the items associated with it.

What should I do?

This is the JavaScript code:

var minusButton = document.getElementsByClassName("btn minus1")
for (var i = 0; i < minusButton.length; i++) {
minusButton[i].addEventListener("click", function(event){
var quantity = document.getElementsByClassName("cart-quantity-input")
for (var i = 0; i < quantity.length; i++) {
var quantity = quantity[i].value--
//console.log(quantity)
 }
})}

This is the HTML code:

<!DOCTYPE HTML> 
<html lang="en">
<head>
    <meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cart</title>
    <link rel="stylesheet" type="text/css" href="{% static 'css/cart.css' %}">
</head>

<body>
<!-- navigation menu -->
{% include "topnav.html" %}

<div class="maincontent">
    <h1 class="hhh1" style="font-size:50px; margin:0px; margin-bottom:30px">Your Cart</h1>
    <div class="centerblock">
    <!-- DYNAMIC CONTENT GOES HERE -->
        <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>
        <div class="cart-items">
        {% for item in items %}
            <div>
                <div class="cart-item cart-column">
                    <img class="cart-item-image" src="{{item.product.imageURL}}" width="100" height="100">
                    <span class="cart-item-title">{{item.product.title}}</span>
                </div>
                <span class="cart-price cart-column">£{{item.product.price}}</span>
                <div class="cart-quantity cart-column">
                    <div class="quantity">
                        <button data-product={{item.product.id}} data-action="remove" id="minus" class="btn minus1 update-cart">-</button>
                        <input class="cart-quantity-input quantity" type="number" id="id_form-0-quantity" name="quantity" min="1" max="5" value="{{item.quantity}}">
                        <button data-product={{item.product.id}} data-action="add" id="plus" class="btn add1 update-cart">+</button>
                        <button class="removeButton" type="button">REMOVE</button>
                    </div>
            {% endfor %}
                </div>
            </div>
            <div class="cart-total">
                <strong class="cart-total-title">Total</strong>
                <span class="cart-total-price">£{{order.get_cart_total}}</span>
            </div>
            <div class="ordersummary">
                <form action="checkout-info" method="post">
                {% csrf_token %}
                <input type="submit" value="CHECKOUT">
                </form>
            </div>
        </div>
    </div>
</div>

{% include "footer.html" %}

<script src="{% static 'js/cart.js' %}" ></script>
<!--<script src="{% static 'js/test.js' %}" ></script>-->

</body>

</html>

Answer

I understand that your intention is to increment or decrement the value cart-quantity-input by one with the minus1 and add1 buttons. However, on your script, for each minus1 button, you are getting all of the cart-quantity-input when you used document.getElementsByClassName (hint: it reads as for current document, get all elements with that class name). To select the box next to those buttons, you need to navigate through the HTML structure. take a look at the script below:

let deductBtnArr = document.getElementsByClassName('minus1');
let addButtonArr = document.getElementsByClassName('add1');

for(let deductBtn of deductBtnArr){
    deductBtn.onclick = function(){
        let currentInputBox = deductBtn.nextElementSibling;
        currentInputBox.value =  currentInputBox.value - 1;
    }
}

for(let addButton of addButtonArr){
    addButton.onclick = () => {
        let currentInputBox = addButton.previousElementSibling;
        currentInputBox.value =  parseInt(currentInputBox.value) + 1;
    }
}

I used element.nextElementSibling and element.previousElementSibling to tell the page that I want the element next to them, which on both cases is the cart-quantity-input box.

Of course, if you add an element between the buttons and the input box, or if you encapsulate them in another element, the script above will fail. There are other navigation functions that are available around. Please check them out.