Skip to content

Instantly share code, notes, and snippets.

@caprosset
Last active October 23, 2022 15:32
Show Gist options
  • Save caprosset/648f01347377f65feeb0d7a2a8d78d02 to your computer and use it in GitHub Desktop.
Save caprosset/648f01347377f65feeb0d7a2a8d78d02 to your computer and use it in GitHub Desktop.
LAB solution - M1 | DOM Ironhack Cart
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<link rel="stylesheet" href="./css/style.css" />
<title>Ironhack Cart</title>
</head>
<body>
<h1>Ironhack Cart</h1>
<table id="cart">
<thead>
<tr>
<th>Product Name</th>
<th>Unit Price</th>
<th>Quantity</th>
<th>Subtotal</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr class="product">
<td class="name">
<span>Ironhack Rubber Duck</span>
</td>
<td class="price">$<span>25.00</span></td>
<td class="quantity">
<input type="number" value="0" min="0" placeholder="Quantity" />
</td>
<td class="subtotal">$<span>0</span></td>
<td class="action">
<button class="btn btn-remove">Remove</button>
</td>
</tr>
<!-- Iteration 2: Add more products here -->
<tr class="product">
<td class="name">
<span>Ironhack Shirt</span>
</td>
<td class="price">$<span>15.00</span></td>
<td class="quantity">
<input type="number" value="0" min="0" placeholder="Quantity" />
</td>
<td class="subtotal">$<span>0</span></td>
<td class="action">
<button class="btn btn-remove">Remove</button>
</td>
</tr>
</tbody>
<tfoot>
<!-- Iteration 5: Create new product -->
<tr class="create-product">
<td>
<input type="text" placeholder="Product Name" />
</td>
<td>
<input type="number" min="0" value="0" placeholder="Product Price" />
</td>
<td></td>
<td></td>
<td>
<button id="create" class="btn">Create Product</button>
</td>
</tr>
</tfoot>
</table>
<p class="calculate-total">
<button id="calculate" class="btn btn-success">Calculate Prices</button>
</p>
<h2 id="total-value">Total: $<span>0</span></h2>
<script type="text/javascript" src="./js/index.js"></script>
</body>
</html>
// get the parent of the product rows (that we will reuse in different functions)
var cartElement = document.querySelector("#cart tbody");
// ITERATION 1
function updateSubtot(product) {
// Get DOM elements that hold price and quantity
const priceElement = product.querySelector(".price span");
const qtyElement = product.querySelector(".quantity input");
// Extract values from DOM elements
const price = Number(priceElement.innerHTML); // convert string into number
const qty = Number(qtyElement.value); // convert string into number
// Calculate subtotal value
const subtotal = price * qty;
// Get DOM element that holds the subtotal value for the product
const subtotalElement = product.querySelector(".subtotal span");
// Set the product subtotal to the corresponding DOM element
subtotalElement.innerHTML = subtotal;
// Return subtotal value so it can be used later
return subtotal;
}
function calculateAll() {
// code in the following two lines is added just for testing purposes in iteration 1.
// const singleProduct = document.querySelector('.product');
// updateSubtotal(singleProduct);
// end of test
// ITERATIONS 2 & 3
// Get the DOM nodes for each product row
const productElements = document.querySelectorAll(".product"); // returns a Node List of product rows
// Declare an auxiliary variable that will hold the sum of each product subtotal
let totalPrice = 0;
// Iterate through the product nodes,
// call updateSubtot() on it and add the product subtotals to the total value
productElements.forEach(function(oneProduct) {
var productTotal = updateSubtot(oneProduct); // updates the subtotal element on each product row <tr>
totalPrice += productTotal;
});
// Get DOM element that holds the cart total value
var totalPriceElement = document.querySelector("#total-value span");
// Display the total value of products in cart in the appropriate node
totalPriceElement.textContent = totalPrice;
}
// ITERATION 4
function removeProduct(event) {
const target = event.currentTarget;
console.log('The target in remove is:', target);
const productToRemove = target.parentNode.parentNode;
cartElement.removeChild(productToRemove);
calculateAll(); // calculates the new cart total, after product removal
}
// ITERATION 4 - Create a binding function that will allow us to easily bind the eventListener to any "Remove" button
function bindDeleteButton(deleteButton) {
deleteButton.addEventListener("click", removeProduct);
}
// ITERATION 5
function createProduct() {
let nameElement = document.querySelector('.create-product input[type="text"]');
let priceElement = document.querySelector('.create-product input[type="number"]');
console.log(nameElement);
console.log(priceElement);
let newProductTr = document.createElement('tr'); // Create new tr element
newProductTr.setAttribute('class', 'product'); // same as => newProductTr.className = "product";
// use innerHTML to create child elements inside <tr>
newProductTr.innerHTML = `
<td class="name">
<span>${nameElement.value}</span>
</td>
<td class="price">$<span>${priceElement.value}</span></td>
<td class="quantity">
<input type="number" value="0" min="0" placeholder="Quantity" />
</td>
<td class="subtotal">$<span>0</span></td>
<td class="action">
<button class="btn btn-remove">Remove</button>
</td>
`;
// append the newly created row to the parent
cartElement.appendChild(newProductTr);
// make sure remove button inherits the same behavior as other remove buttons
var newRemoveButton = newProductTr.querySelector('.btn-remove');
newRemoveButton.addEventListener('click', removeProduct);
// clean the fields
nameElement.value = "";
priceElement.value = 0;
}
// this code is ran once, on page load
window.addEventListener('load', () => {
const calculatePricesBtn = document.getElementById('calculate');
calculatePricesBtn.addEventListener('click', calculateAll);
// ITERATION 4
const removeButtons = cart.getElementsByClassName('btn-remove'); // returns an HTML collection, needs to be spread into an array to iterate on it
[...removeButtons].forEach(button => button.addEventListener('click', removeProduct));
// ITERATION 5
const createButton = document.getElementById('create');
if(createButton) {
createButton.addEventListener('click', createProduct);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment