curriculum/challenges/english/blocks/learn-basic-oop-by-building-a-shopping-cart/63f0374d5351223a747c301d.md
Following the same pattern as your cartSubTotal, update the cartTaxes to display the tax value, and your cartTotal to display the total property.
You should access the textContent property of the cartTaxes element.
assert.match(cart.calculateTotal.toString(), /cartTaxes\.textContent/);
You should call the .toFixed() method on the tax variable, passing 2 as the argument.
assert.match(cart.calculateTotal.toString(), /tax\.toFixed\(\s*2\s*\)/);
You should use template literal syntax to add the dollar sign before your .toFixed() call.
const afterCalculateTotal = code.split('calculateTotal')[1];
assert.match(afterCalculateTotal, /`\$\$\{tax\.toFixed\(\s*2\s*\)\}\`/);
You should set the textContent of the cartTaxes element to tax.toFixed template string.
const afterCalculateTotal = code.split('calculateTotal')[1];
assert.match(afterCalculateTotal, /cartTaxes\.textContent\s*=\s*`\$\$\{tax\.toFixed\(\s*2\s*\)\}\`/);
You should access the textContent property of the cartTotal element.
assert.match(cart.calculateTotal.toString(), /cartTotal\.textContent/);
You should call the .toFixed() method on the total variable, passing 2 as the argument. Remember to use the this keyword.
assert.match(cart.calculateTotal.toString(), /this\.total\.toFixed\(\s*2\s*\)/);
You should use template literal syntax to add the dollar sign before your .toFixed() call.
const afterCalculateTotal = code.split('calculateTotal')[1];
assert.match(afterCalculateTotal, /`\$\$\{this\.total\.toFixed\(\s*2\s*\)\}\`/);
You should set the textContent of the cartTotal element to your total.toFixed template string.
const afterCalculateTotal = code.split('calculateTotal')[1];
assert.match(afterCalculateTotal, /cartTotal\.textContent\s*=\s*`\$\$\{this\.total\.toFixed\(\s*2\s*\)\}\`/);
<!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>freeCodeCamp Shopping Cart</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<header>
<h1 class="title">Desserts Page</h1>
</header>
<main>
<button id="cart-btn" type="button" class="btn">
<span id="show-hide-cart">Show</span> Cart
</button>
<div id="cart-container">
<button class="btn" id="clear-cart-btn">Clear Cart</button>
<div id="products-container"></div>
<p>Total number of items: <span id="total-items">0</span></p>
<p>Subtotal: <span id="subtotal">$0</span></p>
<p>Taxes: <span id="taxes">$0</span></p>
<p>Total: <span id="total">$0</span></p>
</div>
<div id="dessert-card-container"></div>
</main>
<script src="./script.js"></script>
</body>
</html>
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #1b1b32;
--light-grey: #f5f6f7;
--black: #000;
--white: #fff;
--grey: #3b3b4f;
--golden-yellow: #fecc4c;
--yellow: #ffcc4c;
--gold: #feac32;
--orange: #ffac33;
--dark-orange: #f89808;
}
body {
background-color: var(--dark-grey);
}
.title {
color: var(--light-grey);
text-align: center;
margin: 25px 0;
}
#dessert-card-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
}
.dessert-card {
background-color: var(--light-grey);
padding: 15px;
text-align: center;
border-radius: 15px;
margin: 20px 10px;
}
.dessert-price {
font-size: 1.2rem;
}
.btn {
display: block;
cursor: pointer;
width: 100px;
color: var(--dark-grey);
background-color: var(--gold);
background-image: linear-gradient(var(--golden-yellow), var(--orange));
border-color: var(--gold);
border-width: 3px;
}
.btn:hover {
background-image: linear-gradient(var(--yellow), var(--dark-orange));
}
#cart-btn {
position: absolute;
top: 0;
right: 0;
}
.add-to-cart-btn {
margin: 30px auto 10px;
}
#cart-container {
display: none;
position: absolute;
top: 60px;
right: 0;
background-color: var(--light-grey);
width: 200px;
height: 400px;
border: 8px double var(--black);
border-radius: 15px;
text-align: center;
font-size: 1.2rem;
overflow-y: scroll;
}
.product {
margin: 25px 0;
}
.product-count {
display: inline-block;
margin-right: 10px;
}
.product-category {
margin: 10px 0;
}
@media (min-width: 768px) {
#dessert-card-container {
flex-direction: row;
}
.dessert-card {
flex: 1 0 21%;
}
#cart-container {
width: 300px;
}
}
const cartContainer = document.getElementById("cart-container");
const productsContainer = document.getElementById("products-container");
const dessertCards = document.getElementById("dessert-card-container");
const cartBtn = document.getElementById("cart-btn");
const clearCartBtn = document.getElementById("clear-cart-btn");
const totalNumberOfItems = document.getElementById("total-items");
const cartSubTotal = document.getElementById("subtotal");
const cartTaxes = document.getElementById("taxes");
const cartTotal = document.getElementById("total");
const showHideCartSpan = document.getElementById("show-hide-cart");
let isCartShowing = false;
const products = [
{
id: 1,
name: "Vanilla Cupcakes (6 Pack)",
price: 12.99,
category: "Cupcake",
},
{
id: 2,
name: "French Macaron",
price: 3.99,
category: "Macaron",
},
{
id: 3,
name: "Pumpkin Cupcake",
price: 3.99,
category: "Cupcake",
},
{
id: 4,
name: "Chocolate Cupcake",
price: 5.99,
category: "Cupcake",
},
{
id: 5,
name: "Chocolate Pretzels (4 Pack)",
price: 10.99,
category: "Pretzel",
},
{
id: 6,
name: "Strawberry Ice Cream",
price: 2.99,
category: "Ice Cream",
},
{
id: 7,
name: "Chocolate Macarons (4 Pack)",
price: 9.99,
category: "Macaron",
},
{
id: 8,
name: "Strawberry Pretzel",
price: 4.99,
category: "Pretzel",
},
{
id: 9,
name: "Butter Pecan Ice Cream",
price: 2.99,
category: "Ice Cream",
},
{
id: 10,
name: "Rocky Road Ice Cream",
price: 2.99,
category: "Ice Cream",
},
{
id: 11,
name: "Vanilla Macarons (5 Pack)",
price: 11.99,
category: "Macaron",
},
{
id: 12,
name: "Lemon Cupcakes (4 Pack)",
price: 12.99,
category: "Cupcake",
},
];
products.forEach(
({ name, id, price, category }) => {
dessertCards.innerHTML += `
<div class="dessert-card">
<h2>${name}</h2>
<p class="dessert-price">$${price}</p>
<p class="product-category">Category: ${category}</p>
<button
id="${id}"
class="btn add-to-cart-btn">Add to cart
</button>
</div>
`;
}
);
class ShoppingCart {
constructor() {
this.items = [];
this.total = 0;
this.taxRate = 8.25;
}
addItem(id, products) {
const product = products.find((item) => item.id === id);
const { name, price } = product;
this.items.push(product);
const totalCountPerProduct = {};
this.items.forEach((dessert) => {
totalCountPerProduct[dessert.id] = (totalCountPerProduct[dessert.id] || 0) + 1;
})
const currentProductCount = totalCountPerProduct[product.id];
const currentProductCountSpan = document.getElementById(`product-count-for-id${id}`);
currentProductCount > 1
? currentProductCountSpan.textContent = `${currentProductCount}x`
: productsContainer.innerHTML += `
<div id="dessert${id}" class="product">
<p>
<span class="product-count" id="product-count-for-id${id}"></span>${name}
</p>
<p>${price}</p>
</div>
`;
}
getCounts() {
return this.items.length;
}
calculateTaxes(amount) {
return parseFloat(((this.taxRate / 100) * amount).toFixed(2));
}
--fcc-editable-region--
calculateTotal() {
const subTotal = this.items.reduce((total, item) => total + item.price, 0);
const tax = this.calculateTaxes(subTotal);
this.total = subTotal + tax;
cartSubTotal.textContent = `$${subTotal.toFixed(2)}`;
}
--fcc-editable-region--
};
const cart = new ShoppingCart();
const addToCartBtns = document.getElementsByClassName("add-to-cart-btn");
[...addToCartBtns].forEach(
(btn) => {
btn.addEventListener("click", (event) => {
cart.addItem(Number(event.target.id), products);
totalNumberOfItems.textContent = cart.getCounts();
})
}
);
cartBtn.addEventListener("click", () => {
isCartShowing = !isCartShowing;
showHideCartSpan.textContent = isCartShowing ? "Hide" : "Show";
cartContainer.style.display = isCartShowing ? "block" : "none";
});