Skip to main content

Command Palette

Search for a command to run...

How to make a shopping cart in HTML,CSS & JavaScript?

Shopping Cart is one of the basic JavaScript project a beginner should must build to brush up their JavaScript knowledge.

Updated
8 min read
How to make a shopping cart in HTML,CSS & JavaScript?
S

I am a self taught Web developer from India. I enjoy learning new things and building projects. I am currently exploring NodeJS and Solidity, On this journey I am also writing blogs about projects I make and things I learned.

Introduction

Shopping cart is one of the basic JavaScript projects a beginner front end developer must built in order to learn JavaScript and also to showcase their CSS skills.

A shopping cart involves JavaScript concepts like functions, loops, objects, arrays, array methods, it involves creation, deletion and updation in arrays and objects, so it can be a good addition to the resume of a beginner frontend developer.

What are we going to build?

We are building a shopping cart where we can add products, delete the products, increase and decrease the quantity of the products, and spontaneously calculate the total number of products in cart and total cart value.

We are focussing more on the Logical part rather than designing so I will be providing a link to the CSS file and just not wasting time in designing.

Let's get started.

Prerequisites

  • basic knowledge of HTML/CSS.

  • basic knowledge of JavaScript

  • a working computer

  • a text editor

  • a web browser

Initialization

  • Create a directory by the name of your choice.

  • Create a file named index.html in the directory we just created. Add the following HTML boilerplate code to it.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Shopping Cart</title>
    <link rel="stylesheet" href="style.css" />
  </head>

  <body>
      <script src="app.js"></script>
  </body>
</html>
  • Create another file named app.js in the same directory.

  • At last create a file names style.css and paste the styles from the given GitHub repository.

Creating the HTML layout

Copy and Paste the following inside the body element.

<h1 class="">Shopping Cart</h1> 
    <div class="body">
      <div class="container">
        <h3 class="heading">Products</h3>
        <div class="result"></div>
      </div>
      <div class="cart">
        <div class="cart-header">
          <h3>CART</h3>
          <p class="noOfItems">0 items</p>
        </div>
        <hr noshade="true" size="1px" />
        <div class="cart-items"></div>
        <hr noshade="true" size="1px" />
        <div class="cart-footer cart-header">
          <h4>Total</h4>
          <p class="total">$0</p>
        </div>
        <button class="buy-btn">PROCEED TO BUY</button>
      </div>
    </div>

Layout Explanation

There is heading at the top. Then there is a div tag with class body which consists of two divs one containing the products and the other cart.

iMac - 1.png

Adding products array and mapping it

Copy and paste the following product array or you could make your own product array in the same format.

const products = [
  {
    name: "Adidas Shoes",
    price: 2500,
    id: 1,
    quantity: 1,
    sizes: ["S", "M", "L", "XL"],
  },
  {
    name: "Sting Energy Drink",
    price: 120,
    id: 2,
    quantity: 1,
    variants: ["Regular", "Sugar Free"],
  },
  {
    name: "Umbrella",
    price: 500,
    id: 3,
    quantity: 1,
    sizes: ["Small", "Medium", "Large"],
  },
  {
    name: "Cat Food",
    price: 900,
    id: 4,
    quantity: 1,
    variants: ["Chicken", "Fish", "Beef"],
  },
  {
    name: "T Shirt",
    price: 300,
    id: 5,
    quantity: 1,
    sizes: ["S", "M", "L", "XL"],
  },
  {
    name: "Book",
    price: 100,
    id: 6,
    quantity: 1,
    variants: ["Fiction", "Non-Fiction", "Comics"],
  },
];

Now in app.js create a const named productsHTML and then map all the products with all the metadata in the products array and assign it to productsHTML.

const productsHTML = products.map(
  (product) => `<div class="product-card">
        <h2 class="product-name">${product.name}</h2>

        ${product.sizes ? `<select class="product-size">
            <option value="">Select Size</option>
            ${product.sizes
        .map((size) => `<option value="${size}">${size}</option>`)
        .join("")}
        </select>` : ""}

        ${product.variants ? `<select class="product-variant">
            <option value="">Select Variant</option>
            ${product.variants
        .map((variant) => `<option value="${variant}">${variant}</option>`)
        .join("")}
        </select>` : ""}

        <strong>$${product.price}</strong>
        <button class="product-btn" data-id="${product.id}">Add to Cart</button>
    </div>`
);

