Skip to content

Instantly share code, notes, and snippets.

@umutyerebakmaz
Last active May 20, 2023 09:33
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save umutyerebakmaz/fa824be8196bad0bce3b002e2d741617 to your computer and use it in GitHub Desktop.
Save umutyerebakmaz/fa824be8196bad0bce3b002e2d741617 to your computer and use it in GitHub Desktop.
Pure JavaScript Advanced shopping cart localstorage storage
const openCartBtn = document.querySelector(".open-cart");
const closeCartBtn = document.querySelector(".close-cart");
const clearCartBtn = document.querySelector(".clear-cart");
const cartDOM = document.querySelector(".cart");
const cartOverlay = document.querySelector(".cart-overlay");
const cartItems = document.querySelector(".cart-items");
const cartTotal = document.querySelector(".cart-total");
const checkoutTotal = document.querySelector(".checkout-total");
const itemTotal = document.querySelector(".item-total");
const cartContent = document.querySelector(".cart-content");
const checkoutContent = document.querySelector(".checkout-content");
const placeOrderBtn = document.querySelector(".place-order-btn");
const leaveNote = document.getElementById("leaveNote");
const csrfToken = document.head.querySelector("[name~=csrf-token][content]").content;
let cart = [];
let buttonsDOM = [];
class Products {
async getProducts() {
try {
let result = await fetch('products');
return await result.json();
}
catch (error) {
console.log(error);
}
}
}
class UI {
getBagButtons() {
let buttons = [...document.querySelectorAll(".bag-btn")];
buttonsDOM = buttons;
buttons.forEach(button => {
let id = parseInt(button.dataset.id);
let inCart = cart.find(item => item.id === id);
if (inCart) {
button.innerText = "In Cart";
button.disabled = true;
}
button.addEventListener("click", event => {
// disable button
event.target.innerText = "In Cart";
event.target.disabled = true;
// add to cart
let cartItem = { ...Storage.getProduct(id), amount: 1 };
cart = [...cart, cartItem];
Storage.saveCart(cart);
// add to DOM
this.setCartValues(cart);
this.addCartItem(cartItem);
this.addCheckoutItem(cartItem);
});
});
};
setCartValues(cart) {
let tempTotal = 0;
let itemsTotal = 0;
cart.map(item => {
tempTotal += item.price * item.amount;
itemsTotal += item.amount;
});
cartTotal.innerText = parseFloat(tempTotal.toFixed(2));
cartItems.innerText = itemsTotal;
if (itemTotal) {
itemTotal.innerText = `(${itemsTotal})`;
checkoutTotal.innerText = parseFloat(tempTotal.toFixed(2));
}
};
addCartItem(item) {
const div = document.createElement("div");
div.classList.add("cart-item");
div.innerHTML = `
<img src="/img/doner.jpg" alt="${item.title}">
<div class="cart-item-info">
<h4>${item.title}</h4>
<h5>$${item.price}</h5>
<span class="remove-item" data-id="${item.id}">remove</span>
</div>
<div class="chevrons">
<span class="fas fa-chevron-up" data-id=${item.id}></span>
<span class="item-amount">${item.amount}</span>
<span class="fas fa-chevron-down" data-id=${item.id}></span>
</div>
`;
cartContent.appendChild(div);
};
addCheckoutItem(item) {
const div = document.createElement("div");
div.classList.add("checkout-item");
div.innerHTML = `
<div class="checkout-item-row">
<div>${item.title}</div>
<div class="price">$${item.price}</div>
<div>X ${item.amount}</div>
</div>
`;
if(checkoutContent){
checkoutContent.appendChild(div);
}
};
showCart() {
cartOverlay.classList.add("transparentBcg");
cartDOM.classList.add("showCart");
};
hideCart() {
cartOverlay.classList.remove("transparentBcg");
cartDOM.classList.remove("showCart");
};
setupAPP() {
cart = Storage.getCart();
this.setCartValues(cart);
this.populateCart(cart);
this.populateCheckout(cart);
openCartBtn.addEventListener("click", this.showCart);
closeCartBtn.addEventListener("click", this.hideCart);
if(placeOrderBtn) {
placeOrderBtn.addEventListener("click", this.placeOrderPost);
}
};
populateCart(cart) {
cart.forEach(item => this.addCartItem(item));
};
populateCheckout(cart) {
cart.forEach(item => this.addCheckoutItem(item));
};
cartLogic() {
clearCartBtn.addEventListener("click", () => {
this.clearCart();
});
cartContent.addEventListener("click", event => {
if (event.target.classList.contains("remove-item")) {
let removeItem = event.target;
let id = parseInt(removeItem.dataset.id);
cartContent.removeChild(removeItem.parentElement.parentElement);
this.removeItem(id);
} else if (event.target.classList.contains("fa-chevron-up")) {
let addAmount = event.target;
let id = parseInt(addAmount.dataset.id);
let tempItem = cart.find(item => item.id === id);
tempItem.amount = tempItem.amount + 1;
Storage.saveCart(cart);
this.setCartValues(cart);
addAmount.nextElementSibling.innerText = tempItem.amount;
} else if (event.target.classList.contains("fa-chevron-down")) {
let lowerAmount = event.target;
let id = parseInt(lowerAmount.dataset.id);
let tempItem = cart.find(item => item.id === id);
tempItem.amount = tempItem.amount - 1;
if (tempItem.amount > 0) {
Storage.saveCart(cart);
this.setCartValues(cart);
lowerAmount.previousElementSibling.innerText = tempItem.amount;
} else {
cartContent.removeChild(lowerAmount.parentElement.parentElement);
this.removeItem(id);
}
}
});
};
clearCart(){
let cartItems = cart.map(item => item.id);
cartItems.forEach(id => this.removeItem(id));
while (cartContent.children.length > 0) {
cartContent.removeChild(cartContent.children[0]);
}
this.hideCart();
};
removeItem(id) {
cart = cart.filter(item => item.id !== parseInt(id));
this.setCartValues(cart);
Storage.saveCart(cart);
let button = this.getSingleButton(id);
if(button) {
button.disabled = false;
button.innerHTML = `<span class="fas fa-shopping-cart"></span>add to bag`;
}
};
getSingleButton(id) {
return buttonsDOM.find(button => parseInt(button.dataset.id) === id);
};
itemListPlainText(cart) {
let template = ``;
for (let item of cart) {
template += `<span>${item.title} - x ${item.amount}</span>`;
}
return template;
};
placeOrderPost() {
const order = {
user_id: parseInt(document.getElementById("userId").value),
item_list: this.itemListPlainText(cart),
total: parseFloat(document.querySelector(".checkout-total").innerHTML),
leave_note: leaveNote.value
};
this.sendData(order);
};
sendData(order) {
fetch('/orders', {
method: 'post',
body: JSON.stringify(order),
headers: {
'Conent-Type': 'application/json',
"X-CSRF-Token": csrfToken
}
})
.then(response => {
if(response.status === 200) {
const placeOrderBtn = document.querySelector('.place-order-btn');
placeOrderBtn.innerText = "THANK YOU FOR CHOOSING US !";
placeOrderBtn.disabled = true;
setTimeout(() => {
placeOrderBtn.innerText = "PLACE ORDER";
placeOrderBtn.disabled = false;
}, 15000);
}
return response.json();
})
.then(text => {
return console.log(text);
})
.catch(error => console.error(error));
}
}
class Storage {
static saveProducts(products) {
localStorage.setItem('products', JSON.stringify(products));
}
static getProduct(id) {
let products = JSON.parse(localStorage.getItem('products'));
return products.find(product => product.id === id);
}
static saveCart(cart) {
localStorage.setItem("cart", JSON.stringify(cart));
}
static getCart() {
return localStorage.getItem("cart")
? JSON.parse(localStorage.getItem("cart"))
: [];
}
}
document.addEventListener("DOMContentLoaded", () => {
const ui = new UI();
const products = new Products();
ui.setupAPP();
products
.getProducts()
.then(products => {
Storage.saveProducts(products);
})
.then(() => {
ui.getBagButtons();
ui.cartLogic();
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment