Build shopping cart functions with vanilla Javascript - javascript

I am trying to build a shopping cart function.
I have a product page, that displays API data. When pressing the "Add to cart" button, the item should be added to local storage, and fetched from local storage to build the html content for the shopping cart.
The cart page should display this:
A list of all products added to the cart, each item must include a title, price, a link to the product view page and a product image.
If the cart is empty I want to display a message indicating this.
After the list of products, i want to display the total price of all the products in the cart.
Here is the combined code for the productDetail page and all cart functions that I have built so far.
import { baseUrl } from "../../constants/api.js";
import displayMessage from "../displayMessage.js";
// const productsURL = baseUrl + "/products";
const queryString = document.location.search;
const params = new URLSearchParams(queryString);
const id = params.get ("id");
let cartArray = [];
if(!id) {
document.location.href ="./index.html";
}
const productsUrl = baseUrl + "/products/" + id;
const results = await fetch(productsUrl);
const details = await results.json();
export async function productDetails() {
try {
// const response = await fetch(productUrl);
// const details = await response.json();
document.title = details.name;
const productContainer = document.querySelector(".product__card");
productContainer.innerHTML = `
<img src="${baseUrl + details.image.url}" class="card-img-top rounded-0 card__image" alt="${details.image.name}">
<div class="card-body p-0 pt-2 details">
<h2 class="">${details.title}</h2>
<div class="accordion" id="accordionExample">
<div class="card product__details">
<div class="details__header p-0 mt-2">
<p class="mb-0">
<button class="btn btn-link btn-block text-left p-0 m-0 text-decoration-none text-transform-none" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
<span class="padding__wrapper details__btn">Details</span>
<i class="fas fa-chevron-down"></i>
</button>
</p>
</div>
<div id="collapseOne" class="collapse" aria-labelledby="headingOne" data-parent="#accordionExample">
<div class="card-body details__text">
${details.description}
</div>
</div>
</div>
</div>
<p class="card-text mt-2 details__price">
$${details.price}
</p>
<button class="btn btn-primary mt-3 shadow-none cart__button" data-product="${details.id}" type="button">
<span class="padding__wrapper">Add to cart</span>
<i class="fas fa-shopping-bag"></i>
</button>
</div>`;
const addCartButton = document.querySelectorAll("button.cart__button");
console.log(addCartButton);
addCartButton.forEach(function(button){
button.onclick = function(event) {
console.log(button);
cartArray.push(event.target.dataset.product);
console.log(cartArray);
// this line should look inside the function that loops the html and finds the item with the correct id
// const itemToAdd = details.find(item => item.id === event.target.dataset.product);
// console.log(itemToAdd);
// cartArray.push(itemToAdd);
// showCart(cartArray);
// localStorage.setItem("cartList", JSON.stringify(cartArray));
}
});
}catch(error) {
displayMessage("error", "Error when loading the product", ".product__card");
}
};
function showCart(cartItems) {
const cartContainer = document.querySelector(".cart__container");
const totalContainer = document.querySelector(".total__container");
cartContainer.innerHTML = "";
let total = 0;
cartItems.forEach(function (cartElement) {
total += cartElement.price;
cartContainer.innerHTML += `
<div class="row no-gutters">
<div class="loading"></div>
<div class="col-xs-4">
<img src="${baseUrl + cartElement.image.url}" class="card-img cart__product__image" alt="${cartElement.image.name}">
</div>
<div class="col-xs-8">
<div class="card-body">
<h5 class="card-title">${cartElement.title}</h5>
<p class="card-text">$${cartElement.price}</p>
<div class="row edit__amount">
<i class="fas fa-minus-circle"></i>
<div class=""></div>
<i class="fas fa-plus-circle"></i>
</div>
</div>
</div>
<div class="col-xs-4">
<i class="fas fa-trash-alt"></i>
</div>
</div>`;
})
totalContainer.innerHTML =
`<h2>Order Summary</h2>
<p>You order:</p>
<div class="table-responsive table-sm">
<table class="table">
<tr>
<td>Subtotal:</td>
<td>$${total}</td>
</tr>
<tr>
<td>Shipping:</td>
<td>Free Shipping</td>
</tr>
</table>
</div>
<hr/>
<div class="table-responsive table-sm">
<table class="table">
<tr>
<td>Total:</td>
<td>$${total}</td>
</tr>
</table>
</div>
To Checkout`;
};

Related

Making a search box works

I have a problem creating a search box i my JS code. The search needs to find in the restaurant name and the restaurant description. Actually when I search, the code duplicate the cards in my web because my function showRestaurants creates the cards of the web. I don't know how to fix this problem.
The JS code:
import { RestaurantService } from './restaurant-service.class.js';
import '../node_modules/bootstrap/dist/css/bootstrap.css';
import css from '../styles.css';
import RestaurantTemplate from '../templates/restaurant.handlebars';
let restaurants = [];
const restaurantService = new RestaurantService();
const weekdays = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
const currentDay = new Date().getDay();
restaurantService.getAll().then((array) => {
restaurants = array;
restaurants = array.filter((restaurant) => restaurants.id !== restaurant.id);
showRestaurants(restaurants);
});
function createCard(titleName, descriptionText, openDays, cuisineText, phone, image, id) {
// I need a new form to create the cards with handlebars
const objectCard = {
restaurantName: titleName,
restaurantDescription: descriptionText,
restaurantOpenDays: openDays.map(day => weekdays[day]).join(', '),
restaurantOpen: openDays.includes(String(currentDay)),
restaurantCuisine: cuisineText,
restaurantPhoneNumber: phone,
restaurantImageSource: image,
};
const htmlCard = RestaurantTemplate(objectCard);
const container = document.createElement('div');
container.className = 'col';
container.innerHTML = htmlCard;
container.getElementsByTagName('button')[0].addEventListener('click', () => {
if (window.confirm('Are you sure to delete this card?')) {
restaurantService.delete(id).then(() => {
container.remove();
});
}
});
document.getElementById('placesContainer').appendChild(container);
}
function showRestaurants(restaurants) {
for (let index = 0; index < restaurants.length; index++) {
createCard(restaurants[index].name, restaurants[index].description, restaurants[index].daysOpen, restaurants[index].cuisine, restaurants[index].phone, restaurants[index].image ,restaurants[index].id);
}
}
// Search box but actually duplicates the cards that find
document.getElementById('search').addEventListener('keyup', e => {
const searchRestaurant = restaurants.filter(restaurant =>
restaurant.name.toLowerCase().includes(document.getElementById('search').value.toLowerCase()) ||
restaurant.description.toLowerCase().includes(document.getElementById('search').value.toLowerCase()));
showRestaurants(searchRestaurant);
});
The html code:
<html>
<head>
<title>Exercise 3 | Home</title>
<meta charset="UTF-8">
</head>
<body>
<nav class="navbar navbar-expand navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">FoodScore</a>
<ul class="navbar-nav me-auto mb-lg-0">
<li class="nav-item">
<a class="nav-link active" href="index.html">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="new-restaurant.html">New restaurant</a>
</li>
</ul>
</div>
</nav>
<div class="container">
<!--Optional-->
<nav class="navbar navbar-light bg-light justify-content-between mt-3">
<form class="container-fluid">
<input class="form-control" type="text" name="search" id="search" placeholder="Search"
aria-label="Search">
</form>
</nav>
<div id="placesContainer" class="mb-4 mt-2 row row-cols-1 row-cols-md-2 row-cols-xl-3 g-4">
<!-- <div class="col">
<div class="card h-100 shadow">
<img class="card-img-top" src="IMAGE_BASE64">
<div class="card-body">
<button class="btn btn-danger btn-sm float-end">Delete</button>
<h4 class="card-title">Restaurant Name</h4>
<p class="card-text">Restaurant Description</p>
<div class="card-text">
<small class="text-muted">
<strong>Opens: </strong>Mo, Tu, We, Th, Fr, Sa, Su
</small>
<span class="badge ms-2 bg-success">Open</span>
</div>
<div class="card-text">
<small class="text-muted">
<strong>Phone: </strong>999999999
</small>
</div>
</div>
<div class="card-footer">
<small class="text-muted">Cuisine style</small>
</div>
</div>
</div> -->
</div>
</div>
</body>
</html>
The handlebars:
<div class="card h-100 shadow">
<img class="card-img-top" src="{{restaurantImageSource}}">
<div class="card-body">
<button class="btn btn-danger btn-sm float-end">Delete</button>
<h4 class="card-title">{{restaurantName}}</h4>
<p class="card-text">{{restaurantDescription}}</p>
<div class="card-text">
<small class="text-muted">
<strong>Opens: </strong>{{restaurantOpenDays}}
</small>
{{#if restaurantOpen}}
<span class="badge ms-2 bg-success">Open</span>
{{else}}
<span class="badge ms-2 bg-danger">Closed</span>
{{/if}}
</div>
<div class="card-text">
<small class="text-muted">
<strong>Phone: </strong>{{restaurantPhoneNumber}}
</small>
</div>
</div>
<div class="card-footer">
<small class="text-muted">{{restaurantCuisine}}</small>
</div>
</div>
I've tried making a function similar to showRestaurants to filter the array, but is not really necessary because the includes is already in the eventlistener from the search box.
Thanks to James for the clue, I can fix the problem with a function:
function clearRestaurants() {
const everyChildren = document.getElementById('placesContainer').children;
const arrayEveryChildren = Array.from(everyChildren);
for (let index = 0; index < arrayEveryChildren.length; index++) {
arrayEveryChildren[index].remove();
}
}
And adding the function just before the showRestaurants(searchRestaurant)

How to update JavaScript after executing a function?

Good day to all, I'm new to js, so I would like to ask you, after executing the function, I add a response with content via innerHTML, but this content should also work with javascript, but it works, so I have to restart the page, how to do it right so that my functions work with the added answer?
Need to run this code
document.querySelectorAll('.btn-comment-like, .btn-comment-dislike').forEach((e) =>
e.addEventListener('click', function(e) {
e.preventDefault()
const commentRatingButtons = this;
const commentRatingId = commentRatingButtons.getAttribute('data-id');
const commentRatingAction = commentRatingButtons.getAttribute('data-action');
const commentTotalRating = document.querySelector(`button[data-comment-rating='${commentRatingId}']`);
const commentMessageRating = document.querySelector(`div[data-comment-message='${commentRatingId}']`);
fetch(`/api/comments/${commentRatingId}/${commentRatingAction}/`, {
method: 'POST',
headers: {
"X-CSRFToken": csrftoken,
"X-Requested-With": "XMLHttpRequest",
},
}).then((response) => response.json()).then((result) => {
if (result['error']) {
commentMessageRating.innerHTML = `
<div class="alert alert-danger rounded-0 shadow-sm me-2 align-self-start mb-2" role="alert" style="padding:2px;">
<i class="fa-solid fa-hexagon-exclamation"></i> ${result['error']}!
</div>`
} else {
if (commentRatingAction === 'like') {
commentMessageRating.innerHTML = `
<div class="alert alert-success rounded-0 shadow-sm me-2 align-self-start mb-2" role="alert" style="padding:2px;">
<i class="fa-solid fa-face-smile"></i> Спасибо за оценку, ${result['author']}!
</div>`
} else {
commentMessageRating.innerHTML = `
<div class="alert alert-danger rounded-0 shadow-sm me-2 align-self-start mb-2" role="alert" style="padding:2px;">
<i class="fa-solid fa-face-frown"></i> Спасибо за критику, ${result['author']}!
</div>`
}
commentTotalRating.innerHTML = `${result['comment_total_rating']} <i class="fa-solid fa-hand-holding-heart"></i>`
}
})
})
)
after doing this
commentForm.addEventListener('submit', function(e) {
e.preventDefault()
const commentForm = this;
const commentFormSubmit = commentForm.querySelector('#commentSubmit');
const commentArticleId = commentForm.getAttribute('data-article-id');
const commentEmpty = document.querySelector('#emptyComments');
const commentNestedList = document.querySelector('.nested-comments');
commentFormSubmit.innerText = "Ожидаем добавления...";
commentFormSubmit.disabled = true;
fetch(`/api/articles/${commentArticleId}/comments/create/`, {
method: 'POST',
headers: {
"X-CSRFToken": csrftoken,
"X-Requested-With": "XMLHttpRequest",
},
body: new FormData(commentForm),
}).then((response => response.json()))
.then((result) => {
if (result['comment_is_child']) {
const commentParentThread = document.querySelector(`#comment-thread-${result['comment_parent_id']}`);
commentParentThread.innerHTML += `
<ul id="comment-thread-${result['comment_id']}">
<li>
<div class="card mb-3 nth-shadow border-0 rounded-1">
<div class="card-body">
<div class="row">
<div class="col-md-2 d-none d-sm-inline pe-0">
<img src="${result['comment_avatar']}" class="img-fluid rounded-1 nth-img-comment nth-shadow" alt="{{ node.author.username }}">
</div>
<div class="col-md-10">
<div class="d-flex flex-row gap-2">
<div class="card-title">
<h6 class="nth-card-user-username mb-0">${result['comment_author']}</h6>
</div>
<div class="nth-card-title-username">
${result['comment_created_at']}
</div>
</div>
<div class="card-text mb-2">
${result['comment_content']}
</div>
<div class="d-grid gap-2 d-md-block">
<button class="btn btn-outline-secondary nth-btn-sm btn-like shadow-none" data-id="${result['comment_id']}" data-action="like" type="button">+1 <i class="fa-solid fa-heart-circle-plus"></i></button>
<button class="btn btn-outline-secondary nth-btn-sm btn-dislike shadow-none" data-id="${result['comment_id']}" data-action="dislike" type="button">-1 <i class="fa-solid fa-heart-circle-minus"></i></button>
<button class="btn btn-outline-secondary nth-btn-sm shadow-none" type="button" data-comment-rating="${result['comment_id']}">${result['comment_total_rating']} <i class="fa-solid fa-hand-holding-heart"></i></button>
</div>
</div>
</div>
</div>
</div>
</li>
</ul>
`
} else {
if (commentEmpty) {
commentEmpty.remove();
}
commentNestedList.innerHTML += `
<ul id="comment-thread-${result['comment_id']}">
<li>
<div class="card mb-3 nth-shadow border-0 rounded-1">
<div class="card-body">
<div class="row">
<div class="col-md-2 d-none d-sm-inline pe-0">
<img src="${result['comment_avatar']}" class="img-fluid rounded-1 nth-img-comment nth-shadow" alt="{{ node.author.username }}">
</div>
<div class="col-md-10">
<div class="d-flex flex-row gap-2">
<div class="card-title">
<h6 class="nth-card-user-username mb-0">${result['comment_author']}</h6>
</div>
<div class="nth-card-title-username">
${result['comment_created_at']}
</div>
</div>
<div class="card-text mb-2">
${result['comment_content']}
</div>
<div class="d-grid gap-2 d-md-block">
<button class="btn btn-outline-secondary nth-btn-sm btn-comment-like shadow-none" data-id="${result['comment_id']}" data-action="like" type="button">+1 <i class="fa-solid fa-heart-circle-plus"></i></button>
<button class="btn btn-outline-secondary nth-btn-sm btn-comment-dislike shadow-none" data-id="${result['comment_id']}" data-action="dislike" type="button">-1 <i class="fa-solid fa-heart-circle-minus"></i></button>
<button class="btn btn-outline-secondary nth-btn-sm shadow-none" type="button" data-comment-rating="${result['comment_id']}">${result['comment_total_rating']} <i class="fa-solid fa-hand-holding-heart"></i></button>
</div>
</div>
</div>
</div>
</div>
</li>
</ul>
`
}
commentForm.reset();
commentFormSubmit.innerText = "Добавить комментарий";
commentFormSubmit.disabled = false;
commentFormParentField.value = null;
})
})
I would be very grateful if you direct me to the correctness of creating such methods.
If you are feeling lazy to add it to the function then do something like:
let href = "http://"; //the location of your own html file you are working on.
//This will open your file on a new tab
window.open(href, "_blank");
//This will close your own tab.
window.close();
In this way you can close and open the tab again if it does'nt work with: "window.location.reload".
Put all your js code that you want to reload in a function and simply call it again when you want to. You can also use: window.location.reload();

How do i add items to my cart using javascript?

When I click on a product in the store section I want it to go in the cart. For some reason nothing is showing up in the cart but empty space. `//show cart
(function(){
const cartInfo = document.getElementById('cart-info');
const cart = document.getElementById('cart');
cartInfo.addEventListener('click', function(){
cart.classList.toggle('show-cart')
})
})();
//add items to cart
(function() {
const cartBtn = document.querySelectorAll('.store-item-icon');
cartBtn.forEach(function(btn) {
btn.addEventListener('click', function(event) {
if (event.target.parentElement.classList.contains('store-item-icon'))
{
let fullPath =
event.target.parentElement.previousElementSibling.src;
let pos = fullPath.indexOf('img') + 3;
let partPath = fullPath.slice(pos);
const item = {};
item.img = `
img - cart$ {
partPath
}
`;
let name =
event.target.parentElement.parentElement.nextElementSibling
.children[0].children[0].textContent;
item.name = name;
let price =
event.target.parentElement.parentElement.nextElementSibling
.children[0].children[1].textContent;
let finalPrice = price.slice(1).trim();
item.price = finalPrice;
console.log(finalPrice);
console.log(item);
const cartItem = document.createElement('div')
cartItem.classList.add('cart-item', 'd-flex', 'justify-content-between',
'text-capitalize', 'my-3');
cartItem.innerHtML = ` < img
src = "${item.img}"
class = "img-fluid rounded-circle"
id = "item-img"
alt = "" /
>
<
div class = "item-text" >
<
p id = "cart-item-title"
class = "font-weight-bold mb-0" >
$ {
item.name
} <
/p> <
span > £ < /span> <
span id = "cart-item-price"
class = "cart-item-price mb-0" >
$ {
item.price
} < /span >
<
/div> <
a href = "#"
id = "cart-item-remove"
class = "cart-item-remove" >
<
i class = "fas fa-trash" > < /i> <
/a> <
/div> *
/
`;
//select cart
const cart = document.getElementById('cart');
const total = document.querySelector('.cart-total-container');
cart.insertBefore(cartItem, total);
alert('item added to the cart')
}
});
});
})();
<!--cart-->
<div class="cart" id="cart">
<!--cart item-->
<div class="cart-item d-flex justify-content-between text-capitalize my-3">
<img src="img-cart/creamicon.jpg" class="img-fluid rounded-circle" id="item-img" alt="" />
<div class="item-text">
<p id="cart-item-title" class="font-weight-bold mb-0">cart item</p>
<span>£ </span>
<span id="cart-item-price" class="cart-item-price mb-0">10.99</span>
</div>
<a href="#" id="cart-item-remove" class="cart-item-remove">
<i class="fas fa-trash"></i>
</a>
</div>
<!--cart item end-->
<!--cart item-->
<div class="cart-item d-flex justify-content-between text-capitalize my-3">
<img src="img-cart/creamicon2.jpg" class="img-fluid rounded-circle" id="item-img" alt="" />
<div class="item-text">
<p id="cart-item-title" class="font-weight-bold mb-0">cart item</p>
<span>£ </span>
<span id="cart-item-price" class="cart-item-price mb-0">10.99</span>
</div>
<a href="#" id="cart-item-remove" class="cart-item-remove">
<i class="fas fa-trash"></i>
</a>
</div>
<!--cart item end-->
<!--total-->
<div class="cart-total-container d-flex justify-content-around text-capitalize mt-5">
<h5>total</h5>
<h5>£ <strong id="cart-total" class="font-weight-bold">21.99</strong></h5>
</div>
<!--end of total-->
<!--buttons-->
<div class="cart-buttons-container mt-3 d-flex justify-content-between">
clear cart
checkout
</div>
</div>
</div>
</div>
<!--store items-->
<div class="row store-items" id="store-items">
<!-- single item-->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item sweets" data-item="sweets">
<div class="card single-item">
<div class="img-container">
<img src="img/bodybutter.jpg" class="card-img-top store-img" />
<span class="store-item-icon"><i class="fas fa-shopping-cart"></i> </span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">body butter</h5>
<h5 class="store-item-value">£ <strong id="store-item-price" class="font-weight-bold">10.99</strong></h5>
</div>
</div>
</div>
</div>
<!--singles item end -->
There are more then one errors in your code starting with innerHtML instead of innerHTML and incorrectly formatted template literal and incorrect bindings inside it ... so I have decided to just post a working code. Keep in mind that incorrect HTML will be treated as text only, so check the correctness of the HTML block you want to place inside innerHTML, because there was as an extra closing div also.
(function(){
const cartInfo = document.getElementById('cart-info');
const cart = document.getElementById('cart');
cartInfo.addEventListener('click', function(){
cart.classList.toggle('show-cart')
})
})();
//add items to cart
(function() {
const cartBtn = document.querySelectorAll('.store-item-icon');
cartBtn.forEach(function(btn) {
btn.addEventListener('click', function(event) {
if (event.target.parentElement.classList.contains('store-item-icon'))
{
let fullPath =
event.target.parentElement.previousElementSibling.src;
let pos = fullPath.indexOf('img') + 3;
let partPath = fullPath.slice(pos);
const item = {};
item.img = `img - cart${partPath}`;
let name = event.target.parentElement.parentElement.nextElementSibling
.children[0].children[0].textContent;
item.name = name;
let price =
event.target.parentElement.parentElement.nextElementSibling
.children[0].children[1].textContent;
let finalPrice = price.slice(1).trim();
item.price = finalPrice;
console.log(finalPrice);
console.log(item);
const cartItem = document.createElement('div')
cartItem.classList.add('cart-item', 'd-flex', 'justify-content-between', 'text-capitalize', 'my-3');
cartItem.innerHTML =
`<img src = "${item.img}" class="img-fluid rounded-circle" id="item-img" alt="" />
<div class="item-text">
<p id="cart-item-title" class="font-weight-bold mb-0">${item.name}</p>
<span>£ </span>
<span id="cart-item-price" class="cart-item-price mb-0">${item.price}</span>
</div>
<a href="#" id="cart-item-remove" class="cart-item-remove">
<i class="fas fa-trash"></i></a>`;
//select cart
const cart = document.getElementById('cart');
const total = document.querySelector('.cart-total-container');
cart.insertBefore(cartItem, total);
alert('item added to the cart')
}
});
});
})();
.cart.show-cart{display:block}
.cart{display:none; border: 1px solid #000; padding: 20px}
.store-items{margin:20px 0;border:1px solid #000;padding: 20px}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css" integrity="sha512-YWzhKL2whUzgiheMoBFwW8CKV4qpHQAEuvilg9FAn5VJUDwKZZxkJNuGM4XkWuk94WCrrwslk8yWNGmY1EduTA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<a id="cart-info" href="javascript:;">Toggle Cart</a>
<!--cart-->
<div class="cart" id="cart">
<!--cart item-->
<div class="cart-item d-flex justify-content-between text-capitalize my-3">
<img src="img-cart/creamicon.jpg" class="img-fluid rounded-circle" id="item-img" alt="" />
<div class="item-text">
<p id="cart-item-title" class="font-weight-bold mb-0">cart item</p>
<span>£ </span>
<span id="cart-item-price" class="cart-item-price mb-0">10.99</span>
</div>
<a href="#" id="cart-item-remove" class="cart-item-remove">
<i class="fas fa-trash"></i>
</a>
</div>
<!--cart item end-->
<!--cart item-->
<div class="cart-item d-flex justify-content-between text-capitalize my-3">
<img src="img-cart/creamicon2.jpg" class="img-fluid rounded-circle" id="item-img" alt="" />
<div class="item-text">
<p id="cart-item-title" class="font-weight-bold mb-0">cart item</p>
<span>£ </span>
<span id="cart-item-price" class="cart-item-price mb-0">10.99</span>
</div>
<a href="#" id="cart-item-remove" class="cart-item-remove">
<i class="fas fa-trash"></i>
</a>
</div>
<!--cart item end-->
<!--total-->
<div class="cart-total-container d-flex justify-content-around text-capitalize mt-5">
<h5>total</h5>
<h5>£ <strong id="cart-total" class="font-weight-bold">21.99</strong></h5>
</div>
<!--end of total-->
<!--buttons-->
<div class="cart-buttons-container mt-3 d-flex justify-content-between">
clear cart
checkout
</div>
</div>
</div>
</div>
<!--store items-->
<div class="row store-items" id="store-items">
<!-- single item-->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item sweets" data-item="sweets">
<div class="card single-item">
<div class="img-container">
<img src="img/bodybutter.jpg" class="card-img-top store-img" />
<span class="store-item-icon"><i class="fas fa-shopping-cart"></i></span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">body butter</h5>
<h5 class="store-item-value">£ <strong id="store-item-price" class="font-weight-bold">10.99</strong></h5>
</div>
</div>
</div>
</div>
<!--singles item end -->

How to get the text value in a div html by clicking on button

I want to get the text between the div tag by clicking on the button event
<div class="col-lg-3 col-md-6 mb-4">
<div class="pricing-table pricing-secondary">
<div class="price-header">
<h3 class="title text-white">Gold Plan</h3>
<div class="price">
<span class="dollar">&#8377</span> 7000
</div>
<span class="permonth">3 months</span>
</div>
<div class="price-footer">
<a data-toggle="modal" data-target="#myModal"
class="btn btn-primary btn-block btn-lg" href="javascript:void(0);">Book an
Online Appointment</a>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6 mb-4">
<div class="pricing-table pricing-third">
<div class="price-header">
<h3 class="title text-white">Diamond Plan</h3>
<div class="price text-primary">
<span class="dollar">&#8377</span> 12000
</div>
<span class="permonth">6 Months</span>
</div>
<div class="price-footer">
<a data-toggle="modal" data-target="#myModal"
class="btn btn-primary btn-block btn-lg" href="javascript:void(0);">Book an
Online Appointment</a>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6 mb-4">
<div class="pricing-table pricing-fourth">
<div class="price-header">
<h3 class="title text-white">Platinum Plan</h3>
<div class="price text-white">
<span class="dollar">&#8377</span> 15000
</div>
<span class="permonth">12 Months</span>
</div>
<div class="price-footer">
<a data-toggle="modal" data-target="#myModal"
class="btn btn-primary btn-block btn-lg" href="javascript:void(0);">Book an
Online Appointment</a>
</div>
</div>
</div>
I have this type of divs its around three or four I want to detect the value 12000 and the month 6 Months by clicking on this button
How can I achieve that.
Try
$(".price-footer .btn").on( "click", function(event) {
const parent = $(this).parents('.pricing-table');
const priceText = $('.price', parent).text().trim();
const priceParts = priceText.split(' ');
console.log(`priceText: ${priceParts[1]}`);
// Output: "priceText: 12000"
const permonthText = $('.permonth', parent).text().trim();
console.log(`permonthText: ${permonthText}`);
// Output: "permonthText: 6 Months"
});
Demo - https://codepen.io/vyspiansky/pen/MWybEEr
You can add ids to the elements you want to extract the contents of, then you can use document.getElementById(id) to get those elements, and use .innerText to extract the string contents.
Then with a string.replace() you can remove any non-numerical values, and convert the monetary value into a number.
const dollarAmount = parseFloat(document.getElementById("dollar-info").innerText.replace(/[^0-9.]/g, ''))
const month = document.getElementById("month-info").innerText
console.log(dollarAmount)
console.log(month)
<div class="price-header">
<h3 class="title text-white">Diamond Plan</h3>
<div id="dollar-info" class="price text-primary">
<span class="dollar">&#8377</span>12000.80
</div>
<span id="month-info" class="permonth">6 Months</span>
</div>
Assuming you have many price tables you can loop each table as below example. You can wrap you data in a certain class and get the text value of that class div. Click the button on the to get the value in the example below
$(document).ready(function(){
$('.pricing-table').each(function(){
var $table = $(this);
$table.on('click', '.btn-primary', function(){
var price = $table.find('.price').text().trim();
var permonth = $table.find('.permonth').text().trim();
alert("price is " + price + " for " + permonth);
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-lg-3 col-md-6 mb-4">
<div class="pricing-table pricing-third">
<div class="price-header">
<h3 class="title text-white">Diamond Plan</h3>
<div class="price text-primary">
<span class="dollar">&#8377</span> 12000
</div>
<span class="permonth">6 Months</span>
</div>
<div class="price-footer">
<a data-toggle="modal" data-target="#myModal"
class="btn btn-primary btn-block btn-lg" href="javascript:void(0);">Book an
Online Appointment</a>
</div>
</div>
</div>
There are so many options to do this. Here is my example with the snippet and code sandbox.
// jquery
const findValues = (target, value) => target.parents().eq(1).find(value);
$(document).on("click", ".btn", (e) => {
const $target = $(e.target);
// dollar is optional
const $dollar = findValues($target, ".dollar");
const $value = findValues($target, ".value");
const $month = findValues($target, ".permonth");
$("#test").text(`${$dollar.text()} ${$value.text()} ${$month.text()}`);
});
// // vanilla js
const test1 = document.querySelector("#test1");
document.querySelectorAll(".btn").forEach((btn) => {
btn.addEventListener("click", ({ target }) => {
const nodes = target.parentNode.parentNode;
const dollar1 = nodes.querySelector(".dollar");
const value1 = nodes.querySelector(".value");
const month1 = nodes.querySelector(".permonth");
test1.innerText = `${dollar1.textContent} ${value1.textContent} ${month1.textContent}`;
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-lg-3 col-md-6 mb-4">
<div class="pricing-table pricing-secondary">
<div class="price-header">
<h3 class="title text-white">Gold Plan</h3>
<div class="price">
<span class="dollar">&#8377</span> <span class="value">7000</span>
</div>
<span class="permonth">3 months</span>
</div>
<div class="price-footer">
<a data-toggle="modal" data-target="#myModal" class="btn btn-primary btn-block btn-lg"
href="javascript:void(0);">Book an
Online Appointment</a>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6 mb-4">
<div class="pricing-table pricing-third">
<div class="price-header">
<h3 class="title text-white">Diamond Plan</h3>
<div class="price text-primary">
<span class="dollar">&#8377</span> <span class="value">12000</span>
</div>
<span class="permonth">6 Months</span>
</div>
<div class="price-footer">
<a data-toggle="modal" data-target="#myModal" class="btn btn-primary btn-block btn-lg"
href="javascript:void(0);">Book an
Online Appointment</a>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6 mb-4">
<div class="pricing-table pricing-fourth">
<div class="price-header">
<h3 class="title text-white">Platinum Plan</h3>
<div class="price text-white">
<span class="dollar">&#8377</span> <span class="value">15000</span>
</div>
<span class="permonth">12 Months</span>
</div>
<div class="price-footer">
<a data-toggle="modal" data-target="#myModal" class="btn btn-primary btn-block btn-lg"
href="javascript:void(0);">Book an
Online Appointment</a>
</div>
</div>
</div>
<div id="test"></div>
<div id="test1"></div>
https://codesandbox.io/s/eager-voice-2w640?file=/src/index.js

My question is about getting a solution to calculate the total price of an order with javascript

I'm developping a web page were there is some products in their prices and the quantity of each one, what I'm trying to do, is to calculate the total price, but, with the same class name for every product
I've already tried the solution in the code bellow, but I'm not getting the right price
<ul class="list-group list-group-flush">
<li class="list-group-item">
<div class="row">
<div class="col-md-4">
<img src="../img/produit_newyork_0.jpeg" class="img-fluid float-left mr-5" width="80" height="60"/>
</div>
<div class="col-md-4">
<p class="mb-auto">Lego Architecture</p>
<p class="font-weight-bold">New York City</p>
<p class="font-italic">Quantité : <span class="qte">1</span></p>
</div>
<div class="col-md-4">
<h4 class="text-right prix">49,99€</h4>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button class="btn btn-outline-danger btn-sm float-right">Supprimer <i class="fas fa-trash-alt"></i></button>
</div>
</div>
</li>
<li class="list-group-item">
<div class="row">
<div class="col-md-4">
<img src="../img/produit_londres_0.jpeg" class="img-fluid float-left mr-5" width="80" height="60"/>
</div>
<div class="col-md-4">
<p class="mb-auto">Lego Architecture</p>
<p class="font-weight-bold">Londres City</p>
<p class="font-italic">Quantité : <span class="qte">3</span></p>
</div>
<div class="col-md-4">
<h4 class="text-right prix">49,99€</h4>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button class="btn btn-outline-danger btn-sm float-right">Supprimer <i class="fas fa-trash-alt"></i></button>
</div>
</div>
</li>
</ul>
<script type="text/javascript>
const qte = document.querySelectorAll('.qte');
const prix = document.querySelectorAll('.prix');
const prixPanier = document.querySelector('#prixPanier');
const TVA = document.querySelector('#TVA');
const Total = document.querySelector('#Total');
let prixTotal = 0;
for(let i=0; i < qte.length; i++){
prixTotal = prixTotal + (parseInt(qte[i].innerText)* parseFloat(prix[i].innerText));
}
prixPanier.innerText = prixTotal;
TVA.innerText = prixTotal * 0.15;
</script>
So what I'm looking for, is the right solution also for my last question, How can i add the total and the TVA so i can get the final or the total price ?
When you are working with numbers that contain symbols that are not detected or parsed with JavaScript internal functions, you should make sure to avoid those problems by simply removing the symbol before parsing anything.
This is how the code working looks like:
for(let i=0; i < qte.length; i++){
let price = parseFloat(prix[i].innerText.replace('€','').replace(',','.')),
quantity = parseInt(qte[i].innerText);
prixTotal += (quantity*price);
}
Also, it has kind of a better readability. I'll leave you a
Fiddle so you can check if it is giving your desired output:
https://jsfiddle.net/y0x84rwq/
You have some issues:
the price contain comma, need convert to dot before use.
let price = parseFloat(prix[i].innerHTML.replace(/,/g, '.')).toFixed(2);
This is worked code:
const qte = document.querySelectorAll('.qte');
const prix = document.querySelectorAll('.prix');
const prixPanier = document.querySelector('#prixPanier');
const TVA = document.querySelector('#TVA');
const Total = document.querySelector('#Total');
let prixTotal = 0.0;
for(let i=0; i < qte.length; i++){
let price = parseFloat(prix[i].innerText.replace(/,/g, '.')).toFixed(2);
//console.log(price)
prixTotal = prixTotal + (parseInt(qte[i].innerHTML)* price);
}
prixPanier.innerText = prixTotal;
TVA.innerText = prixTotal * 0.15;
<ul class="list-group list-group-flush">
<li class="list-group-item">
<div class="row">
<div class="col-md-4">
<img src="../img/produit_newyork_0.jpeg" class="img-fluid float-left mr-5" width="80" height="60"/>
</div>
<div class="col-md-4">
<p class="mb-auto">Lego Architecture</p>
<p class="font-weight-bold">New York City</p>
<p class="font-italic">Quantité : <span class="qte">1</span></p>
</div>
<div class="col-md-4">
<h4 class="text-right prix">49,99€</h4>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button class="btn btn-outline-danger btn-sm float-right">Supprimer <i class="fas fa-trash-alt"></i></button>
</div>
</div>
</li>
<li class="list-group-item">
<div class="row">
<div class="col-md-4">
<img src="../img/produit_londres_0.jpeg" class="img-fluid float-left mr-5" width="80" height="60"/>
</div>
<div class="col-md-4">
<p class="mb-auto">Lego Architecture</p>
<p class="font-weight-bold">Londres City</p>
<p class="font-italic">Quantité : <span class="qte">3</span></p>
</div>
<div class="col-md-4">
<h4 class="text-right prix">49,99€</h4>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button class="btn btn-outline-danger btn-sm float-right">Supprimer <i class="fas fa-trash-alt"></i></button>
</div>
</div>
</li>
</ul>
<div id="prixPanier"></div>
<div id="TVA"></div>

Categories