Last active
May 20, 2023 09:33
-
-
Save umutyerebakmaz/fa824be8196bad0bce3b002e2d741617 to your computer and use it in GitHub Desktop.
Pure JavaScript Advanced shopping cart localstorage storage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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