简体   繁体   中英

On click, push one item from an an array to another, and change text dependent on items in array

I am trying to set it so that if I click on a button with the class of "addtocart" it will check the id of the button in the HTML document and iterate through the products array objects until it finds the object with the same Id as the button on the element, and then push it to the cart array. I then need to change the innertext of the "cartamnt" span so that based on how many items are added to the cart, text "0 cart" becomes "1 cart", etc..

 //Arrays var products = [{ Price: 20, Name: "Football Helmet", Description: "Titans football helmet", Id: "Titan_a" }, { Price: 15, Name: "Light Blue Shirt", Description: "Titans light blue shirt", Id: "Titan_b" }, { Price: 15, Name: "White Shirt", Description: "Titans white shirt", Id: "Titan_c" }, { Price: 15, Name: "Blue Shirt", Description: "Titans blue shirt", Id: "Titan_d" }, { Price: 25, Name: "Hockey Stick", Description: "Titans hockey stick", Id: "Titan_d" } ]; var cart = []; //All the button variables var addtocart = document.getElementsByClassName("add"); var camount = document.getElementById("cartamnt"); cartamnt.innerText = "0 cart" addtocart.onclick = function(products, cart) { for (var i = 0; i < products.length; i++) { if (addtocart.Id == products.Id) { cart.push(products.Id[i]) cartamnt.innerText = i++ + "cart" } } }
 <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="css/styles.css"> </head> <body> <h1 id="main_title">Titan Sports and Apparel LLC</h1> <div class="main"> <div class="row"> <span href="checkout.html" id="cartamnt">0 cart</span> <br /> </div> <div class="row"> <div class="column"> <h1>Football helmet</h1> <img id="img" src="img/Helmet_A.jpg"> <p>Price: $20</p> <p>Official Titan Sportswear Helmet</p> <button class="add" id="Titan_a">Add to cart</button> <button id="Remove_a">Remove from cart</button> </div> <div class="column"> <h1>Light Blue Shirt</h1> <img id="img" src="img/Shirt_A.jpg"> <p>Price: $15</p> <p>Light blue cotton material Titans shirt</p> <button class="add" id="Titan_b">Add to cart</button> <button id="Remove_b">Remove from cart</button> </div> <div class="column"> <h1>White Shirt</h1> <img id="img" src="img/Shirt_B.jpg"> <p>Price: $15</p> <p>White cotton material Titans shirt</p> <button class="add" id="Titan_c">Add to cart</button> <button id="Remove_c">Remove from cart</button> </div> <div class="column"> <h1>Blue Shirt</h1> <img id="img" src="img/Shirt_C.jpg"> <p>Price: $15</p> <p>Blue cotton material Titans shirt</p> <button class="add" id="Titan_d">Add to cart</button> <button id="Remove_d">Remove from cart</button> </div> <div class="column"> <h1>Hockey Stick</h1> <img id="img" src="img/Stick_A.png"> <p>Price: $25</p> <p>Black Titans hockey stick</p> <button class="add" id="Titan_e">Add to cart</button> <button id="Remove_e">Remove from cart</button> </div> </div> </div> <a href="index.html">Homepage</a> <footer>© Titan Sports and Apparel LLC | Email: TitanSportsApparel@gmail.com</footer> <script src="js/shoppingCart.js"></script> </body> </html>

Your code is a bit messy. I cleaned it a bit to get you started, but I would really suggest you post it at Code Review to learn how you can improve it.

The first thing to notice is that you are using the id of the "add" button to store the id of the product. This is a problem for two reasons:

  1. The purpose of the id attribute is to give the element a unique identifier, not to store data.
  2. You also have a "remove" button, which should remove the product from the cart. With your approach, it will have the same id as the "add" button, which is incorrect since id should be unique. The other way would be to give it a different id, and somehow extract the product id from it in JS, which is really convoluted.

This is why we will use data attributes instead of id to store the product id. For example:

<button class="add" data-product="Titan_a">Add to cart</button>
<button class="remove" data-product="Titan_a">Remove from cart</button>

