Simple Javascript Shopping Cart (Free Code Download)

Welcome to a tutorial on how to create a simple vanilla Javascript Shopping Cart. Looking to build an eCommerce website or web app? Not too keen on the complicated bloated scripts and just need a simple interface? Well, here it is. A standalone local storage shopping cart that does not use any frameworks – Read on to find out!

ⓘ I have included a zip file with all the example source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

TABLE OF CONTENTS

 

 

DOWNLOAD & DEMO

Firstly, here is the download link to the example code as promised.

 

QUICK NOTES

For you guys who just want to use this as a “plugin”:

  • Edit products.js, fill in your own products.
  • Put the product images in the images/ folder.
  • Set iURL in cart.js section A to an absolute URL if you have trouble with the images.
  • Launch cart.html, use http:// not file://.
  • Lastly, complete your own checkout sequence cart.js, section H.
If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

EXAMPLE CODE DOWNLOAD

Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

JAVASCRIPT CART DEMO

 

 

JAVASCRIPT SHOPPING CART

All right, let us now get into the mechanics of the shopping cart itself.

 

PART 1) THE HTML

cart.html
<!-- (A) CART -->
<div id="cart-wrap">
  <!-- (A1) PRODUCTS LIST -->
  <div id="cart-products"></div>
 
  <!-- (A2) CURRENT CART ITEMS -->
  <div id="cart-items"></div>
</div>
 
<!-- (B) TEMPLATES -->
<!-- (B1) PRODUCT CELL -->
<template id="template-product">
<div class="p-item">
  <img class="p-img"/>
  <div class="p-name"></div>
  <div class="p-desc"></div>
  <div class="p-price"></div>
  <button class="cart p-add">Add To Cart</button>
</div>
</template>
 
<!-- (B2) CART ITEMS -->
<template id="template-cart">
<div class="c-item">
  <div class="c-name"></div>
  <button class="c-del cart">X</button>
  <input class="c-qty" type="number" min="0"/>
</div>
</template>
<template id="template-cart-checkout">
  <button class="c-empty cart" onclick="cart.nuke()">Empty</button>
  <button class="c-checkout cart" onclick="cart.checkout()">Checkout</button>
</template>
  1. The HTML interface should be very straightforward with only 2 sections in the <div id="cart-wrap"> container:
    • <div id="cart-products"> To contain the list of products.
    • <div id="cart-items"> To show the current items in the cart.
  2. HTML templates for the product and cart items.

 

PART 2) THE PRODUCTS

products.js
// DUMMY PRODUCTS (PRODUCT ID : DATA)
var products = {
  123: {
    name : "MokBook Thicc",
    desc : "Greatest properly off ham exercise all.",
    img : "dummy-pdt-b.jpg",
    price : 2034
  },
  124: {
    name : "MokBook Rookie",
    desc : "Unsatiable its possession nor off.",
    img : "dummy-pdt-b.jpg",
    price : 1247
  },
  125: {
    name : "iPong Max",
    desc : "All difficulty unreserved the solicitude.",
    img : "dummy-pdt-a.jpg",
    price : 675
  },
  126: {
    name : "iTab Pok",
    desc : "Had judgment out property the supplied. ",
    img : "dummy-pdt-a.jpg",
    price : 842
  }
};

Since we don’t have a database here, the only option is to hardcode all the products in a script.

 

 

PART 3) THE JAVASCRIPT

3A) THE PROPERTIES

cart.js
var cart = {
  // (A) PROPERTIES
  hPdt : null,      // html products list
  hItems : null,    // html current cart
  items : {},       // current items in cart
  iURL : "images/", // product image url folder
};

Captain Obvious – The var cart object will keep all the cart-related mechanics. Right at the top, we only have 4 properties.

  • cart.hPdt and cart.hItems shouldn’t be too difficult to understand – We will use these to refer to <div id="cart-products"> and <div id="cart-items">.
  • cart.items contains the current items in the cart. This is simply an object that has the format of PRODUCT ID : QUANTITY.
  • iURL is the URL to the product image folder.

 

3B) WORKING WITH LOCALSTORAGE

cart.js
// (B) LOCALSTORAGE CART
// (B1) SAVE CURRENT CART INTO LOCALSTORAGE
save : () => {
  localStorage.setItem("cart", JSON.stringify(cart.items));
},

// (B2) LOAD CART FROM LOCALSTORAGE
load : () => {
  cart.items = localStorage.getItem("cart");
  if (cart.items == null) { cart.items = {}; }
  else { cart.items = JSON.parse(cart.items); }
},
  
// (B3) NUKE CART!
nuke : () => { if (confirm("Empty cart?")) {
  cart.items = {};
  localStorage.removeItem("cart");
  cart.list();
}}

That’s right. Without a server session, whatever is in the cart will disappear as soon as the user reloads the page. To prevent that from happening, we will save the cart items into the localStorage.

  • cart.save() simply saves cart.items into the local storage.
  • cart.load() will fetch the data from the local storage and restore cart.items.
  • Lastly, cart.nuke() will empty the entire cart.

 

 

3C) SHOPPING CART INITIALIZATION

cart.js
// (C) INITIALIZE
init : () => {
  // (C1) GET HTML ELEMENTS
  cart.hPdt = document.getElementById("cart-products");
  cart.hItems = document.getElementById("cart-items");
    
  // (C2) DRAW PRODUCTS LIST
  cart.hPdt.innerHTML = "";
  let template = document.getElementById("template-product").content,
      p, item, part;
  for (let id in cart.products) {
    p = cart.products[id];
    item = template.cloneNode(true);
    item.querySelector(".p-img").src = cart.iURL + p.img;
    item.querySelector(".p-name").textContent = p.name;
    item.querySelector(".p-desc").textContent = p.desc;
    item.querySelector(".p-price").textContent = "$" + p.price.toFixed(2);
    item.querySelector(".p-add").onclick = () => { cart.add(id); };
    cart.hPdt.appendChild(item);
  }
    
  // (C3) LOAD CART FROM PREVIOUS SESSION
  cart.load();
    
  // (C4) LIST CURRENT CART ITEMS
  cart.list();
}

The init() function runs on page load. It may seem to be massive, but what it does is actually very basic:

  • (C1) “Tie” cart.hPdt to <div id="cart-products"> and cart.hItems to <div id="cart-items">.
  • (C2) Draw the list of products.
  • (C3) Load the cart from the previous session.
  • (C4) Draw the current cart items.

 

 

3D) DRAW SHOPPING CART ITEMS

cart.js
// (D) LIST CURRENT CART ITEMS (IN HTML)
list : () => {
  // (D1) RESET
  cart.hItems.innerHTML = "";
  let item, part, pdt, empty = true;
  for (let key in cart.items) {
    if (cart.items.hasOwnProperty(key)) { empty = false; break; }
  }

  // (D2) CART IS EMPTY
  if (empty) {
    item = document.createElement("div");
    item.innerHTML = "Cart is empty";
    cart.hItems.appendChild(item);
  }
    
  // (D3) CART IS NOT EMPTY - LIST ITEMS
  else {
    let template = document.getElementById("template-cart").content,
        p, total = 0, subtotal = 0;
    for (let id in cart.items) {
      // (D3-1) PRODUCT ITEM
      p = cart.products[id];
      item = template.cloneNode(true);
      item.querySelector(".c-del").onclick = () => { cart.remove(id); };
      item.querySelector(".c-name").textContent = p.name;
      item.querySelector(".c-qty").value = cart.items[id];
      item.querySelector(".c-qty").onchange = function () { cart.change(id, this.value); };
      cart.hItems.appendChild(item);
 
      // (D3-2) SUBTOTAL
      subtotal = cart.items[id] * p.price;
      total += subtotal;
    }

    // (D3-3) TOTAL AMOUNT
    item = document.createElement("div");
    item.className = "c-total";
    item.id = "c-total";
    item.innerHTML ="TOTAL: $" + total;
    cart.hItems.appendChild(item);
 
    // (D3-4) EMPTY & CHECKOUT
    item = document.getElementById("template-cart-checkout").content.cloneNode(true);
    cart.hItems.appendChild(item);
  }
}

The list() function draws the current cart items into <div id="cart-items">. Looks complicated, but it is just generating a whole load of HTML.

 

 

3E) SHOPPING CART ACTIONS

cart.js
// (E) ADD ITEM INTO CART
add : (id) => {
  if (cart.items[id] == undefined) { cart.items[id] = 1; }
  else { cart.items[id]++; }
  cart.save(); cart.list();
},

// (F) CHANGE QUANTITY
change : (pid, qty) => {
  // (F1) REMOVE ITEM
  if (qty <= 0) {
    delete cart.items[pid];
    cart.save(); cart.list();
  }

  // (F2) UPDATE TOTAL ONLY
  else {
    cart.items[pid] = qty;
    var total = 0;
    for (let id in cart.items) {
      total += cart.items[id] * products[id].price;
      document.getElementById("c-total").innerHTML ="TOTAL: $" + total;
    }
  }
},
  
// (G) REMOVE ITEM FROM CART
remove : (id) => {
  delete cart.items[id];
  cart.save();
  cart.list();
},
  
// (H) CHECKOUT
checkout : () => {
  // SEND DATA TO SERVER
  // CHECKS
  // SEND AN EMAIL
  // RECORD TO DATABASE
  // PAYMENT
  // WHATEVER IS REQUIRED
  alert("TO DO");

  /*
  var data = new FormData();
  data.append("cart", JSON.stringify(cart.items));
  data.append("products", JSON.stringify(products));
 
  fetch("SERVER-SCRIPT", { method:"POST", body:data })
  .then(res=>res.text()).then((res) => {
    console.log(res);
  })
  .catch((err) => { console.error(err); });
  */
}

Finally, all of these functions deal with cart actions:

  • cart.add() Adds a selected item into the cart. Remember the format of cart.items = { ID : QUANTITY }? That is exactly what we are doing here.
  • cart.change() Changes the quantity of the item in the cart.
  • cart.remove() Removes an item from the cart.
  • cart.checkout() Is up to you to complete – Send the order via email, SMS, save to database, save to Google Forms, etc…

 

EXTRA BITS & LINKS

That’s all for this project, and here is a small section on some extras and links that may be useful to you.

 

MULTIPLE PRODUCT CATEGORIES?

As you may have noticed, there are no product categories. But yes, it is possible to add sections with some changes:

  • Create another var categories object to hold the product IDs of each category. For example { CATEGORY-A: [123, 124, 125], CATEGORY-B: [1, 2, 3] }.
  • Modify the cart.draw() function to draw the products in a selected category.

 

PRODUCT OPTIONS

For the guys who are sarcastically saying “adding product options should be easy for you, it can be done in 5 minutes” – Of course, it is “so simple”, even you can do it within “just a few minutes”. Feel free to challenge yourself:

  • Create a new var options = { color : [red, green, blue], size : [small, large], ... }.
  • Attach the options to products.
  • Change the product list to also draw the options.
  • Change the way the cart records items – PRODUCT-ID[OPTION][VALUE][OPTION][VALUE] : QUANTITY.

Yes, that’s all, just a few steps only. Please don’t ask about product options again… It is “so simple” that I don’t even want to touch on it.

 

A BETTER SHOPPING CART

Need a shopping cart with product options? Product categories? Discount coupons? User system and admin panel? Click here to check out my eBook!

 

HOW TO “COMPLETE THE CHECKOUT”

The only piece of advice I can give is to learn a server-side programming language of your choice – PHP, ASP, JSP, Python, or NodeJS. Everyone has different requirements.

  • Save order to the database.
  • Save order to Google Forms.
  • Send order via email.
  • Send order via SMS.
  • Process online payment.
  • Link up with other systems.

As you can guess, there is simply no way that I can explain “how to checkout” in every possible scenario and language. Neither can I give free consultation services. So it is up to you to complete your own checkout sequence. If you need more examples, check out the PHP MySQL shopping cart link below… Or get my eBook above. 😆

 

COMPATIBILITY CHECKS

Works well in all modern browsers. If you want to be safe, use Modernizr to do feature checks and even load polyfills.

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

29 thoughts on “Simple Javascript Shopping Cart (Free Code Download)”

  1. How would I reference the total value? Creating a PayPal button that takes the total price as the price to charge. Great tutorial; thank you for taking the time to share!

  2. How do I send an email to a static address with the order when the Check Out button is clicked? Can the user also enter an email address to have the order sent to as well?

  3. excellent..Is it possible to select an image and have the image in the cart as well..
    basically i want the user to select an image .then click customise then have the image move to web page 2 with his new dimensions.

  4. Trevor John Lloyd

    Absolutely brilliant. How can I change the currency to GBP? I tried changing all the $ to £ that didn’t work. Also is there a way to make the cart position fixed i tried bunging it in at cart wrap.
    Thanks Trev

Leave a Comment

Your email address will not be published.