0

I am trying to build a functional shopping cart using either vanilla JavaScript or jQuery. I'm not sure if I'm going about it in the right way but what I'm trying to do is the following:

  1. Setup an array called cartItems where all shopping cart data (ID, price, image, description, weight, tax) will be stored.

  2. Populate this array by either adding an event listener to the add to cart button or by getting the button element by ID (One thing I'm not sure of is how to setup different listeners when there's multiple products, all of which need to follow the same process to be added to the cart).

  3. Once the cart data has been added to the array I can then use it to populate the Cart page. On the Cart page will be options to update the quantity and remove the item. I can use edits to the array to make these changes.

The biggest problem for now is the second part. Actually 'waiting' for the add to cart button click and processing the data that should be processed.


**HTML**

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Weyland's | Shop</title>

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  <link rel="stylesheet" href="main.css">
</head>
<body>
  <nav class="navbar navbar-expand-sm navbar-light bg-light">
    <a class="navbar-brand" href="index.html">Weyland's</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>

      <div id="navbarNavDropdown" class="navbar-collapse collapse">
        <ul class="navbar-nav mr-auto">
          <li class="nav-item"><a class="nav-link" href="about.html">About</a></li>
          <li class="nav-item"><a class="nav-link" href="shop.html">Shop</a></li>
          <li class="nav-item"><a class="nav-link" href="shipping.html">Shipping</a></li>
        </ul>

        <ul class="navbar-nav navbar-right">
          <li>
            <div class="dropdown-divider"></div>
          </li>
          <li class="nav-item"><a class="nav-link" href="login.html">Login</a></li>
          <li class="nav-item"><a class="nav-link" href="register.html">Register</a></li>
          <li>
            <div class="dropdown-divider"></div>
          </li>
          <li>
            <span class="navbar-text d-none d-sm-block"> | </span>
          </li>
          <li class="nav item"><a class="nav-link" href="#" id="cart">Cart <span id="itemsInCart"></span></a></li>
        </ul>
      </div>
  </nav>

  <div class="container">
    <div class="row">
      <div class="col col-12 col-sm-12 col-md-6 col-lg-4 pt-5">
        <div class="card text-white bg-dark">
          <img class="card-img-top img-fluid" src="https://source.unsplash.com/9489sFfgk4c/1000x1000" alt="Card Image">
          <div class="card-body">
            <h4 class="card-title">St. Helen Chair</h4>
            <p class="card-subtitle text-muted">R1,999.00</p>
            <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rerum, amet!</p>
            <a href="st-helen-chair.html" class="btn btn-outline-light">Read More</a>
            <a href="#" id="atc-button" class="atc btn btn-primary float-right">Add to Cart</a>
          </div>
        </div>
      </div>

      <div class="col col-12 col-sm-12 col-md-6 col-lg-4 pt-5">
        <div class="card text-white bg-dark">
          <img class="card-img-top img-fluid" src="https://source.unsplash.com/0kjNpxQ6dPQ/1000x1000" alt="Card Image">
          <div class="card-body">
            <h4 class="card-title">Crane Neck Lamp</h4>
            <p class="card-subtitle text-muted">R499.00</p>
            <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rerum, amet!</p>
            <a href="crane-neck-lamp.html" class="btn btn-outline-light">Read More</a>
            <a href="#" id="atc-button" class="atc btn btn-primary float-right">Add to Cart</a>
          </div>
        </div>
      </div>

      <div class="col col-12 col-sm-12 col-md-6 col-lg-4 pt-5">
        <div class="card text-white bg-dark">
          <img class="card-img-top img-fluid" src="https://source.unsplash.com/qVg2lhK4sVY/1000x1000" alt="Card Image">
          <div class="card-body">
            <h4 class="card-title">His & Hers Mugs</h4>
            <p class="card-subtitle text-muted">R249.00</p>
            <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rerum, amet!</p>
            <a href="his-and-hers-mugs.html" class="btn btn-outline-light">Read More</a>
            <a href="#" class="atc btn btn-primary float-right">Add to Cart</a>
          </div>
        </div>
      </div>

      <div class="col col-12 col-sm-12 col-md-6 col-lg-4 pt-5">
        <div class="card text-white bg-dark">
          <img class="card-img-top img-fluid" src="https://source.unsplash.com/XwdSGEiOahM/1000x1000" alt="Card Image">
          <div class="card-body">
            <h4 class="card-title">Minimalistic Frame</h4>
            <p class="card-subtitle text-muted">R659.00</p>
            <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rerum, amet!</p>
            <a href="minimalistic-frame.html" class="btn btn-outline-light">Read More</a>
            <a href="#" class="atc btn btn-primary float-right">Add to Cart</a>
          </div>
        </div>
      </div>

      <div class="col col-12 col-sm-12 col-md-6 col-lg-4 pt-5">
        <div class="card text-white bg-dark">
          <img class="card-img-top img-fluid" src="https://source.unsplash.com/igKjieyjcko/1000x1000" alt="Card Image">
          <div class="card-body">
            <h4 class="card-title">City Crusier</h4>
            <p class="card-subtitle text-muted">R8,999.00</p>
            <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rerum, amet!</p>
            <a href="city-cruiser.html" class="btn btn-outline-light">Read More</a>
            <a href="#" class="atc btn btn-primary float-right">Add to Cart</a>
          </div>
        </div>
      </div>
    </div>
  </div>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  <script src="shopScripting.js"></script>
  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>
