I picked up where I left off. I need to make the 'Add to cart' buttons work.
As with the 'Remove from cart' and quantity inputs, I need to create a value in my ready function, addToCartButtons. I then started working on the addToCartClicked function.
When a user clicks the 'Add to cart' button, I need to create a row in the cart featuring an image of the item, the item name, the item price, the quantity (default set to 1) and the remove button.
I need to get the image, item name and item price out of information in the HTML. I used the hierarchy of the HTML to select the parent of the parent of the 'Add to cart' button (ie the element containing all of the HTML for each item in my shop). I could then query (via the getElementsByClass function) to pull out the item title and price.
I want to draw out the source of the image file, to display in the cart. INstead of querying the innerText of the element class shop-item-image, I used the src attribute to get the image source.
My code now looks like this (I've added a console command so that I can check that it is working, since I haven't got a way of adding this data to a row on the cart yet).
function addToCartClicked(event) {
var button = event.target
var shopItem = button.parentElement.parentElement
var title = shopItem.getElementsByClassName("shop-item-title")[0].innerText
var price = shopItem.getElementsByClassName("shop-item-price")[0].innerText
var imageSrc = shopItem.getElementsByClassName("shop-item-image")[0].src
console.log(title, price, imageSrc)
}
Apparently, this will be the most complex part of the process. Yikes!
I started by adding a method (addItemToCart) which included the title, price and imageSrc variables. I then started creating the addItemToCart function.
I create a cartRow variable, which included a command to help me add a div (rather than find one) to the HTML once a user clicks the 'Add to cart' button.
function addItemToCart(title, price, imageSrc) {
var cartRow = document.createElement('div')
}
I then queried to get the cart items container (which contains all of the cart rows) and appended this new div onto the end of the list of cart items. I added a line of code to add innerText to the variable cartRow, which was set to title - and I was able to click the 'Add to cart' and see the title appear at the bottom of the cart.
But I want the whole row to appear, with an image and the price, and the remove button. So I was told to create HTML.
I copied the HTML for each row of the cart table from my HTML file and pasted it between back speech marks (so that I could paste multiple lines of code) in the addItemToCart function. I pasted in the HTML for the contents of a row of the cart.
And after adding the class of cart-row (for styling) to this new <div>, which is generated in Javascript, I was able to add a new row to the cart.
function addItemToCart(title, price, imageSrc) {
var cartRow = document.createElement("div")
cartRow.classList.add("cart-row")
var cartItems = document.getElementsByClassName("cart-items")[0]
var cartRowContents = `
<div class="cart-item cart-column">
<img class="cart-item-image" src="Images/tshirt.jpg" width="100">
<span class="cart-item-title">T-Shirt</span>
</div>
<span class="cart-price cart-column">£19.99</span>
<div class="cart-quantity cart-column">
<input class="cart-quantity-input" type="number" value="1">
<button class="btn btn-danger" role="button">REMOVE</button>
</div>
`
cartRow.innerHTML = cartRowContents
cartItems.append(cartRow)
}
But this meant that I was adding a t-shirt row every time (since this is the HTML content I copied. I needed to add variables to the HTML so that clicking an 'Add to cart' button added that item to the cart.
I used ${variable} to insert variable content where I could.
var cartRowContents = `
<div class="cart-item cart-column">
<img class="cart-item-image" src="${imageSrc}" width="100">
<span class="cart-item-title">${title}</span>
</div>
<span class="cart-price cart-column">${price}</span>
<div class="cart-quantity cart-column">
<input class="cart-quantity-input" type="number" value="1">
<button class="btn btn-danger" role="button">REMOVE</button>
</div>
`
This worked nicely, but I need to add a check to make sure I can't add two rows of the same content to the cart.
I added the following code to loop through each item in the cart once a user clicks on an 'Add to cart' button. The loop checks if the title of the item they've just clicked matches any titles in the cart already. If it does, the user gets an error message saying "This item is already in the cart", and the code stops, so the item is not added to the cart.
var cartItemNames = cartItems.getElementsByClassName("cart-item-title")
for (var i = 0; i < cartItemNames.length; i++) {
if (cartItemNames[i].innerText == title) {
alert("This item is already added to the cart")
return
}
A quick thing. I spotted the total wasn't updating when new items are added to the cart. This was quickly remedied by calling the updateCartTotal function within the addItemToCart function.
The functionality for the cart (mentioned in the previous post) only worked on page load. Since new rows are added after the page has loaded, I need to write similar code for the addItemToCart function. So the total is updated once new items are added to the cart.
I added two lines at the bottom of my addItemToCart function to add event listeners to the remove button and the quantity input. I called the relevant functions to each of these listeners.
cartRow.getElementsByClassName("btn-danger")[0].addEventListener("click", removeCartItem)
cartRow.getElementsByClassName("cart-quantity-input")[0].addEventListener("change", quantityChanged)
I created two rows of shopping cart data so that I could code out the styling and functionality. Since I no longer need these two rows to show on page load, I can remove them from my HTML.
we want to alert the user that they have purchased whatever was in the cart and remove all items in the cart. I used a while loop, which will keep executing so long as the statement is true.
Below, when a user clicks the purchase button, they will get a notification saying they've purchased their items. The while loop will then remove each child within the cart-items container (ie each cart-row), starting from the top cart-row, until there are no more cart-rows left, at which point the function will stop.
function purchaseClicked() {
alert("Thank you for your purchase")
var cartItems = document.getElementsByClassName("cart-items")[0]
while (cartItems.hasChildNodes()) {
cartItems.removeChild(cartItems.firstChild)
}
updateCartTotal()
}
The cart total is also updated to £0.00 since the cart has been emptied by the purchase.
Website complete. Though I can't show it because I don't know how to upload it to the web :)
I will do more tutorials later...