Now, the problem with your JS is that your addtocart variable is actually an array of all buttons, and not a single button, so you cannot just attach an onclick event to it. You need to iterate over all the buttons and individually attach the onclick event to them.

So we will get something like this:

const addButtons = document.getElementsByClassName("add");
const removeButtons = document.getElementsByClassName("remove");

for (const addButton of addButtons) {
    addButton.addEventListener("click", () => {
         ...
    });
}
for (const removeButton of removeButtons) {
    removeButton.addEventListener("click", () => {
         ...
    });
}

Now it's easy to implement the adding and removing. You don't need to manually loop throw your array, you could simply use the find function and some other useful "built-in" array functions.

Here is a complete working example:

 let products = [{ Price: 20, Name: "Football Helmet", Description: "Titans football helmet", Id: "Titan_a" }, { Price: 15, Name: "Light Blue Shirt", Description: "Titans light blue shirt", Id: "Titan_b" }, { Price: 15, Name: "White Shirt", Description: "Titans white shirt", Id: "Titan_c" }, { Price: 15, Name: "Blue Shirt", Description: "Titans blue shirt", Id: "Titan_d" }, { Price: 25, Name: "Hockey Stick", Description: "Titans hockey stick", Id: "Titan_e" } ]; let cart = []; const addButtons = document.getElementsByClassName("add"); const removeButtons = document.getElementsByClassName("remove"); const amountLabel = document.getElementById("cartamnt"); for (const addButton of addButtons) { addButton.addEventListener("click", () => { let product = products.find(p => p.Id == addButton.dataset.product); cart.push(product); amountLabel.innerText = cart.length + "items"; }); } for (const removeButton of removeButtons) { removeButton.addEventListener("click", () => { const index = cart.findIndex(p => p.Id === removeButton.dataset.product); // index of product to remove cart.splice(index, 1); // removing it amountLabel.innerText = cart.length + "items"; }); }
 <!DOCTYPE html> <html> <body> <h1 id="main_title">Titan Sports and Apparel LLC</h1> <div class="main"> <div class="row"> <span href="checkout.html" id="cartamnt">0 cart</span> <br /> </div> <div class="row"> <div class="column"> <h1>Football helmet</h1> <img id="img" src="img/Helmet_A.jpg"> <p>Price: $20</p> <p>Official Titan Sportswear Helmet</p> <button class="add" data-product="Titan_a">Add to cart</button> <button class="remove" data-product="Titan_a">Remove from cart</button> </div> <div class="column"> <h1>Light Blue Shirt</h1> <img id="img" src="img/Shirt_A.jpg"> <p>Price: $15</p> <p>Light blue cotton material Titans shirt</p> <button class="add" data-product="Titan_b">Add to cart</button> <button class="remove" data-product="Titan_b">Remove from cart</button> </div> <div class="column"> <h1>White Shirt</h1> <img id="img" src="img/Shirt_B.jpg"> <p>Price: $15</p> <p>White cotton material Titans shirt</p> <button class="add" data-product="Titan_c">Add to cart</button> <button class="remove" data-product="Titan_c">Remove from cart</button> </div> <div class="column"> <h1>Blue Shirt</h1> <img id="img" src="img/Shirt_C.jpg"> <p>Price: $15</p> <p>Blue cotton material Titans shirt</p> <button class="add" data-product="Titan_d">Add to cart</button> <button class="remove" data-product="Titan_d">Remove from cart</button> </div> <div class="column"> <h1>Hockey Stick</h1> <img id="img" src="img/Stick_A.png"> <p>Price: $25</p> <p>Black Titans hockey stick</p> <button class="add" data-product="Titan_e">Add to cart</button> <button class="remove" data-product="Titan_e">Remove from cart</button> </div> </div> </div> <a href="index.html">Homepage</a> <footer>© Titan Sports and Apparel LLC | Email: TitanSportsApparel@gmail.com</footer> </body> </html>

This is quick and dirty, but it should do your job:

Note that I added a 'remove' class onto the 'remove from cart' buttons and I put as id attribute the same id (as we need to search by them in the products array). This should work and as a bonus I added an if case for when you have multiple identhical products in the cart but want to remove just one.

I also attached event listeners differently.

const addProductToCard = (e) => {
    const productToAdd = products.find(i => i.Id === e.target.id);
    cart.push(productToAdd);
}

const removeFromCard = (e) => {
    const identical = cart.filter(i => i.Id === e.target.id);

    if (identical.length === 1) {
        cart = cart.filter(i => i.Id !== e.target.id);
    } else {
        cart = [...identical.splice(1), ...cart.filter(i => i.Id !== e.target.id)];
    }
}

document.querySelectorAll('.add').forEach(i => i.addEventListener("click", addProductToCard));
document.querySelectorAll('.remove').forEach(i => i.addEventListener("click", removeFromCard));

You just have to loop over the array and then add event listener as:

addtocart.forEach(btn => {
  btn.addEventListener("click", (e) => {
    const Id = e.target.id;
    const product = products.find(o => o.Id === Id);
    product &&  cart.push({ ...product });
    cartamnt.innerText = cart.length + " cart";
  })
})

 var products = [{ Price: 20, Name: "Football Helmet", Description: "Titans football helmet", Id: "Titan_a" }, { Price: 15, Name: "Light Blue Shirt", Description: "Titans light blue shirt", Id: "Titan_b" }, { Price: 15, Name: "White Shirt", Description: "Titans white shirt", Id: "Titan_c" }, { Price: 15, Name: "Blue Shirt", Description: "Titans blue shirt", Id: "Titan_d" }, { Price: 25, Name: "Hockey Stick", Description: "Titans hockey stick", Id: "Titan_d" } ]; var cart = []; //All the button variables var addtocart = [...document.getElementsByClassName("add")]; var camount = document.getElementById("cartamnt"); cartamnt.innerText = "0 cart" addtocart.forEach(btn => { btn.addEventListener("click", (e) => { const Id = e.target.id; const product = products.find(o => o.Id === Id); product && cart.push({ ...product }); cartamnt.innerText = cart.length + " cart"; }) })
 <h1 id="main_title">Titan Sports and Apparel LLC</h1> <div class="main"> <div class="row"> <span href="checkout.html" id="cartamnt">0 cart</span> <br /> </div> <div class="row"> <div class="column"> <h1>Football helmet</h1> <img id="img" src="img/Helmet_A.jpg"> <p>Price: $20</p> <p>Official Titan Sportswear Helmet</p> <button class="add" id="Titan_a">Add to cart</button> <button id="Remove_a">Remove from cart</button> </div> <div class="column"> <h1>Light Blue Shirt</h1> <img id="img" src="img/Shirt_A.jpg"> <p>Price: $15</p> <p>Light blue cotton material Titans shirt</p> <button class="add" id="Titan_b">Add to cart</button> <button id="Remove_b">Remove from cart</button> </div> <div class="column"> <h1>White Shirt</h1> <img id="img" src="img/Shirt_B.jpg"> <p>Price: $15</p> <p>White cotton material Titans shirt</p> <button class="add" id="Titan_c">Add to cart</button> <button id="Remove_c">Remove from cart</button> </div> <div class="column"> <h1>Blue Shirt</h1> <img id="img" src="img/Shirt_C.jpg"> <p>Price: $15</p> <p>Blue cotton material Titans shirt</p> <button class="add" id="Titan_d">Add to cart</button> <button id="Remove_d">Remove from cart</button> </div> <div class="column"> <h1>Hockey Stick</h1> <img id="img" src="img/Stick_A.png"> <p>Price: $25</p> <p>Black Titans hockey stick</p> <button class="add" id="Titan_e">Add to cart</button> <button id="Remove_e">Remove from cart</button> </div> </div> </div> <a href="index.html">Homepage</a> <footer>© Titan Sports and Apparel LLC | Email: TitanSportsApparel@gmail.com</footer>

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