I have a website and there is a shopping cart. I can put stuff in there. There is also an item counter in this basket, but there was one problem. Now I need to find the cost of items added to the cart through the console. But when you try to do this, the console returns NaN.
const cartWrapper = document.querySelector('#check');
window.addEventListener('click', function(event) {
if (event.target.hasAttribute('data-cart')) {
const card = event.target.closest('.dlg-modal')
//Собираем данные
const productInfo = {
id: card.dataset.id,
imgSrc: card.querySelector('.gui__pizzablock').getAttribute('src'),
title: card.querySelector('.productTitle').innerText,
price: card.querySelector('.priceTitle').innerText,
description: card.querySelector('.gui__description').innerText,
counter: card.querySelector('[data-counter]').innerText,
};
const itemInCart = cartWrapper.querySelector(`[data-id="${productInfo.id}"]`);
if (itemInCart) {
alert('present')
const counterElement = itemInCart.querySelector('[data-counter]')
counterElement.innerHTML = parseInt(counterElement.innerHTML) + 1;
alert('wow')
} else {
const cartItemHTML = `<div class="item__block">
<div data-id="${productInfo.id}">
<img class="img__rubb" src="${productInfo.imgSrc}">
<p style="margin: -73px 100px">${productInfo.title}</p>
<p class="description__rubb" style="margin: 81px 100px">${productInfo.description}</p>
<hr class="hr__rubb">
<p style="margin: 70px 15px"><span class="amount__price">${productInfo.price}</span>руб.</p>
<!-- <div class="items__control" data-action="minus">-</div>-->
<div class="counter__rubb">
<div class="counter__rubb_text">
<a class="minus__plus__rubb" style=" -moz-user-select: none; display: inline-flex; font-size: 21px" data-action="minus">-</a>
<div style="display: inline-flex; cursor: default; -moz-user-select: none; " data-counter>${productInfo.counter}</div>
<a class="minus__plus__rubb" style=" -moz-user-select: none; display: inline-flex; font-size: 21px;" data-action="plus">+</a>
</div>
</div>
<div class="buy__rubb">
<div class="buy__rbb__boxes">
<p style="margin: 1% 3%; display: inline-flex">1 товар</p>
<p style="margin: 1% 30.5%; display: inline-flex">0 руб.</p>
<hr class="hr__rubba">
<p style="margin: 1% 3%; font-size: 16px; display: inline-flex">Сумма заказа</p>
<p style="margin: 1% 22.5%; display: inline-flex">0 руб.</p>
<div class="btn__rubb__podval">
К оформлению заказа
</div>
</div>
</div>
</div>
</div>`;
cartWrapper.insertAdjacentHTML('beforeend', cartItemHTML)
}
offCartStatus();
}
})
function calcPrice() {
const cartItems = document.querySelectorAll('.item__block')
let totalPrice;
cartItems.forEach(function(item) {
const amount = item.querySelector('[data-counter]');
const price = item.querySelector('.amount__price');
const currentPrice = parseInt(amount.innerHTML) * parseFloat(price.innerHTML);
totalPrice = totalPrice + currentPrice
})
console.log(totalPrice)
}
<div data-id="999" id="check" class="dlg-modal dlg-modal-fade" style="background: #f3f3f3; width: 790px; height: 100%; left: 100%">
<div class="item__block__container">
<div data-cart-empty class="emptyContainer">
<div class="emptyBlock">
<img class="emptyBlock" src="notfinedCart.svg" style="">
<h2 class="emptyBlock">Empty!</h2>
<p class="emptyBlock"><br>Oh!!!<br>Cart empty:(<br>Select something</p>
</div>
</div>
Note: I open cart with popup
If you do not put everything in a variable, then there are no errors.
You need to set the initial value of totalPrice so that you aren't trying to add with an undefined value.
let totalPrice = 0;
function calcPrice() {
const cartItems = document.querySelectorAll('.item__block')
let totalPrice = 0;
cartItems.forEach(function(item) {
const amount = item.querySelector('[data-counter]');
const price = item.querySelector('.amount__price');
const currentPrice = parseInt(amount.innerHTML) * parseFloat(price.innerHTML);
totalPrice += currentPrice;
})
console.log(totalPrice)
}
calcPrice();
<div class="item__block">
<span class="amount__price">100</span>
<div data-counter>5</div>
</div>
<div class="item__block">
<span class="amount__price">10</span>
<div data-counter>3</div>
</div>
Related
I'm currently doing a Javascript challenge on Scrimba that requires you to recreate a Basketball scoreboard. I've gotten the design down but i'm having trouble with increment buttons to add either 1,2, or 3 points to either teams score. Each team's scoreboard has 3 buttons underneath that can add 1,2, or 3 points. Originally i was just going to write 6 functions, 3 for each team that would function based on which increment button you select for which team. I figured i could probably just write the three separate increment functions and find a way to pass in an argument to direct which team was getting the points. This worked except that the functions all target a 'points' variable so they end up incrementing off of each other when you add points to the opposite team.
Here is the HTML
<div class="container">
<div class="column">
<h3 class="title">HOME</h3>
<h2 class="score" id="home-score">0</h2>
<div>
<button class="increment-btn" onclick="add1Point('home-score')">+1</button>
<button class="increment-btn" onclick="add2Points('home-score')">+2</button>
<button class="increment-btn" onclick="add3Points('home-score')">+3</button>
</div>
</div>
<div class="column">
<h3 class="title">GUEST</h3>
<h2 class="score" id="guest-score">0</h2>
<div>
<button class="increment-btn" onclick="add1Point('guest-score')">+1</button>
<button class="increment-btn" onclick="add2Points('guest-score')">+2</button>
<button class="increment-btn" onclick="add3Points('guest-score')">+3</button>
</div>
And here is the JS
let points = 0
function add1Point(idValue){
let teamId = document.getElementById(idValue)
points += 1
teamId.textContent = points
}
function add2Points(idValue){
let teamId = document.getElementById(idValue)
points += 2
teamId.textContent = points
}
function add3Points(idValue){
let teamId = document.getElementById(idValue)
points += 3
teamId.textContent = points
}
I know i need to find a way to have two separate point variables for each team but I'm not sure how i can point the individual functions to a specific variable base on which teams button is selected. Not without creating a whole new function specifically for that variable. If possible i would like a solution with the most basic vanilla JS possible, I know there are more complex ways to solve this but im only so far with my learning. Thanks in advance!
use closures
function score(points = 0) {
return function(value) {
points += value;
return points;
}
}
const $homeScore = document.getElementById("home-score");
const $guestScore = document.getElementById("guest-score");
const homeScore = score();
const guestScore = score();
const $homeButtons = document.querySelectorAll("#home-buttons button");
const $guestButtons = document.querySelectorAll("#guest-buttons button");
for(let i = 0; i < $homeButtons.length; i++) {
$homeButtons[i].addEventListener("click", () => {
$homeScore.innerText = homeScore(i + 1);
});
}
for(let i = 0; i < $guestButtons.length; i++) {
$guestButtons[i].addEventListener("click", () => {
$guestScore.innerText = guestScore(i + 1);
});
}
.container {
display: flex;
justify-content: space-between;
background-color: black;
color: white;
font-family: Courier, Courier New, monospace;
padding: 2px 5px;
}
.container .column .score {
border: 1px solid white;
border-radius: 2px;
padding: 2px 5px;
text-align: center;
}
<div class="container">
<div class="column">
<h3 class="title">HOME</h3>
<h2 class="score" id="home-score">0</h2>
<div id="home-buttons">
<button class="increment-btn">+1</button>
<button class="increment-btn">+2</button>
<button class="increment-btn">+3</button>
</div>
</div>
<div class="column">
<h3 class="title">GUEST</h3>
<h2 class="score" id="guest-score">0</h2>
<div id="guest-buttons">
<button class="increment-btn">+1</button>
<button class="increment-btn">+2</button>
<button class="increment-btn">+3</button>
</div>
</div>
</div>
As far as I understand, you'd probably need 2 individual variables to hold the value for each team, here's an example for add 1 point
let guest = 0;
let home = 0;
function add1Point(idValue){
let teamId = document.getElementById(idValue)
if (idValue === 'guest-score') { //Assume your element has name to tell them apart
guest += 1;
teamId.textContent = guest;
} else {
home += 1;
teamId.textContent = home;
}
}
In the other hand, you should make your method reusable and flexible a little like this
function addPoints(idValue, point) {
let teamId = document.getElementById(idValue)
if (idValue === 'guest-score') { //Assume your element has name to tell them apart
guest += point;
teamId.textContent = guest;
} else {
home += point;
teamId.textContent = home;
}
}
then your code will look cleaner
<button class="increment-btn" onclick="addPoints('guest-score', 1)">+1</button>
<button class="increment-btn" onclick="addPoints('guest-score', 2)">+2</button>
<button class="increment-btn" onclick="addPoints('guest-score', 3)">+3</button>
You can simplify it to one function only:
var homeScore = 0;
var guestScore = 0;
var homeScoreEl = document.getElementById('home-score');
var guestScoreEl = document.getElementById('guest-score');
function addPoints(isHome, points = 1) {
window[isHome ? 'homeScore' : 'guestScore'] += points
window[isHome ? 'homeScoreEl' : 'guestScoreEl'].textContent = window[isHome ? 'homeScore' : 'guestScore']
}
.container {
display: flex;
justify-content: space-between;
background-color: black;
color: white;
font-family: Courier, Courier New, monospace;
padding: 2px 5px;
}
.container .column .score {
border: 1px solid white;
border-radius: 2px;
padding: 2px 5px;
text-align: center;
}
<div class="container">
<div class="column">
<h3 class="title">HOME</h3>
<h2 class="score" id="home-score">0</h2>
<div>
<button class="increment-btn" onclick="addPoints(true)">+1</button>
<button class="increment-btn" onclick="addPoints(true, 2)">+2</button>
<button class="increment-btn" onclick="addPoints(true, 3)">+3</button>
</div>
</div>
<div class="column">
<h3 class="title">GUEST</h3>
<h2 class="score" id="guest-score">0</h2>
<div>
<button class="increment-btn" onclick="addPoints(false)">+1</button>
<button class="increment-btn" onclick="addPoints(false, 2)">+2</button>
<button class="increment-btn" onclick="addPoints(false, 3)">+3</button>
</div>
So I have 6 cards on my html. Each one on click need to pop up a modal window (this modal window is the card with more informations, so each modal window is corresponding to one card).
I dont know how to do that. After a day searching on the web I'm here to ask your help.
I have tried to make the html animal_card, and my modal appart. Then all the content will change with php.
And the Javascript need to change the modal window css property to absolute on click.
Someone know how to do that with Javascript ?
HTML :
<div class="animal_card">
<div class="card_title">
<h3>title</h3>
</div>
<div class="card_image">
<img src="image.img" alt="">
</div>
<div class="card_text">
<div class="card_info">
<div class="card_info_age">
<h4>Age</h4>
<p>14</p>
</div>
<div class="card_info_gender">
<h4>Gender :</h4>
<p>Female</p>
</div>
</div>
<h4>Who am I</h4>
<p>Description Text</p>
</div>
</div>
<div class="bg-modal">
<div class="modal-content">
<div class="modal-animal">
<h1>Animal Name</h1>
<button class="close" onclick="closeModal()">×</button>
<div><img src="img/greciaprofile.jpg" alt=""></div>
<div class="animal-informations">
<div class="left">
<label for="">Age</label>
<p>14</p>
<label for="">Sexe</label>
<p>Female</p>
</div>
<div class="right">
<label for="">Description</label>
<p>
Text
</p>
</div>
</div>
<div>
<button class="main">Adopt</button>
<button class="secondary">Support</button>
</div>
</div>
</div>
</div>
CSS :
.bg-modal {
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.7);
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
}
.modal-content {
position: absolute;
margin-top: 5rem;
width: 75vw;
background-color: $white;
border-radius: 15px;
}
Javascript :
const cards = document.querySelectorAll('.animal_card');
const modal = document.getElementsByClassName('bg-modal');
const onCardClick = async (e) => {
const card = e.currentTarget;
modal.style.position = 'absolute';
}
cards.forEach(card => card.addEventListener('click', onCardClick));
function closeModal() {
modal[0].style.position = 'none';
}
const cards = document.querySelectorAll('.animal_card');
const modal = document.getElementsByClassName('bg-modal');
const getKeyMap = (modal) => {
if (modal) {
let i;
let keyMap = {};
for (i = 0; i < modal.length; i++) {
const item = modal[i];
const key = item.getAttribute('key');
keyMap[key] = item;
}
return keyMap;
}
return null;
};
const modalMap = getKeyMap(modal);
const onCardClick = async (e) => {
const card = e.currentTarget && e.currentTarget.getAttribute('key') || null;
const selectedModal = modalMap[card] || null;
if (selectedModal) {
selectedModal.style.position = 'absolute';
}
}
cards.forEach(card => card.addEventListener('click', onCardClick));
.bg-modal {
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.7);
/* position: absolute; */
top: 0;
left: 0;
display: flex;
justify-content: center;
}
.modal-content {
position: absolute;
margin-top: 5rem;
width: 75vw;
background-color: $white;
border-radius: 15px;
}
<div key="5" class="animal_card">
<div class="card_title">
<h3>title</h3>
</div>
<div class="card_image">
<img src="image.img" alt="">
</div>
<div class="card_text">
<div class="card_info">
<div class="card_info_age">
<h4>Age</h4>
<p>14</p>
</div>
<div class="card_info_gender">
<h4>Gender :</h4>
<p>Female</p>
</div>
</div>
<h4>Who am I</h4>
<p>Description Text</p>
</div>
</div>
<div class="bg-modal" key="5">
<div class="modal-content">
<div class="modal-animal">
<h1>Animal Name</h1>
<button class="close">×</button>
<div><img src="img/greciaprofile.jpg" alt=""></div>
<div class="animal-informations">
<div class="left">
<label for="">Age</label>
<p>14</p>
<label for="">Sexe</label>
<p>Female</p>
</div>
<div class="right">
<label for="">Description</label>
<p>
Text
</p>
</div>
</div>
<div>
<button class="main">Adopt</button>
<button class="secondary">Support</button>
</div>
</div>
</div>
</div>
So the direct answer using your example is modal on the onCardClick is returning a collection, not a single element. So selecting the first one modal[0] will fix the position update. I attached an example.
If you are going to show different modals based on the card you click on, you generally need to have a method to track them. Really depends on how you want to do that, based on ids, or index position or so on. Anyways, let me know if this helps.
This is supposed to be a simple pure html, css and javascript order form with four fields for four different product. Users can adjust quantity and calculate totals for each product and for the final total. Everything is working except the final calculation and I have no idea why because it uses the same methods I used to calculate the individual totals.
<!DOCTYPE html>
<html>
<head>
<title>Order Form</title>
<style>
#productOnePrice, #productOneName, #productOneQuantity, #productOneTotal,
#productTwoPrice, #productTwoName, #productTwoQuantity, #productTwoTotal,
#productThreePrice, #productThreeName, #productThreeQuantity,
#productThreeTotal, #productFourPrice, #productFourName,
#productFourQuantity, #productFourTotal, #orderTotalButton, #orderTotal{
height:20px;
width:238px;
float:left;
margin: 5px 5px 5px 5px;
padding: 1px 1px 1px 1px;
outline: 2px solid black;
text-align: center;
}
.container {
height:auto;
width:1000px;
float:left;
padding: 5px 5px 5px 5px;
outline: 2px solid black;
text-align: center;
}
.quantityOne{
text-align: right;
}
</style>
</head>
<body>
<div class="container">
<!-- Product One -->
<div>
<p id="productOneName"></p>
</div>
<div>
<p id="productOnePrice"></p>
</div>
<div>
<p id="productOneQuantity">
<input id="quantityOne" type="number">
<button onclick="productOneTotal()">Add</button>
</p>
</div>
<div>
<p id="productOneTotal"></p>
</div>
<!-- Product Two -->
<div>
<p id="productTwoName"></p>
</div>
<div>
<p id="productTwoPrice"></p>
</div>
<div>
<p id="productTwoQuantity">
<input id="quantityTwo" type="number">
<button onclick="productTwoTotal()">Add</button>
</p>
</div>
<div>
<p id="productTwoTotal"></p>
</div>
<!-- Product Three -->
<div>
<p id="productThreeName"></p>
</div>
<div>
<p id="productThreePrice"></p>
</div>
<div>
<p id="productThreeQuantity">
<input id="quantityThree" type="number">
<button onclick="productThreeTotal()">Add</button>
</p>
</div>
<div>
<p id="productThreeTotal"></p>
</div>
<!-- Product Four -->
<div>
<p id="productFourName"></p>
</div>
<div>
<p id="productFourPrice"></p>
</div>
<div>
<p id="productFourQuantity">
<input id="quantityFour" type="number">
<button onclick="productFourTotal()">Add</button>
</p>
</div>
<div>
<p id="productFourTotal"></p>
</div>
<!-- Order Total -->
<div>
<p id="orderTotalButton">
<button onclick="orderTotal()">Add</button>
</p>
</div>
<div>
<p id="orderTotal"></p>
</div>
<script>
/* Product One Total Function */
document.getElementById("productOneName").innerText = "mp3";
document.getElementById("productOnePrice").innerHTML = 1;
function productOneTotal(price, quantity){
price = 1;
quantity = document.getElementById("quantityOne").value;
document.getElementById("productOneTotal").innerHTML =
parseInt(price) * parseInt(quantity);
}
/* Product Two Total Function */
document.getElementById("productTwoName").innerText = "Cassette";
document.getElementById("productTwoPrice").innerHTML = 1;
function productTwoTotal(price, quantity){
price = 1;
quantity = document.getElementById("quantityTwo").value;
document.getElementById("productTwoTotal").innerHTML =
parseInt(price) * parseInt(quantity);
}
/* Product Three Total Function */
document.getElementById("productThreeName").innerText = "Vinyl LP";
document.getElementById("productThreePrice").innerHTML = 1;
function productThreeTotal(price, quantity){
price = 1;
quantity = document.getElementById("quantityThree").value;
document.getElementById("productThreeTotal").innerHTML =
parseInt(price) * parseInt(quantity);
}
/* Product Four Total Function */
document.getElementById("productFourName").innerText = "T-Shirt";
document.getElementById("productFourPrice").innerHTML = 1;
function productFourTotal(price, quantity){
price = 1;
quantity = document.getElementById("quantityFour").value;
document.getElementById("productFourTotal").innerHTML =
parseInt(price) * parseInt(quantity);
}
/* Order Total Function */
function orderTotal(productOneTotal, productTwoTotal,
productThreeTotal, productFourTotal){
productOneTotal =
document.getElementById("productOneTotal").value;
productTwoTotal =
document.getElementById("productTwoTotal").value;
productThreeTotal =
document.getElementById("productThreeTotal").value;
productFourTotal =
document.getElementById("productFourTotal").value;
document.getElementById("orderTotal").innerHTML =
parseInt(productOneTotal) + parseInt(productTwoTotal) +
parseInt(productThreeTotal) + parseInt(productFourTotal);
}
</script>
</div>
</body>
</html>
You need to target your total elements with .innerHTML instead of value.
productOneTotal = document.getElementById("productOneTotal").innerHTML;
That'll remove the NaN error you were getting. The elements don't have a value so attempts to retrieve .value were returning undefined.
NOTE: Textbox, and other elements .value is used. and div elements gain value we have use .innerHTML
<!DOCTYPE html>
<html>
<head>
<title>Order Form</title>
<style>
#productOnePrice, #productOneName, #productOneQuantity, #productOneTotal,
#productTwoPrice, #productTwoName, #productTwoQuantity, #productTwoTotal,
#productThreePrice, #productThreeName, #productThreeQuantity,
#productThreeTotal, #productFourPrice, #productFourName,
#productFourQuantity, #productFourTotal, #orderTotalButton, #orderTotal{
height:20px;
width:238px;
float:left;
margin: 5px 5px 5px 5px;
padding: 1px 1px 1px 1px;
outline: 2px solid black;
text-align: center;
}
.container {
height:auto;
width:1000px;
float:left;
padding: 5px 5px 5px 5px;
outline: 2px solid black;
text-align: center;
}
.quantityOne{
text-align: right;
}
</style>
</head>
<body>
<div class="container">
<!-- Product One -->
<div>
<p id="productOneName"></p>
</div>
<div>
<p id="productOnePrice"></p>
</div>
<div>
<p id="productOneQuantity">
<input id="quantityOne" type="number">
<button onclick="productOneTotal()">Add</button>
</p>
</div>
<div>
<p id="productOneTotal"></p>
</div>
<!-- Product Two -->
<div>
<p id="productTwoName"></p>
</div>
<div>
<p id="productTwoPrice"></p>
</div>
<div>
<p id="productTwoQuantity">
<input id="quantityTwo" type="number">
<button onclick="productTwoTotal()">Add</button>
</p>
</div>
<div>
<p id="productTwoTotal"></p>
</div>
<!-- Product Three -->
<div>
<p id="productThreeName"></p>
</div>
<div>
<p id="productThreePrice"></p>
</div>
<div>
<p id="productThreeQuantity">
<input id="quantityThree" type="number">
<button onclick="productThreeTotal()">Add</button>
</p>
</div>
<div>
<p id="productThreeTotal"></p>
</div>
<!-- Product Four -->
<div>
<p id="productFourName"></p>
</div>
<div>
<p id="productFourPrice"></p>
</div>
<div>
<p id="productFourQuantity">
<input id="quantityFour" type="number">
<button onclick="productFourTotal()">Add</button>
</p>
</div>
<div>
<p id="productFourTotal"></p>
</div>
<!-- Order Total -->
<div>
<p id="orderTotalButton">
<button onclick="orderTotal()">Add</button>
</p>
</div>
<div>
<p id="orderTotal"></p>
</div>
<script>
/* Product One Total Function */
document.getElementById("productOneName").innerText = "mp3";
document.getElementById("productOnePrice").innerHTML = 1;
function productOneTotal(){
price = 1;
quantity = document.getElementById("quantityOne").value;
if(quantity=="") {
quantity = 0;
}
document.getElementById("productOneTotal").innerHTML =
parseInt(price) * parseInt(quantity);
}
/* Product Two Total Function */
document.getElementById("productTwoName").innerText = "Cassette";
document.getElementById("productTwoPrice").innerHTML = 1;
function productTwoTotal(){
price = 1;
quantity = document.getElementById("quantityTwo").value;
if(quantity=="") {
quantity = 0;
}
document.getElementById("productTwoTotal").innerHTML =
parseInt(price) * parseInt(quantity);
}
/* Product Three Total Function */
document.getElementById("productThreeName").innerText = "Vinyl LP";
document.getElementById("productThreePrice").innerHTML = 1;
function productThreeTotal(){
price = 1;
quantity = document.getElementById("quantityThree").value;
if(quantity=="") {
quantity = 0;
}
document.getElementById("productThreeTotal").innerHTML =
parseInt(price) * parseInt(quantity);
}
/* Product Four Total Function */
document.getElementById("productFourName").innerText = "T-Shirt";
document.getElementById("productFourPrice").innerHTML = 1;
function productFourTotal(){
price = 1;
quantity = document.getElementById("quantityFour").value;
if(quantity=="") {
quantity = 0;
}
document.getElementById("productFourTotal").innerHTML =
parseInt(price) * parseInt(quantity);
}
/* Order Total Function */
function orderTotal(productOneTotal, productTwoTotal,
productThreeTotal, productFourTotal){
productOneTotal =
document.getElementById("productOneTotal").innerHTML;
productTwoTotal =
document.getElementById("productTwoTotal").innerHTML;
productThreeTotal =
document.getElementById("productThreeTotal").innerHTML;
productFourTotal =
document.getElementById("productFourTotal").innerHTML;
if(productOneTotal=="") {
productOneTotal=0;
}
if(productTwoTotal=="") {
productTwoTotal=0;
}
if(productThreeTotal=="") {
productThreeTotal=0;
}
if(productFourTotal=="") {
productFourTotal=0;
}
document.getElementById("orderTotal").innerHTML =
parseInt(productOneTotal) + parseInt(productTwoTotal) +
parseInt(productThreeTotal) + parseInt(productFourTotal);
}
</script>
</div>
</body>
</html>
I have dynamically added divs with nested divs to the dom. These have data-attributes:
data-name-nr, data-model, data-price.
What I want is to take the highest value of "data-price" to an array from each of all "data-div". In my example there is two nested divs inside the last
More explanation: In my example I have three div with class "frame" = I need an array with three values. In reality there night be whatever between 1 and 10 or even more.
So the outcome of my example would be
let array = [100,150,200]
or
let object = {1:100,2:150,3:200} //from the name-nr
So far I only managed to map the data-items
I tried with map.get and other, they all gave me errors and I don't know which direction I should go. Please can you help?
Example:
HTML
<div class="flex">
<div class="frame" data-name-nr="1">
<div class="border" data-name-nr="1" data-price="100" data-div="1/1"></div>
</div>
<div class="frame" data-name-nr="2">
<div class="border" data-name-nr="2" data-price="150" data-div="1/1"></div>
</div>
<div class="frame" data-name-nr="3">
<div class="border fifty" data-name-nr="3" data-price="100" data-div="1/2"></div>
<div class="border fifty" data-name-nr="3" data-price="200" data-div="2/2"></div>
</div>
</div>
JS
function functionName() {
jQuery( ".frame .box" ).map(function() {
const key = ['name','model','price']
let values = [[jQuery(this).data("name-nr"),( jQuery(this).data('div')),( jQuery(this).data('price'))]]
let result = values.map(row =>
row.reduce((acc, cur, i) =>
(acc[key[i]] = cur, acc), {}))
console.log(result[0])
})
}
$(document).on('click', '.click', functionName)
Console
Object { name: 1, model: "1/1", price: 100 }
Object { name: 2, model: "1/1", price: 150 }
Object { name: 3, model: "1/2", price: 100 }
Object { name: 3, model: "2/2", price: 200 }
https://jsfiddle.net/mik_a/a6jt7kb0/
Create a hash table by reducing to a hash with unique names with the largest price and then take them out to the array as required.
See demo below:
function functionName() {
let hash = jQuery(".frame .box").map(function() {
return {
name: jQuery(this).data("name-nr"),
model: jQuery(this).data('div'),
price: jQuery(this).data('price')
};
}).get().reduce(function(p,c){
if((p[c.name] && p[c.name].price < c.price) || !p[c.name])
p[c.name] = c
return p;
},Object.create(null));
let result = Object.keys(hash).map(function(e) {
return hash[e];
});
console.log(result);
}
$(document).on('click', '.click', functionName)
.flex {
display: flex;
align-items: center;
justify-content: center;
width: 400px;
height: 300px;
}
.frame {
outline: 1px solid red;
flex: 1;
display: flex;
flex-direction: column;
height: 100%;
}
.box {
border-top: 1px solid green;
}
.fifty {
height: 50%;
}
button {
width: 100px;
height: 35px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flex">
<div class="frame" data-name-nr="1">
<div class="box" data-name-nr="1" data-price="100" data-div="1/1"></div>
</div>
<div class="frame" data-name-nr="2">
<div class="box" data-name-nr="2" data-price="150" data-div="1/1"></div>
</div>
<div class="frame" data-name-nr="3">
<div class="box fifty" data-name-nr="3" data-price="100" data-div="1/2"></div>
<div class="box fifty" data-name-nr="3" data-price="200" data-div="2/2"></div>
</div>
</div>
<button class="click" value="CLICK">
click
</button>
and the ES6 version:
function functionName() {
let hash = jQuery(".frame .box").map(function() {
return {
name: jQuery(this).data("name-nr"),
model: jQuery(this).data('div'),
price: jQuery(this).data('price')
};
}).get().reduce((p, c) => {
if ((p[c.name] && p[c.name].price < c.price) || !p[c.name])
p[c.name] = c;
return p;
}, Object.create(null));
let result = Object.keys(hash).map(e => hash[e]);
let sum = Object.keys(hash).map(e => hash[e].price).reduce((p,c) => p + c, 0);
console.log(result, sum);
}
$(document).on('click', '.click', functionName)
.flex{display:flex;align-items:center;justify-content:center;width:400px;height:300px}.frame{outline:1px solid red;flex:1;display:flex;flex-direction:column;height:100%}.box{border-top:1px solid green}.fifty{height:50%}button{width:100px;height:35px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flex">
<div class="frame" data-name-nr="1">
<div class="box" data-name-nr="1" data-price="100" data-div="1/1"></div>
</div>
<div class="frame" data-name-nr="2">
<div class="box" data-name-nr="2" data-price="150" data-div="1/1"></div>
</div>
<div class="frame" data-name-nr="3">
<div class="box fifty" data-name-nr="3" data-price="100" data-div="1/2"></div>
<div class="box fifty" data-name-nr="3" data-price="200" data-div="2/2"></div>
</div>
</div>
<button class="click" value="CLICK">
click
</button>
You could select the frame and then reduce on the inside boxes:
$('.frame').map(function() {
const biggerBox = $(this).find('.box').toArray().reduce((bigger, current) =>
$(bigger).data('price') > $(current).data('price') ? bigger : current)
const data = $(biggerBox).data()
console.log({ name: data.nameNr, price: data.price, div: data.div })
})
using a fork from your fiddle: https://jsfiddle.net/zmq5jdh5/
recently I have wanted to turn a number into a star rating and I stumbled upon this post here: https://stackoverflow.com/a/1987545/1871869 which is exactly what I wanted to do. I have followed this explanation but I can't seem to get it to work on my local environment, and I was wondering if someone could help me out. Here is my attempt:
$.fn.stars = function() {
return $(this).each(function() {
// Get the value
var val = parseFloat($(this).html());
// Make sure that the value is in 0 - 5 range, multiply to get width
var size = Math.max(0, (Math.min(5, val))) * 16;
// Create stars holder
var $span = $('<span />').width(size);
// Replace the numerical value with stars
$(this).html($span);
});
}
$(function() {
console.log("Calling stars()");
$('.results-contents span.stars').stars();
});
.results {
font-size: 0;
padding-bottom: 16px;
}
.results-content {
font-size: 13px;
display: inline-block;
margin-left: 20px;
vertical-align: top;
}
.results .results-content span.stars span.stars span {
background: url('/resources/graphics/stars-icons.png') 0 -36px repeat-x;
width: 175px;
height: 80px;
}
.results .results-content span.stars {
max-width: 80px;
background-position: 0 0;
}
<script type="text/template" id="results-template">
<div class="results">
<div class="results-content">
<span class="stars">4.0</span>
</div>
</div>
</script>
Image of stars:
What I wanted to do was to simply have the empty stars show, and then based on the rating, show the orange stars on top of the empty stars so that I can show full and half star ratings. However, all I get is a number to show up. My console.log above seems to be called but it seems like the actual rendering of the image and calculation of the star rating is not working. Any help would be appreciated. Thanks!
You had multiple issues from CSS styles being wrong to your selector being wrong. Below is not perfect, but it is rendering.
$.fn.stars = function() {
return this.each(function() {
// Get the value
var val = parseFloat($(this).html());
// Make sure that the value is in 0 - 5 range, multiply to get width
var size = Math.max(0, (Math.min(5, val))) * 36.5;
// Create stars holder
var $span = $('<span> </span>').width(size);
// Replace the numerical value with stars
$(this).empty().append($span);
});
}
$(function() {
console.log("Calling stars()");
$('.results-content span.stars').stars();
});
.results {
font-size: 0;
padding-bottom: 16px;
}
.results-content {
font-size: 13px;
display: inline-block;
margin-left: 20px;
vertical-align: top;
background: url('https://i.stack.imgur.com/rwkqF.png') 0 0 repeat-x;
width: 185px;
height: 35px;
}
.results .results-content span.stars span {
background: url('https://i.stack.imgur.com/rwkqF.png') 0 -36px repeat-x;
display: inline-block;
height: 35px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="results">
<div class="results-content">
<span class="stars">0.0</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">0.5</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">1.0</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">1.5</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">2.0</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">2.0</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">2.5</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">3.0</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">3.5</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">4.0</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">4.5</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">5.0</span>
</div>
</div>