</html>

**CSS**

/* PAGE BACKGROUNDS */

.index-background {
  height: calc(100vh - 56px);
  min-height: 500px;
  background-image: url('https://source.unsplash.com/kZLaSWR-7J4/1920x1080');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.login-background {
  height: calc(100vh - 56px);
  min-height: 500px;
  background-image: url('https://source.unsplash.com/0vw4InAC-yM/1920x1080');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.register-background {
  height: calc(100vh - 56px);
  min-height: 500px;
  background-image: url('https://source.unsplash.com/0vw4InAC-yM/1920x1080');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}


/* SETTING PAGE HEIGHTS */

.about-row {
  height: calc(100vh - 56px);
}

.shipping-row {
  height: calc(100vh - 56px);
}

.product-detail {
  height: calc(100vh - 56px);
}

.login-row {
  height: calc(100vh - 56px);
}

.register-row {
  height: calc(100vh - 56px);
}


/* EDITS TO CARDS */


.card-img-top {
    width: 100%;
    height: 15rem;
    object-fit: cover;
}

/* MISC. STYLING */

.features-list {
  list-style-type: circle;
  color: #A0A0A0;
}

.shipping-text {
  color: #A0A0A0;
}

/* BUTTON STATES */

.btn-primary:not(:disabled):not(.disabled):active {
  background: #343A40;
  border: 1px black solid;
  box-shadow: none;
}

.btn-primary:not(:disabled):not(.disabled):focus{
  box-shadow: none;
}

/* CART STYLING */

#itemsInCart {
  background-color: #6394F8;
  border-radius: 10px;
  color: white;
  display: none;
  font-size: 12px;
  line-height: 1;
  padding: 3px 7px;
  text-align: center;
  vertical-align: middle;
  white-space: nowrap;
}

**JavaScript/jQuery**

let cartItems = [];

function cartProduct(id,product,price,weight,vat) {
  this.id = id;
  this.product = product;
  this.price = price;
  this.weight = weight;
  this.vat = vat;
}

function addToCart() {
  cartItems = JSON.parse(sessionStorage.getItem("cartItems"));
  let newProduct = new cartProduct
  document.getElementById('atc-button')
}

I know that my JavaScript file is incomplete and not structured correctly. I'm trying to learn how best to do this from the start. I expect that, when an add to cart button is clicked, the corresponding product details are captured and added to the array.

1
  • 1
    every item you sell has an SKU (it they don't, you need to start using them). So, mark up your items with that SKU (<topmostelement data-sku="...">...</...>) and for each of those, a button that adds its own parent, or queries for the sku it knows it needs to query (using document.querySelector(`[data-sku="${sku}""]`)) gets you "the thing". However, really, you kind of don't want HTML elements at all. You want to add just the SKUs to your array of items, with a count, like { "1874-2-613947": 2 } and then you can builkd your cart page however you like. Commented Aug 3, 2019 at 16:09

1 Answer 1

1

So the first thing, you'd likely have the catalog as a data store or something. Next, you will need something to uniquely identify the product (perhaps what you're calling id might be a sku?) With that, we could do something like the following:

// I do this, to turn a NodeList into a true Array
const addToCartBtns = [...document.querySelectorAll(".atc-button")];

addToCartBtns.forEach(button => {
  /***
   * Here, you have the `button` instance, which would handle its
   *   own clicks and updates.
   */
  button.addEventListener("click", function(){
    const productSKU = button.getAttribute('data-product-id');
    // With the id/sku, we can then filter the data store, or
    //   query for the relevant row. We don't need to push all
    //   that onto the cart, though - all we really need is a
    //   sku and quantity. We only need product and price when
    //   we display, and that's all in our data store!
    cartItems.push({
      sku: productSKU,
      qty: 1 /* a default quantity to start */
    });
    // Also at this point, you'd want to notify the user
    //   that you've updated the cart, maybe update the
    //   display or take them to the cart to allow qty
    //   updates or whatever.
  }); 
});
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks for the comment. The logic of this definitely works in my head and makes much more sense than my approach. I just have two questions: 1. Regarding productSKU, would I need to set the data-product-id on an individual button level? (I only have five products so it wouldn't be hard. I'm just not sure where that variable comes from. 2. Once the productSKU and qty have been pushed to the array, how do they 'merge' with the other data (Maybe this sounds stupid, I'm sorry). How do they match up to the product name price, etc? Based on the data-product-id? Thanks again!
I would put a data-product-id on the button itself, yes (so like <button data-product-id='230-335175-m'>.... And once the cart array, containing solely that id and quantity, have been created... Do you have some sort of data-store? An array of product data or something?
I know it's not good practice but for now everything was hardcoded as above in my HTML (There's five products, setup as cards). Also, I'm getting an error on your button.addEventListener line. Any idea why? It's saying that it's not a function.
Sure. There's a confusion - my selector is .atc-button, but you've given them all the id=atc-button, which you can't actually do. ID's must be unique.
Take a look here: repl.it/@TobiasParent/differentMathsInATable - the array likely isn't being populated, unless you assigned a data-product-id to each button.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.