Hey guys in this post, we will create a simple Javascript add-to-cart project. Follow this tutorial till the end to understand the Javascript basics. The project is already live on the internet.
Table of Contents
Topics covered
This application involves the following topics –
- DOM Manipulation
- Control Structures
- Array.forEach()
- JavaScript CSS Manipulation
- eventListeners
- Immediately Invoked Function Expressions
Complete source code
The below image shows you the project structure –
Add styles to the application
Create a style.css
file and add the following content –
@import url("https://fonts.googleapis.com/css?family=Kaushan+Script");
:root {
--mainPink: #ef7998;
--mainYellow: rgb(249, 228, 148);
--mainWhite: #fff;
--mainBlack: #000;
--yellowTrans: rgba(249, 228, 148, 0.5);
--mainGrey: rgb(238, 238, 238);
}
body {
font-family: "Kaushan Script", cursive;
background: var(--mainWhite);
color: var(--mainBlack);
}
/* nav links */
.navbar-toggler {
outline: none !important;
}
.toggler-icon {
font-size: 2.5rem;
color: var(--mainPink);
}
.nav-link {
color: var(--mainPink);
font-size: 1.5rem;
transition: all 0.5s ease-in-out;
}
.nav-link:hover {
color: var(--mainBlack);
}
/* end of nav links */
/* info icons */
.cart-info__icon {
color: var(--mainBlack);
cursor: pointer;
}
.cart-info {
border: 0.1rem solid var(--mainBlack);
color: var(--mainBlack);
border-radius: 0.25rem;
padding: 0.4rem 0.6rem;
cursor: pointer;
}
.cart-info:hover {
background: var(--mainPink);
border-color: var(--mainPink);
color: var(--mainWhite);
}
.cart-info:hover .cart-info__icon {
color: var(--mainWhite);
}
/* end of info icons */
/* banner */
.max-height {
min-height: calc(100vh - 76px);
background: linear-gradient(var(--yellowTrans), var(--yellowTrans)),
url("../img/headerBcg.jpeg") center/cover fixed no-repeat;
position: relative;
}
.banner {
color: var(--mainWhite);
margin-top: -4rem;
}
.banner-title {
color: var(--mainPink);
font-size: 4rem;
}
.banner-link {
font-size: 1.5rem;
color: var(--mainBlack);
border: 0.2rem solid var(--mainBlack);
}
.banner-link:hover {
background: var(--mainBlack);
color: var(--mainPink);
}
/* endo of banner */
/* cart */
.cart {
position: absolute;
min-height: 10rem;
background: var(--mainWhite);
top: 0;
right: 0;
transition: all 0.3s ease-in-out;
background: rgba(255, 255, 255, 0.5);
width: 0;
overflow: hidden;
}
.show-cart {
width: 18rem;
padding: 2rem 1.5rem;
transform: rotateY(-360deg);
}
.cart-item {
transition: all 2s ease-in-out;
}
/* end of cart */
/* cart item */
.cart-item-remove {
color: var(--mainPink);
transition: all 1s ease-in-out;
}
.cart-item-remove:hover {
transform: scale(1.1);
color: var(--mainBlack);
}
#cart-item-price {
font-size: 0.8rem;
}
/* cart item */
/* cart buttons */
.btn-pink {
color: var(--mainPink) !important;
border-color: var(--mainPink) !important;
}
.btn-black {
color: var(--mainBlack) !important;
border-color: var(--mainBlack) !important;
}
.btn-black:hover {
color: var(--mainPink) !important;
background: var(--mainBlack) !important;
}
.btn-pink:hover {
background: var(--mainPink) !important;
color: var(--mainBlack) !important;
}
/* end of cart buttons */
/* about */
.about-img__container {
position: relative;
}
.about-img__container::before {
content: "";
position: absolute;
top: -1.5rem;
left: -1.7rem;
width: 100%;
height: 100%;
outline: 0.5rem solid var(--mainYellow);
z-index: -1;
transition: all 1s ease-in-out;
}
.about-img__container:hover:before {
top: 0;
left: 0;
}
/*end of about */
/* store items */
.store {
background: var(--mainGrey);
}
.img-container {
position: relative;
overflow: hidden;
cursor: pointer;
}
.store-img {
transition: all 1s ease-in-out;
}
.img-container:hover .store-img {
transform: scale(1.2);
}
.store-item-icon {
position: absolute;
bottom: 0;
right: 0;
padding: 0.75rem;
background: var(--mainYellow);
border-top-left-radius: 1rem;
transition: all 1s ease-in-out;
transform: translate(100%, 100%);
}
.img-container:hover .store-item-icon {
transform: translate(0, 0);
}
.store-item-icon:hover {
color: var(--mainWhite);
}
.store-item-value {
color: --mainYellow;
}
/*end of store items */
.search-box {
background: var(--mainPink);
color: var(--mainBlack);
}
/* ligthbox */
.lightbox-container {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
background: rgba(0, 0, 0, 0.6) !important;
display: none;
}
.show {
display: block;
}
.lightbox-holder {
position: relative;
}
.lightbox-item {
min-height: 80vh;
background: url("../img/cake-1.jpeg") center/cover fixed no-repeat;
border-radius: 0.3rem;
}
.lightbox-close {
color: var(--mainPink);
font-size: 3rem;
transition: all 1s ease-in-out;
cursor: pointer;
}
.lightbox-close:hover {
color: var(--mainYellow);
}
.lightbox-control {
position: absolute;
font-size: 4rem;
color: var(--mainPink);
transition: all 1s linear;
cursor: pointer;
}
.lightbox-control:hover {
color: var(--mainYellow);
}
.btnLeft {
top: 50%;
left: 0;
transform: translateX(-60%);
}
.btnRight {
top: 50%;
right: 0;
transform: translateX(60%);
}
Add scripts to the application
Create an app.js
file and add the following content –
// show cart
(function(){
//target cart button
const cartInfo = document.getElementById('cart-info');
const cart = document.getElementById('cart');
cartInfo.addEventListener('click', function(){
cart.classList.toggle('show-cart');
})
})();
// add items to the cart
(function(){
const cartBtn = document.querySelectorAll('.store-item-icon');
cartBtn.forEach(function(btn){
btn.addEventListener('click', function(event){
//make sure event fires only if it has a parent of a certain class.
if(event.target.parentElement.classList.contains('store-item-icon')){
let fullPath = event.target.parentElement.previousElementSibling.src;
let pos = fullPath.indexOf('img') + 3; //use the 3 to get rid of the 'img' string
let partPath = fullPath.slice(pos);
const item = {};
item.img = `img-cart${partPath}`;
let name = event.target.parentElement.parentElement.nextElementSibling.children[0].children[0].textContent;
item.name = name;
let price = event.target.parentElement.parentElement.nextElementSibling.children[0].children[1].textContent;
let finalPrice = price.slice(1).trim();
item.price = finalPrice;
const cartItem = document.createElement('div');
cartItem.classList.add('cart-item', 'd-flix', 'justify-content-between', 'text-capitalize', 'my-3');
cartItem.innerHTML = `<div class="cart-item d-flex justify-content-between text-capitalize my-3"><img src="${item.img}" class="img-fluid rounded-circle" id="item-img" alt="">
<div class="item-text"><p id="cart-item-title" class="font-weight-bold mb-0">${item.name}</p><span>$</span>
<span id="cart-item-price" class="cart-item-price" class="mb-0">${item.price}</span></div><a href="#" id='cart-item-remove' class="cart-item-remove"><i class="fas fa-trash"></i></a></div>`;
//select cart
const cart = document.getElementById('cart');
const total = document.querySelector('.cart-total-container');
cart.insertBefore(cartItem, total);
alert('item added to the cart');
showTotals();
}
});
});
// show totals
function showTotals(){
const total = [];
const items = document.querySelectorAll('.cart-item-price');
items.forEach(function(item){
total.push(parseFloat(item.textContent));
})
const totalMoney = total.reduce(function(total, item){
total += item;
return total;
},0);
const finalMoney = totalMoney.toFixed(2);
document.getElementById('cart-total').textContent = finalMoney;
document.querySelector('.item-total').textContent = finalMoney;
document.getElementById('item-count').textContent = total.length;
}
})();
Add HTML to the application
Create an index.html
file and add the following content –
<!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">
<!-- bootstrap css -->
<link rel="stylesheet" href="css/bootstrap.min.css">
<!-- main css -->
<link rel="stylesheet" href="css/style.css">
<!-- font awesome -->
<link rel="stylesheet" href="css/all.css">
<title>Cart Project</title>
<style>
</style>
</head>
<body>
<!-- header -->
<header>
<!-- navbar -->
<!--
https://www.iconfinder.com/icons/2427887/dessert_donut_doughnut_fat_sweets_icon
Creative Commons (Attribution 3.0 Unported);
https://www.iconfinder.com/korawan_m
-->
<nav class="navbar navbar-expand-lg px-4">
<a class="navbar-brand" href="#"><img src="img/logo.svg" alt=""></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#myNav">
<span class="toggler-icon"><i class="fas fa-bars"></i></span>
</button>
<div class="collapse navbar-collapse" id="myNav">
<ul class="navbar-nav mx-auto text-capitalize">
<li class="nav-item active">
<a class="nav-link" href="#">home</a>
</li>
<li class="nav-item">
<a class="nav-link " href="#">about</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">store</a>
</li>
</ul>
<div class="nav-info-items d-none d-lg-flex ">
<!-- single info -->
<div class="nav-info align-items-center d-flex justify-content-between mx-lg-5">
<span class="info-icon mx-lg-3"><i class="fas fa-phone"></i></span>
<p class="mb-0">+ 123 456 789</p>
</div>
<!-- end of single info -->
<!-- single info -->
<div id="cart-info" class="nav-info align-items-center cart-info d-flex justify-content-between mx-lg-5">
<span class="cart-info__icon mr-lg-3"><i class="fas fa-shopping-cart"></i></span>
<p class="mb-0 text-capitalize"><span id="item-count">2 </span> items - $<span class="item-total">10.49</span></p>
</div>
<!-- end of single info -->
</div>
</div>
</nav>
<!-- end of nav -->
<!-- banner -->
<div class="container-fluid">
<div class="row max-height justify-content-center align-items-center">
<div class="col-10 mx-auto banner text-center">
<h1 class="text-capitalize">welcome to <strong class="banner-title ">grandma's</strong></h1>
<a href="#store" class="btn banner-link text-uppercase my-2">explore</a>
</div>
<div id="cart" class="cart">
<!-- cart item -->
<div class="cart-item d-flex justify-content-between text-capitalize my-3">
<img src="img-cart/cake-2.jpeg" class="img-fluid rounded-circle" id="item-img" alt="">
<div class="item-text">
<p id="cart-item-title" class="font-weight-bold mb-0">cart item</p>
<span>$</span>
<span id="cart-item-price" class="cart-item-price" class="mb-0">10.99</span>
</div>
<a href="#" id='cart-item-remove' class="cart-item-remove">
<i class="fas fa-trash"></i>
</a>
</div>
<!--end of cart item -->
<!-- cart item -->
<div class="cart-item d-flex justify-content-between text-capitalize my-3">
<img src="img-cart/doughnut-2.jpeg" class="img-fluid rounded-circle" id="item-img" alt="">
<div class="cart-item-text">
<p id="cart-item-title" class="font-weight-bold mb-0">cart item</p>
<span>$</span>
<span id="cart-item-price" class="cart-item-price" class="mb-0">10.99</span>
</div>
<a href="#" id='cart-item-remove' class="cart-item-remove">
<i class="fas fa-trash"></i>
</a>
</div>
<!--end of cart item -->
<!-- cart total -->
<div class="cart-total-container d-flex justify-content-around text-capitalize mt-5">
<h5>total</h5>
<h5> $ <strong id="cart-total" class="font-weight-bold">10.00</strong> </h5>
</div>
<!--end cart total -->
<!-- cart buttons -->
<div class="cart-buttons-container mt-3 d-flex justify-content-between">
<a href="#" id="clear-cart" class="btn btn-outline-secondary btn-black text-uppercase">clear cart</a>
<a href="#" class="btn btn-outline-secondary text-uppercase btn-pink">checkout</a>
</div>
<!--end of cart buttons -->
<!-- -->
</div>
</div>
</div>
<!--end of banner -->
</header>
<!-- header -->
<!-- about us -->
<section class="about py-5" id="about">
<div class="container">
<div class="row">
<div class="col-10 mx-auto col-md-6 my-5">
<h1 class="text-capitalize">about <strong class="banner-title ">us</strong></h1>
<p class="my-4 text-muted w-75">Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit, aliquam voluptas
beatae vitae expedita consectetur nesciunt quia deserunt asperiores facere fuga dicta fugiat corrupti et omnis
porro at dolorum! Ad!</p>
<a href="#" class="btn btn-outline-secondary btn-black text-uppercase ">explore</a>
</div>
<div class="col-10 mx-auto col-md-6 align-self-center my-5">
<div class="about-img__container">
<img src="img/sweets-1.jpeg" class="img-fluid" alt="">
</div>
</div>
</div>
</div>
</section>
<!-- end of about us -->
<!-- store -->
<section id="store" class="store py-5">
<div class="container">
<!-- section title -->
<div class="row">
<div class="col-10 mx-auto col-sm-6 text-center">
<h1 class="text-capitalize">our <strong class="banner-title ">store</strong></h1>
</div>
</div>
<!-- end of section title -->
<!--filter buttons -->
<div class="row">
<div class=" col-lg-8 mx-auto d-flex justify-content-around my-2 sortBtn flex-wrap">
<a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="all"> all</a>
<a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="cakes">cakes</a>
<a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="cupcakes">cupcakes</a>
<a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="sweets">sweets</a>
<a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="doughnuts">doughnuts</a>
</div>
</div>
<!-- search box -->
<div class="row">
<div class="col-10 mx-auto col-md-6">
<form>
<div class="input-group mb-3">
<div class="input-group-prepend ">
<span class="input-group-text search-box" id="search-icon"><i class="fas fa-search"></i></span>
</div>
<input type="text" class="form-control" placeholder='item....' id="search-item">
</div>
</form>
</div>
</div>
<!--end of filter buttons -->
<!-- store items-->
<div class="row" class="store-items" id="store-items">
<!-- single item -->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item sweets" data-item="sweets">
<div class="card ">
<div class="img-container">
<img src="img/sweets-1.jpeg" class="card-img-top store-img" alt="">
<span class="store-item-icon">
<i class="fas fa-shopping-cart"></i>
</span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">sweet item</h5>
<h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">5</strong></h5>
</div>
</div>
</div>
<!-- end of card-->
</div>
<!--end of single store item-->
<!-- single item -->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cupcakes" data-item="cupcakes">
<div class="card ">
<div class="img-container">
<img src="img/cupcake-1.jpeg" class="card-img-top store-img" alt="">
<span class="store-item-icon">
<i class="fas fa-shopping-cart"></i>
</span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">cupcake item</h5>
<h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">5</strong></h5>
</div>
</div>
</div>
<!-- end of card-->
</div>
<!--end of single store item-->
<!-- single item -->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cakes" data-item="cakes">
<div class="card ">
<div class="img-container">
<img src="img/cake-1.jpeg" class="card-img-top store-img" alt="">
<span class="store-item-icon">
<i class="fas fa-shopping-cart"></i>
</span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">cake item</h5>
<h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">5</strong></h5>
</div>
</div>
</div>
<!-- end of card-->
</div>
<!--end of single store item-->
<!-- single item -->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item doughnuts" data-item="dougnuts">
<div class="card ">
<div class="img-container">
<img src="img/doughnut-1.jpeg" class="card-img-top store-img" alt="">
<span class="store-item-icon">
<i class="fas fa-shopping-cart"></i>
</span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">dougnut item</h5>
<h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">5</strong></h5>
</div>
</div>
</div>
<!-- end of card-->
</div>
<!--end of single store item-->
<!-- single item -->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item sweets" data-item="sweets">
<div class="card ">
<div class="img-container">
<img src="img/sweets-2.jpeg" class="card-img-top store-img" alt="">
<span class="store-item-icon">
<i class="fas fa-shopping-cart"></i>
</span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">sweet item</h5>
<h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">10</strong></h5>
</div>
</div>
</div>
<!-- end of card-->
</div>
<!--end of single store item-->
<!-- single item -->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cupcakes" data-item="cupcakes">
<div class="card ">
<div class="img-container">
<img src="img/cupcake-2.jpeg" class="card-img-top store-img" alt="">
<span class="store-item-icon">
<i class="fas fa-shopping-cart"></i>
</span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">cupcake item</h5>
<h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">10</strong></h5>
</div>
</div>
</div>
<!-- end of card-->
</div>
<!--end of single store item-->
<!-- single item -->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cakes" data-item="cakes">
<div class="card ">
<div class="img-container">
<img src="img/cake-2.jpeg" class="card-img-top store-img" alt="">
<span class="store-item-icon">
<i class="fas fa-shopping-cart"></i>
</span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">cake item</h5>
<h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">10</strong></h5>
</div>
</div>
</div>
<!-- end of card-->
</div>
<!--end of single store item-->
<!-- single item -->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item doughnuts" data-item="dougnuts">
<div class="card ">
<div class="img-container">
<img src="img/doughnut-2.jpeg" class="card-img-top store-img" alt="">
<span class="store-item-icon">
<i class="fas fa-shopping-cart"></i>
</span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">dougnut item</h5>
<h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">10</strong></h5>
</div>
</div>
</div>
<!-- end of card-->
</div>
<!--end of single store item-->
<!-- single item -->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item sweets" data-item="sweets">
<div class="card ">
<div class="img-container">
<img src="img/sweets-3.jpeg" class="card-img-top store-img" alt="">
<span class="store-item-icon">
<i class="fas fa-shopping-cart"></i>
</span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">sweet item</h5>
<h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">15</strong></h5>
</div>
</div>
</div>
<!-- end of card-->
</div>
<!--end of single store item-->
<!-- single item -->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cupcakes" data-item="cupcakes">
<div class="card ">
<div class="img-container">
<img src="img/cupcake-3.jpeg" class="card-img-top store-img" alt="">
<span class="store-item-icon">
<i class="fas fa-shopping-cart"></i>
</span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">cupcake item</h5>
<h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">15</strong></h5>
</div>
</div>
</div>
<!-- end of card-->
</div>
<!--end of single store item-->
<!-- single item -->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cakes" data-item="cakes">
<div class="card ">
<div class="img-container">
<img src="img/cake-3.jpeg" class="card-img-top store-img" alt="">
<span class="store-item-icon">
<i class="fas fa-shopping-cart"></i>
</span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">cake item</h5>
<h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">15</strong></h5>
</div>
</div>
</div>
<!-- end of card-->
</div>
<!--end of single store item-->
<!-- single item -->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item doughnuts" data-item="dougnuts">
<div class="card ">
<div class="img-container">
<img src="img/doughnut-3.jpeg" class="card-img-top store-img" alt="">
<span class="store-item-icon">
<i class="fas fa-shopping-cart"></i>
</span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">dougnut item</h5>
<h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">15</strong></h5>
</div>
</div>
</div>
<!-- end of card-->
</div>
<!--end of single store item-->
</div>
</section>
<!--end of store items -->
<!-- modal-container -->
<div class="container-fluid ">
<div class="row lightbox-container align-items-center">
<div class="col-10 col-md-10 mx-auto text-right lightbox-holder">
<span class="lightbox-close"><i class="fas fa-window-close"></i></span>
<div class="lightbox-item"></div>
<span class="lightbox-control btnLeft"><i class="fas fa-caret-left"></i></span>
<span class="lightbox-control btnRight"><i class="fas fa-caret-right"></i></span>
</div>
</div>
</div>
<!-- jquery -->
<script src="js/jquery-3.3.1.min.js"></script>
<!-- bootstrap js -->
<script src="js/bootstrap.bundle.min.js"></script>
<!-- script js -->
<script src="js/app.js"></script>
</body>
</html>
Screenshots
Note: Make sure to download the bootstrap.css, bootstrap.js, and jquery.js library from the internet add them to the respective folders. You can download the images from the Github repository.
Download the complete source code from github repository
Original source https://jsbeginners.com/grocery-cart-javascript-project/