const result = document.querySelector(".result");
result.innerHTML = productsHTML.join("");

Now open index.html in your browser, It should look like this.

Adding Products to Cart

Create an empty array cart , which we will be using to store cart items.

let cart = [];

Rendering cart items

Now Create a function updateCart() to map and render cart items and call it to render the current items. Currently no change will be observed in web page since our cart is empty.

function updateCart() {
  const cartHTML = cart.map(
    (item) => `<div class="cart-item">
            <h3>${item.name} (${item.selectedSize ? `<span>${item.selectedSize}</span>` : ""}${item.selectedVariant ? `<span>${item.selectedVariant}</span>` : ""})</h3>
            <div class="cart-detail"><div class="mid">
                <button onclick="decrItem('${item.cartId}')">-</button>
                <p>${item.quantity}</p>
                <button onclick="incrItem('${item.cartId}')">+</button>
            </div>
            <p>$${item.price}</p>
            <button onclick="deleteItem('${item.cartId}')" class="cart-product">D</button></div>
           </div>`
  );

  const cartItems = document.querySelector(".cart-items");
  cartItems.innerHTML = cartHTML.join("");
}

Adding items to cart

Now create a function named addToCart() to add items to cart on clicking the Add to cart button of a product with products, id, size and variant as arguments.

In this function we are verifying if the user has selected a size or variant for a product, if not we are showing an alert and doing nothing.

We are using unshift() since we want to add newer items at the top. After adding new product to cart we are re-rendering the cart items to update the cart items on the webpage.

function addToCart(products, id, size, variant) {
  const product = products.find((product) => product.id === id);
  if (!product) return;

  if (product.sizes && (!size || size === "")) {
    alert("Please select a size before adding to cart.");
    return;
  }
  if (product.variants && (!variant || variant === "")) {
    alert("Please select a variant before adding to cart.");
    return;
  }

  const cartItem = {
    ...product,
    quantity: 1,
    selectedSize: size || null,
    selectedVariant: variant || null,
  };

  // updating the card id with the product id + size/variant
  cartItem.cartId = `${cartItem.id}-${cartItem.selectedSize || ""}-${cartItem.selectedVariant || ""}`;
  cart.unshift(cartItem);

  updateCart();
  getTotal(cart);
}

The function takes product and the particular product as argument which you want to add to cart.

Now we are going to create event listener which will be fired upon when we click add to cart button of a particular product.

We will also be getting the products, id, size and variants of the particular product which we wanna add to cart.

function attachAddToCartHandlers() {
  const buttons = document.querySelectorAll(".product-btn");
  buttons.forEach((btn) => {
    btn.addEventListener("click", function (e) {
      const id = parseInt(btn.dataset.id, 10);
      const card = btn.closest(".product-card");
      const sizeSelect = card ? card.querySelector('.product-size') : null;
      const variantSelect = card ? card.querySelector('.product-variant') : null;
      const size = sizeSelect ? sizeSelect.value : null;
      const variant = variantSelect ? variantSelect.value : null;

      addToCart(products, id, size, variant);
    });
  });
}

attachAddToCartHandlers();

Calculating Total items and Total cart value

Now we will create a function named getTotal() and call it to get total items and total cart value.
we are using array.reduce method to traverse the cart items and calculate the total and update it to show in our UI.

function getTotal(cart) {
  let { totalItem, cartTotal } = cart.reduce(
    (total, cartItem) => {
      total.cartTotal += cartItem.price * cartItem.quantity;
      total.totalItem += cartItem.quantity;
      return total;
    },
    { totalItem: 0, cartTotal: 0 }
  );
  const totalItemsHTML = document.querySelector(".noOfItems");
  totalItemsHTML.innerHTML = `${totalItem} items`;
  const totalAmountHTML = document.querySelector(".total");
  totalAmountHTML.innerHTML = `$${cartTotal}`;
}

Now update the addToCart() function by calling getTotal(cart); at the end of the function since we want to calculate and update total on adding each product.

We are calculating total items using reduce() method and then updating the data to the webpage.

Increasing and Decreasing quantity of cart items

Increasing quantity of items

Now we will create a function named incrItem() and pass cartId as parameter which we will be receiving when we click plus button of the particular cart product item.

We are looping over the cart and if we find the match we are terminating the loop.

function incrItem(cartId) {
  for (let i = 0; i < cart.length; i++) {
    if (cart[i] && cart[i].cartId == cartId) {
      cart[i].quantity += 1;
      break;
    }
  }
  updateCart();
  getTotal(cart);
}

!! Bug alert

As one can notice after clicking add to cart button of a particular button it should increase the no of product not add a new product in the cart.

Let's fix it by updating the function addToCart().

function addToCart(products, id, size, variant) {
  const product = products.find((product) => product.id === id);
  if (!product) return;

  if (product.sizes && (!size || size === "")) {
    alert("Please select a size before adding to cart.");
    return;
  }
  if (product.variants && (!variant || variant === "")) {
    alert("Please select a variant before adding to cart.");
    return;
  }

  const cartItem = {
    ...product,
    quantity: 1,
    selectedSize: size || null,
    selectedVariant: variant || null,
  };

  cartItem.cartId = `${cartItem.id}-${cartItem.selectedSize || ""}-${cartItem.selectedVariant || ""}`;

  const existingIndex = cart.findIndex((item) => item.cartId === cartItem.cartId);
  if (existingIndex > -1) {
   // if the product already exists in the cart we are increasing the quantity.
    cart[existingIndex].quantity += 1;
  } else {
    cart.unshift(cartItem);
  }

  updateCart();
  getTotal(cart);
}

Decreasing quantity of items

Now we will create a function named decrItem() and pass id as parameter which we will be receiving when we click minus button of the particular cart product item.

function decrItem(cartId) {
  for (let i = 0; i < cart.length; i++) {
    if (cart[i].cartId == cartId && cart[i].quantity > 1) {
      cart[i].quantity -= 1;
      break;
    }else if (cart[i].cartId == cartId && cart[i].quantity == 1) {
      cart.splice(i, 1);
      break;
    }
  }
  updateCart();
  getTotal(cart);
}

Notice quantity of a product cannot be less than one. So If we don't want to buy an item we can delete it instead making its quantity to zero.

Deleting Items from cart

Now we will create a function named deleteItem() and pass id as parameter which we will be receiving when we click delete button of the particular cart product item.

We are using array.splice() method to delete cart array item.

function deleteItem(cartId) {
  for (let i = 0; i < cart.length; i++) {
    if (cart[i].cartId === cartId) {
      cart.splice(i, 1);
      break;
    }
  }
  updateCart();
  getTotal(cart);
}

Finishing it!

Let’s create a function to get and print the cart items on clicking the Proceed To Buy button.

function getCartPayload() {
  return cart.map(({ id, name, price, quantity, selectedSize, selectedVariant }) => ({
    id,
    name,
    price,
    quantity,
    selectedSize: selectedSize || null,
    selectedVariant: selectedVariant || null,
  }));
}

const buyBtn = document.querySelector('.buy-btn');
if (buyBtn) {
  buyBtn.addEventListener('click', () => {
    if (!cart.length) {
      alert('Cart is empty');
      return;
    }
    const payload = getCartPayload();
    alert("Cart Payload: " + JSON.stringify(payload, null, 2));
  });
}

The finished project should look like this:

If you ran into a problem or got bugs in your project, you can check out the finished project here.

Check out the finished live project here

Thank you for reading this article 😊.

Please feel free to ask questions in the comments below.

O

I read this and this article and it is useful for every beginner and can help you to familiarize with real use of functions, loops.

D

Great.. 🤓

1
D

Thanks for sharing buddy

1
N

Im lovin it

2
K

Congrats on writing your first blog 🎉

1
Y
Y verma3y ago

Really helpful.....

1
D

Thanks a lot😊. Find it helpful

2

More from this blog

Sudhanshu Ranjan's Blog

3 posts

I am a self taught Front end developer from India. I enjoy learning new things and building projects. I am currently exploring NodeJS and Solidity, On this journey I am also writing blogs about projec