简体   繁体   中英

'Remove item from cart' and 'manage Quantity' buttons not working when i add more products

I am designing an e-commerce website and since I am not good at DOM manipulation using Javascript so to add Cart functionality to the website I just copied some code from Github. All things are working fine, when I am adding a product it is added to the cart and when I click the remove button or try to increase or decrease the quantity of the product it works fine. The only problem is that when I try to add more products to the products section. The remove buttons and increase/decrease quantity buttons stop working. Can anyone please help me with this?

The Products in the products.html file look something like this.

<div class="image">
            <img src="../images/greytshirt.jpg" alt="thsirt1">
            <h3> 
                <ion-icon name="star"></ion-icon>
                <ion-icon name="star"></ion-icon>
                <ion-icon name="star"></ion-icon>
                <ion-icon name="star"></ion-icon>
                <ion-icon name="star-outline"></ion-icon>
            </h3>
            <h3>Grey Tshirt 
            </h3>
            <h3>$15,00</h3>
            <a class="add-cart cart1" href="#">Add to Cart</a>
            <input type="hidden" value="15"/>
        </div>
        <div class="image">
            <img src="../images/greyhoddie.jpg" alt="thsirt1">
            <h3> 
                <ion-icon name="star"></ion-icon>
                <ion-icon name="star"></ion-icon>
                <ion-icon name="star"></ion-icon>
                <ion-icon name="star-half"></ion-icon>
            </h3>
            <h3>Grey Hoddie</h3>
            <h3>$20,00</h3>
            <a class="add-cart cart2" href="#">Add to Cart</a>
            <input type="hidden" value="20"/>
        </div>

Main.js file(All functions are implemented in this file)

/*------------------------------------------------Js for cart related functionalities------------------------------------------------*/
let carts = document.querySelectorAll('.add-cart');

let products = [ 
    {
        name: "Grey Tshirt",
        tag: "greytshirt",
        price: 15,
        inCart: 0
    },
    {
        name: "Grey Hoddie",
        tag: "greyhoddie",
        price: 20,
        inCart: 0
    },
    {
        name: "Black Tshirt",
        tag: "blacktshirt",
        price: 15,
        inCart: 0
    },
    {
        name: "Black Hoddie",
        tag: "blackhoddie",
        price: 20,
        inCart: 0
    }
];

for(let i=0; i< carts.length; i++) {
    carts[i].addEventListener('click', () => {
        console.log(products[i]);
        cartNumbers(products[i]);
        totalCost(products[i]);
    });
}

function onLoadCartNumbers() {
    let productNumbers = localStorage.getItem('cartNumbers');
    if( productNumbers ) {
        document.querySelector('.cart span').textContent = productNumbers;
    }
}

function cartNumbers(product, action) {
    let productNumbers = localStorage.getItem('cartNumbers');
    productNumbers = parseInt(productNumbers);

    let cartItems = localStorage.getItem('productsInCart');
    cartItems = JSON.parse(cartItems);

    if( action ) {
        localStorage.setItem("cartNumbers", productNumbers - 1);
        document.querySelector('.cart span').textContent = productNumbers - 1;
        console.log("action running");
    } else if( productNumbers ) {
        localStorage.setItem("cartNumbers", productNumbers + 1);
        document.querySelector('.cart span').textContent = productNumbers + 1;
    } else {
        localStorage.setItem("cartNumbers", 1);
        document.querySelector('.cart span').textContent = 1;
    }
    setItems(product);
}

function setItems(product) {
    // let productNumbers = localStorage.getItem('cartNumbers');
    // productNumbers = parseInt(productNumbers);
    let cartItems = localStorage.getItem('productsInCart');
    cartItems = JSON.parse(cartItems);

    if(cartItems != null) {
        let currentProduct = product.tag;
    
        if( cartItems[currentProduct] == undefined ) {
            cartItems = {
                ...cartItems,
                [currentProduct]: product
            }
        } 
        cartItems[currentProduct].inCart += 1;

    } else {
        product.inCart = 1;
        cartItems = { 
            [product.tag]: product
        };
    }

    localStorage.setItem('productsInCart', JSON.stringify(cartItems));
}

function totalCost( product, action ) {
    let cart = localStorage.getItem("totalCost");

    if( action) {
        cart = parseInt(cart);

        localStorage.setItem("totalCost", cart - product.price);
    } else if(cart != null) {
        
        cart = parseInt(cart);
        localStorage.setItem("totalCost", cart + product.price);
    
    } else {
        localStorage.setItem("totalCost", product.price);
    }
}

function displayCart() {
    let cartItems = localStorage.getItem('productsInCart');
    cartItems = JSON.parse(cartItems);

    let cart = localStorage.getItem("totalCost");
    cart = parseInt(cart);

    let productContainer = document.querySelector('.products');
    
    if( cartItems && productContainer ) {
        productContainer.innerHTML = '';
        Object.values(cartItems).map( (item, index) => {
            productContainer.innerHTML += 
            `<div class="product"><ion-icon name="close-circle"></ion-icon><img src="../images/${item.tag}.jpg" />
                <span class="sm-hide">${item.name}</span>
            </div>
            <div class="price sm-hide">$${item.price},00</div>
            <div class="quantity">
                <ion-icon class="decrease " name="arrow-dropleft-circle"></ion-icon>
                    <span>${item.inCart}</span>
                <ion-icon class="increase" name="arrow-dropright-circle"></ion-icon>   
            </div>
            <div class="total">$${item.inCart * item.price},00</div>`;
        });

        productContainer.innerHTML += `
            <div class="basketTotalContainer">
                <h4 class="basketTotalTitle">Basket Total</h4>
                <h4 class="basketTotal">$${cart},00</h4>
                <input class="empty" onclick="emptyCart()" value="Empty Cart">
            </div>
            <div class="checkout"><button class="placeorder btn" onclick="checkout()">Place Order</button></div>`

        deleteButtons();
        manageQuantity();
    }
}

function manageQuantity() {
    let decreaseButtons = document.querySelectorAll('.decrease');
    let increaseButtons = document.querySelectorAll('.increase');
    let currentQuantity = 0;
    let currentProduct = '';
    let cartItems = localStorage.getItem('productsInCart');
    cartItems = JSON.parse(cartItems);

    for(let i=0; i < increaseButtons.length; i++) {
        decreaseButtons[i].addEventListener('click', () => {

            currentQuantity = decreaseButtons[i].parentElement.querySelector('span').textContent;

            currentProduct = decreaseButtons[i].parentElement.previousElementSibling.previousElementSibling.querySelector('span').textContent.toLocaleLowerCase().replace(/ /g,'').trim();


            if( cartItems[currentProduct].inCart > 1 ) {
                cartItems[currentProduct].inCart -= 1;
                cartNumbers(cartItems[currentProduct], "decrease");
                totalCost(cartItems[currentProduct], "decrease");
                localStorage.setItem('productsInCart', JSON.stringify(cartItems));
                displayCart();
            }
        });

        increaseButtons[i].addEventListener('click', () => {
            currentQuantity = increaseButtons[i].parentElement.querySelector('span').textContent;
            currentProduct = increaseButtons[i].parentElement.previousElementSibling.previousElementSibling.querySelector('span').textContent.toLocaleLowerCase().replace(/ /g,'').trim();

            cartItems[currentProduct].inCart += 1;
            cartNumbers(cartItems[currentProduct]);
            totalCost(cartItems[currentProduct]);
            localStorage.setItem('productsInCart', JSON.stringify(cartItems));
            displayCart();
        });
    }
}

function deleteButtons() {
    let deleteButtons = document.querySelectorAll('.product ion-icon');
    let productNumbers = localStorage.getItem('cartNumbers');
    let cartCost = localStorage.getItem("totalCost");
    let cartItems = localStorage.getItem('productsInCart');
    cartItems = JSON.parse(cartItems);
    let productName;

    for(let i=0; i < deleteButtons.length; i++) {
        deleteButtons[i].addEventListener('click', () => {
            productName = deleteButtons[i].parentElement.textContent.toLocaleLowerCase().replace(/ /g,'').trim();
           
            localStorage.setItem('cartNumbers', productNumbers - cartItems[productName].inCart);
            localStorage.setItem('totalCost', cartCost - ( cartItems[productName].price * cartItems[productName].inCart));

            delete cartItems[productName];
            localStorage.setItem('productsInCart', JSON.stringify(cartItems));

            displayCart();
            onLoadCartNumbers();
        })
    }
}

function checkout(){
    emptyCart();
    alert("Your order has been placed successfully.");
}

function emptyCart(){
    localStorage.clear();
    location.reload();
}

onLoadCartNumbers();
displayCart();

And finally, this is the cart.html file

<body>
    {{>header2}}
    <div class="container-products">
        <div class="product-header">
            <div class="cart-h">Your Cart</div>
        </div>
        <div class="products">
        <! -- This section is populated using Javascript -->
        </div>
    </div>
    {{>footer}}
    <script src="js/main.js"></script>
    <script src="js/index.js"></script>
    <script src="https://unpkg.com/ionicons@4.5.10-0/dist/ionicons.js"></script>
</body>

The problem is the event listeners for the click events are being registered to the matching elements before you add the new ones.

One simple solution is to NOT have an event listener for the actual buttons, but instead tie it to document, then just look for the appropriate class on the button.

This answer is very rudimentary, its just to demonstrate the concept. If you notice the buttons are added to the DOM AFTER the event listener, but it still works.

 document.addEventListener("click",function(e){ let btn = e.target; if(btn.className.includes("increase")){ console.log("increase") } else if(btn.className.includes("decrease")){ console.log("decrease") } }); let dest = document.querySelector("#dest"); dest.innerHTML = '<button class="increase">Increase</button><button class="decrease">Decrease</button>';
 <div id="dest"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM