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 -->
Related
My Basket.js file
function test(){
let baskets = document.querySelectorAll('.basket');
baskets.forEach((basket) => {
$(basket).on("click",function(event){
console.log("clicked")
let productId;
let productName;
let productDiscount;
let productPrice;
let productImage;
let check = $(".gridDisable").attr("id");
if (check === "list") {
let parentDataSort = $(this).closest(".dateSort");
productId = parseInt(parentDataSort.find('.cartProduct').val())
productDiscount = $(this).closest(".dateSort").data("discount");
productName = parentDataSort.data("name");
productDiscount = parentDataSort.data("discount");
productPrice = productDiscount ? parentDataSort.find(".discountResult").data("result") : parentDataSort.data("price");
productImage = parentDataSort.find('.product-img-file').attr('src');
} else {
let parentDataColumn = $(this).closest(".dateSortColumn");
productId = parseInt(parentDataColumn.find('.cartProduct').val())
productDiscount = $(this).closest(".dateSortColumn").data("discount");
productName = parentDataColumn.data("name");
productDiscount = parentDataColumn.data("discount");
productPrice = productDiscount ? parentDataColumn.find(".discountResult").data("result") : parentDataColumn.data("price");
productImage = parentDataColumn.find('.product-image').attr('src');
}
addToBasket(productId, productName, productPrice, productImage);
})
})
}
test();
function addToBasket(productId, productName, productPrice, productImage) {
let cart = localStorage.getItem("cart");
let pCart = JSON.parse(cart) != null ? JSON.parse(cart) : [];
let present_or_not = pCart.findIndex(item => item.productId === productId);
if (cart == null || present_or_not == null || present_or_not === -1) {
let product = {
productId: productId,
productName: productName,
pPrice: productPrice,
quantity: 1,
image: productImage
};
pCart.push(product);
localStorage.setItem("cart", JSON.stringify(pCart));
} else {
let actual_stored_product = pCart[present_or_not];
pCart.splice(present_or_not, 1);
let actual_qty = actual_stored_product.quantity == null || actual_stored_product.quantity === "" ? 0 : actual_stored_product.quantity;
actual_stored_product.quantity = parseInt(actual_qty) + 1;
pCart.push(actual_stored_product);
localStorage.setItem("cart", JSON.stringify(pCart));
}
swal({
title: "Səbətə əlavə olundu",
icon: "success",
button: "Bağla",
});
let count = JSON.parse(localStorage.getItem("cart")).length;
$(".basket_count").text(count);
}
My active.js file
function showFilteredPriceProduct(min, max, isNew) {
$.get("/product/price?min=" + min + "&max=" + max + "&isNew=" + isNew, function (data) {
$("#column").empty();
$("#grid").empty();
if (data.data.length <= 10) {
$("#pagen").hide();
} else {
$("#pagen").show();
}
$.each(data.data, function (key, v) {
let item_content = `<div class="col-md-12 ml-4 my-3 py-2 dateSortColumn" data-name="${v.name}" data-price="${v.price}" data-discount="${v.isDiscount}">
${v.isNew ? `<div class="ribbon text-center" >Yeni<br></div>` : `<small style="display:none !important"></small>`}
${v.isDiscount ? `<div class="discount">- ${v.discount} %</div>` : `<small style="display:none !important"></small>`}
<div class="row bg-white">
<div class="col-md-3 mt-1">
<div class="container" id="wishlist">
<i class="far fa-heart js-heart heart"></i>
</div>
<img class="img-fluid img-responsive rounded product-image" src="${v.files[0].url}" />
</div>
<div class="col-md-6 mt-1">
<h5 class="detailLink">${v.name}</h5>
<div class="ratings-cart d-flex flex-row">
<div class="ratings mr-2">
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
</div>
</div>
</div>
<div class="align-items-center align-content-center col-md-3 border-left mt-1">
<label>
<input class="cartProduct" style="visibility: hidden!important;" th:value="${v.id}"
type="text">
</label>
<div class="d-flex flex-column justify-content-start">
${v.isDiscount ? `<div>
<h4 class="mr-1 product-price discountResult">${v.price - (v.price * v.discount / 100)}.00</h4>
</div>` : `<h4 class="mr-1 product-price">₼ ${v.price}.00</h4>`}
${v.isDiscount ? `<del>
<h4 style="font-size:14px;" class="mr-1 product-price">₼ ${v.price}.00</h4>
</del>` : `<small style="display:none;"></small>`}
</div>
<h6 class="text-success">Baxış sayı:<small class="productCount">${v.count}</small></h6>
<div class="d-flex flex-column mt-4">
<button class="btn btn-sm basket" type="button">Səbətə əlavə et</button>
</div>
</div>
</div>
</div>`
let grid_items = `<div class="col-12 col-sm-6 col-md-12 col-xl-6 dateSort" data-name="${v.name}" data-price="${v.price}">
<div class="single-product-wrapper">
${v.isNew ? `<div class="ribbon text-center" >Yeni<br></div>` : `<small style="display:none !important"></small>`}
${v.isDiscount ? `<div class="discount">- ${v.discount} %</div>` : `<small style="display:none !important"></small>`}
<div class="product-img">
<img alt="" class="product-img-file" src="${v.files[0].url}" />
</div>
<div class="product-description d-flex align-items-center justify-content-between">
<div class="product-meta-data">
<label>
<input class="cartProduct" style="visibility: hidden !important;" value="${v.id}" type="text" />
</label>
<div class="line"></div>
<div class="d-flex flex-column justify-content-start dataPrice">
${v.isDiscount ? `<div>
<p class="product-price discountResult"> ₼ ${v.price - (v.price * v.discount / 100)}.00 </p>
</div>` : ` <p class="product-price">₼ ${v.price}.00 </p>`}
${v.isDiscount ? `<del><h4 style="font-size:14px;" class="mr-1 product-price">₼ ${v.price}.00</h4>
</del>` : `<small style="display:none"></small>`}
</div>
<a href="/detail/${v.id}">
<h6 class="productName">${v.name}</h6>
</a>
<button class="basket" type="button">Səbətə əlavə et</button>
</div>
<div class="ratings-cart text-right">
<div class="ratings">
<i aria-hidden="true" class="fa fa-star"></i>
<i aria-hidden="true" class="fa fa-star"></i>
<i aria-hidden="true" class="fa fa-star"></i>
<i aria-hidden="true" class="fa fa-star"></i>
<i aria-hidden="true" class="fa fa-star"></i>
</div>
<small> Baxış sayı: <small>${v.count}</small> </small>
</div>
</div>
</div>
</div>
`
$("#grid").append(grid_items);
$("#column").append(item_content);
})
});
}
Hi everyone my simple project using thymeleaf and javascript code loading my project my add basket service normal working but sort change sort data returns spring boot backend service and append html code using javascript and jquery click event not working my add basket service
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)
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();
I am adding a Search functionality to my E-commerce Project using Javascript, I have followed a tutorial that explains that when writing the title in the search bar only the items with the same letter appears. In my project, it was working fine for basic HTML but I am trying to make it a little more complex to include a complete card with some details such as price, not just the title.
Here is the model.py
class Item(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(blank=False, upload_to=upload_design_to)
price = models.DecimalField(decimal_places=2, max_digits=100)
discount_price = models.DecimalField(decimal_places=2, max_digits=100, blank=True, null=True)
timestamp = models.DateTimeField(default=timezone.now)
Here is the views.py
class ItemListView(ListView):
model = Item
paginate_by = 12
template_name = "store/product_list.html"
ordering = ['-timestamp']
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["qs_json"] = json.dumps(list(Item.objects.values()),cls=DjangoJSONEncoder)
return context
Here is the scripts.py
<script>
const data = '{{qs_json}}'
const rdata = JSON.parse(data.replace(/"/g, '"'))
console.log(rdata)
const input = document.getElementById('search_here')
console.log(input)
let filteredArr = []
input.addEventListener('keyup', (e)=>{
box.innerHTML = ""
filteredArr = rdata.filter(store=> store['title'].includes(e.target.value))
console.log(filteredArr)
if (filteredArr.length > 0){
filteredArr.map(store=>{
box.innerHTML += `<b>${store['title']}</b><br>`
})
} else {
box.innerHTML = "<b>No results found...</b>"
}
})
</script>
Here is the template.html
<input id="search_here" class="mb-2 form-control" placeholder="Type to search...">
<!--Card-->
<div id="box" class='row card-group'>
{% for item in object_list %}
<div class="col-4 mb-3">
<div class="card h-100">
<a href="{{item.get_absolute_url}}">
<embed src="{{ item.image.url }}" class="card-img-top" alt="..."/>
</a>
<div class="card-body">
<h5 class="card-title">{{ item.title }}</h5>
<p class="card-text">
{% if item.description %}
{{ item.description }}
{% endif %}
</p>
</div>
<div class="card-footer">
<small class="text-muted">{{ item.timestamp }}</small>
</div>
</div>
</div>
{% endfor %}
</div>
<!--Card-->
My Question: How do I replace the simple <b>${store['title']}</b><br> with the below in the scripts with the whole card div with all its information related to it?
If any more information or clarifications required let me know
<div class="col-4 mb-3">
<div class="card h-100">
<a href="{{item.get_absolute_url}}">
<embed src="{{ item.image.url }}" class="card-img-top" alt="..."/>
</a>
<div class="card-body">
<h5 class="card-title">{{ item.title }}</h5>
<p class="card-text">
{% if item.description %}
{{ item.description }}
{% endif %}
</p>
</div>
<div class="card-footer">
<small class="text-muted">{{ item.timestamp }}</small>
</div>
</div>
</div>
from django.db.models import Q
name = request.POST['name']
price = request.POST['price']
Item.objects.filter(Q(title __icontains=name) | Q(price __icontains=price))
Try This
Your template.html page already have all htmls generated using for-loop so you don't need to generate them again .Instead , when user type you can loop through all div and check if card-title div has that input if it has simply show that div or else hide it.
Demo Code :
const input = document.getElementById('search_here')
input.addEventListener('keyup', (e) => {
var inputs = e.target.value.toLowerCase(); //do lowercase
//loop through outer div and hide it
document.querySelectorAll('.outers').forEach(function(el) {
el.style.display = 'none';
});
//loop through outer ->card-title
document.querySelectorAll('.outers .card-title').forEach(function(el) {
//compare
if (el.textContent.toLowerCase().indexOf(inputs) > -1) {
el.closest('.outers').style.display = "block"; //if match show that div
}
})
})
.outers {
border: 1px solid blue;
width: 150px;
height: 150px;
margin-bottom: 5px
}
<input id="search_here" class="mb-2 form-control" placeholder="Type to search...">
<div id="box" class='row card-group'>
<!--just added one extra class-->
<div class="col-4 mb-3 outers">
<div class="card h-100">
<a href="{{item.get_absolute_url}}">
<img src="{{ item.image.url }}" class="card-img-top" alt="..." />
</a>
<div class="card-body">
<h5 class="card-title">Somethings</h5>
<p class="card-text">
some things ...
</p>
</div>
<div class="card-footer">
<small class="text-muted">12:30:00</small>
</div>
</div>
</div>
<div class="col-4 mb-3 outers">
<div class="card h-100">
<a href="{{item.get_absolute_url}}">
<img src="{{ item.image.url }}" class="card-img-top" alt="..." />
</a>
<div class="card-body">
<h5 class="card-title">Abc</h5>
<p class="card-text">
some things ...
</p>
</div>
<div class="card-footer">
<small class="text-muted">12:30:00</small>
</div>
</div>
</div>
<div class="col-4 mb-3 outers">
<div class="card h-100">
<a href="{{item.get_absolute_url}}">
<img src="{{ item.image.url }}" class="card-img-top" alt="..." />
</a>
<div class="card-body">
<h5 class="card-title">def</h5>
<p class="card-text">
some things ...
</p>
</div>
<div class="card-footer">
<small class="text-muted">12:30:00</small>
</div>
</div>
</div>
</div>
I think that you can change the script by following code.
const data = '{{qs_json}}'
const rdata = JSON.parse(data.replace(/"/g, '"'))
console.log(rdata)
const input = document.getElementById('search_here')
console.log(input)
let filteredArr = []
input.addEventListener('keyup', (e) => {
box.innerHTML = ""
filteredArr = rdata.filter(store => store['title'].includes(e.target.value))
console.log(filteredArr)
if (filteredArr.length > 0) {
filteredArr.map(store => {
box.innerHTML += `
<div class="col-4 mb-3">
<div class="card h-100">
<a href="${store['get_absolute_url']}">
<embed src="${store['image']['url']}" class="card-img-top" alt="..."/>
</a>
<div class="card-body">
<h5 class="card-title">${store['title']}</h5>
<p class="card-text">
${store['description'] ?? ''}
</p>
</div>
<div class="card-footer">
<small class="text-muted">${store['timestamp']}</small>
</div>
</div>
</div>`;
})
} else {
box.innerHTML = "<b>No results found...</b>"
}
})
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>