How an I Put a sum in the localstorage? - javascript

I want to put the sum in my localStorage thanks to a function because, I have to work with the creation of function. When I put the total of my basket in my local storage, the nav changes number. So, when refreshing the page, the total is counted as one more article and I have an error on the html tag "nan".Can you explain to me what is wrong with my code ?
let totalityPrice = document.querySelector('.subtotal');
let products = [];
let Total = 0;
function displayProduct() {
if (localStorage.length > 0) {
for (let key in localStorage) {
let product = JSON.parse(localStorage.getItem(key));
document.querySelector('.cart span').textContent = localStorage.length;
if (product) {
products.push(key);
cartTablebody.innerHTML += `
<tr>
<td>${product.title}</td>
<td>${product.price / 100}</td> //price=API data//
</tr>
`;
Total += product.price / 100;
}
}
}
}
displayProduct();
function calculatePrice() {
totalityPrice.innerText = Total;
console.log(Total);
//localstoragesetItem//
}
calculatePrice();

It sounds like there's something in localStorage that isn't a cart item. Check that each item has all the required properties before processing it.
And instead of using localStoage.length as the product count in .cart span, use products.length.
let totalityPrice = document.querySelector('.subtotal');
let products = [];
let Total = 0;
function displayProduct() {
if (localStorage.length > 0) {
for (let key in localStorage) {
let product = JSON.parse(localStorage.getItem(key));
if (product && "title" in product && "price" in product) {
products.push(key);
cartTablebody.innerHTML += `
<tr>
<td>${product.title}</td>
<td>${product.price / 100}</td> //price=API data//
</tr>
`;
Total += product.price / 100;
}
}
}
}
displayProduct();
function calculatePrice() {
totalityPrice.innerText = Total;
console.log(Total);
document.querySelector('.cart span').textContent = products.length;;
}
calculatePrice();

Related

how to add input value to counter value?

I'm trying to have a counter that can respond to input values and add it to displayed count but continue to count by 1. The count starts at 0. I have the counter working with buttons, but not with the added input.
let decreaseBtn = document.getElementById("buttonDecrease");
let increaseBtn = document.getElementById("buttonIncrease");
let counter = document.getElementById("counter");
let inputValue = document.getElementById("quantity").inputValue
let count = 0;
decreaseBtn.addEventListener("click", () => {
count--;
counter.innerHTML = count;
counterStyle();
});
increaseBtn.addEventListener("click", () => {
count++;
counter.innerHTML = count;
counterStyle();
});
function counterStyle() {
if (count < 0) {
counter.classList.add("negative");
} else if (count > 0) {
counter.classList.add("positive");
} else {
counter.classList.remove("negative");
counter.classList.remove("positive");
}
}
function addInput() {
console.log(inputValue)
}
addInput();
<h1 id="counter">0</h1>
<div id="button__wrapper">
<button id="buttonDecrease">-</button>
<input type="text" id="quantity" value="1">
<button id="buttonIncrease">+</button>
</div>
Yuo need to get the value of the input in your event listener functions, not when the script starts. Then use that instead of just incrementing and decrementing.
The property to get the value of an input is .value, not .inputValue.
let decreaseBtn = document.getElementById("buttonDecrease");
let increaseBtn = document.getElementById("buttonIncrease");
let counter = document.getElementById("counter");
let quantity = document.getElementById("quantity");
let count = 0;
decreaseBtn.addEventListener("click", () => {
count -= addInput();
counter.innerHTML = count;
counterStyle();
});
increaseBtn.addEventListener("click", () => {
count += addInput();
counter.innerHTML = count;
counterStyle();
});
function counterStyle() {
if (count < 0) {
counter.classList.add("negative");
counter.classList.remove("positive");
} else if (count > 0) {
counter.classList.add("positive");
counter.classList.remove("negative");
} else {
counter.classList.remove("negative");
counter.classList.remove("positive");
}
}
function addInput() {
return parseInt(quantity.value);
}
.positive {
background-color: green;
}
.negative {
background-color: red;
}
<h1 id="counter">0</h1>
<div id="button__wrapper">
<button id="buttonDecrease">-</button>
<input type="text" id="quantity" value="1">
<button id="buttonIncrease">+</button>
</div>
You have increment and decrement operators when you handle the click event. This is why it is always just adding or subtracting by 1, and not by the value of the input. You should be adding the value of the input element, after using parseInt() to make it into an add-able integer.
Your code that I'm changing:
count--;
What I'm changing it to...
count -= parseInt(document.getElementById('quantity').value, 10);
And I'm doing the same for count++.
In addition, it seems your counterStyles() function isn't removing classes appropriately, and sometimes you'll have a red background with positive integers. I fixed this up by adding the needed removeClass() calls here.
The rest of the code is the same...
let decreaseBtn = document.getElementById("buttonDecrease");
let increaseBtn = document.getElementById("buttonIncrease");
let counter = document.getElementById("counter");
let inputValue = document.getElementById("quantity").inputValue
let count = 0;
decreaseBtn.addEventListener("click", () => {
count -= parseInt(document.getElementById('quantity').value, 10);
counter.innerHTML = count;
counterStyle();
});
increaseBtn.addEventListener("click", () => {
count += parseInt(document.getElementById('quantity').value, 10);
counter.innerHTML = count;
counterStyle();
});
function counterStyle() {
if (count < 0) {
counter.classList.add("negative");
counter.classList.remove("positive");
} else if (count > 0) {
counter.classList.add("positive");
counter.classList.remove("negative");
} else {
counter.classList.remove("negative");
counter.classList.remove("positive");
}
}
function addInput() {
console.log(inputValue)
}
addInput();
.positive {
background-color: green;
}
.negative {
background-color: red;
}
<h1 id="counter">0</h1>
<div id="button__wrapper">
<button id="buttonDecrease">-</button>
<input type="text" id="quantity" value="1">
<button id="buttonIncrease">+</button>
</div>

Removing the shipping price, if the amount has reached a certain value

So I have a working shopping cart page, but I do not know how to remove the shipping value, once a user has reached a total, for example, of 50 or higher. In the previous version this was already implemented, so I tried to compare and figure out how to implement this in the new page, but am not skilled enough in JavaScript. This is the JavaScript I am using right now.
$(document).ready(function() {
var taxRate = 0.05;
var shippingRate = 5.00;
var fadeTime = 300;
$('.product-quantity input').change( function() {
updateQuantity(this);
});
$('.product-removal button').click( function() {
removeItem(this);
});
function recalculateCart()
{
var subtotal = 0;
$('.product').each(function () {
subtotal += parseFloat($(this).children('.product-line-price').text());
});
var tax = subtotal * taxRate;
var shipping = (subtotal > 0 ? shippingRate : 0);
var total = subtotal + tax + shipping;
$('.totals-value').fadeOut(fadeTime, function() {
$('#cart-subtotal').html(subtotal.toFixed(2));
$('#cart-tax').html(tax.toFixed(2));
$('#cart-shipping').html(shipping.toFixed(2));
$('#cart-total').html(total.toFixed(2));
if(total == 0){
$('.checkout').fadeOut(fadeTime);
}else{
$('.checkout').fadeIn(fadeTime);
}
$('.totals-value').fadeIn(fadeTime);
});
}
function updateQuantity(quantityInput)
{
var productRow = $(quantityInput).parent().parent();
var price = parseFloat(productRow.children('.product-price').text());
var quantity = $(quantityInput).val();
var linePrice = price * quantity;
productRow.children('.product-line-price').each(function () {
$(this).fadeOut(fadeTime, function() {
$(this).text(linePrice.toFixed(2));
recalculateCart();
$(this).fadeIn(fadeTime);
});
});
}
function removeItem(removeButton)
{
var productRow = $(removeButton).parent().parent();
productRow.slideUp(fadeTime, function() {
productRow.remove();
recalculateCart();
});
}
});
Set shipping to zero when subtotal + tax >= 50 (assuming that's the business rule).
var shipping = subtotal > 0 && (subtotal + tax < 50) ? shippingRate : 0;
And then, for display purposes, set the shipping value element to empty when shipping === 0. A ternary operator is one way to do it.
$('#cart-shipping').html(shipping === 0 ? '' : shipping.toFixed(2));

innerHTML does not dynamically update nor display on PHP page - JavaScript

I have managed to dynamically display the sum of 6 line-cost DOM elements from a php file. Unfortunately, when trying to calculate the delivery charge, my JavaScript methods regarding to the deliveryCharge implementation fails to display anything on the page. With the sub-total methods working and displaying perfectly, I tried to troubleshoot the problem by providing innerHTML with a constant value of both a string and an int- both times yielded nothing to be displayed on screen.
I have displayed both the working part of the sub-total calculation method as well as the non-working part of the delivery-charge calculation. Would the problem lie within an incorrect way of using innerHTML, be a calculation error or a different error entirely?
function calcST(){
var i;
var sum = 0; // initialize the sum
let p = document.getElementsByTagName("line_cost");
for (i = 0; i < p.length; i++) {
if (!isNaN(Number(p[i].innerHTML))) {
sum = Number(sum + Number(p[i].innerHTML)); // p[i].innerHTML gives you the value
}
}
setST(sum, "sub_total");
}
function setST(sum, item_id){
let i = document.getElementById(item_id);
i.innerHTML = sum;
calcDelivCharge();
}
function getST() {
let i = document.getElementById("sub_total");
let v = i.innerHTML;
return v;
}
function calcDelivCharge(){
var delCharge;
var e = getST();
if(e < 100){
delcharge = e*0.10
}else{
delcharge = 0;
}
setDelivCharge("delivery_charge", delCharge);
}
function setDelivCharge(item_id, delCharge){
let i = document.getElementById(item_id);
i.innerHTML = delCharge;
calculateTAX();
}
function getDelivCharge() {
let i = document.getElementById("delivery_charge");
let v = i.innerHTML;
return v;
}
I managed to find that the DOM was not ready loading before the getST() method was called. This can be fixed with the following code:
if(document.getElementById("sub_total") != null){
let i = document.getElementById("sub_total");
let v = i.innerHTML;
return v;
}
Unfortunately, delivery-charge is seen as 'unidentified'. Why does this appear when the getST() method is altered?
Well, if you're HTML is like
<line_cost>
<div>30</div>
<div>40</div>
...
</line_cost>
You can do this:
function calcSubtotal() {
const costs = document.querySelector("line_cost").children;
let sum = 0;
for( let i = 0 ; i < costs.length ; i ++) {
sum += parseInt(costs[i].innerHTML);
}
setST(sum, "sub_total");
}
// Subtotal getter and setter
function setST(sum, item_id) {
document.getElementById(item_id).innerHTML = sum.toFixed(2);
calcDeliveryCharge();
}
function getSubTotal() {
return document.getElementById("sub_total").innerHTML;
}
function calcDeliveryCharge() {
const subTotal = getSubTotal();
setDeliveryCharge("delivery_charge", subTotal < 100 ? subTotal * 0.10 : 0);
}
function setDeliveryCharge(item_id, deliveryCharge){
document.getElementById(item_id).innerHTML = deliveryCharge.toFixed(2);
//calculateTAX();
}
function getDeliveryCharge() {
return document.getElementById("delivery_charge").innerHTML;
}
calcSubtotal();
calcDeliveryCharge();
<line_cost>
<div>5</div>
<div>4</div>
<div>3</div>
<div>20</div>
</line_cost>
<br/>
<div>
<span>Sub Total: $
<span id="sub_total"></span>
</span>
<br/>
<span>Delivery Charge: $
<span id="delivery_charge"></span>
</span>
</div>
Otherwise, if you have:
<div>
<line_cost>30</line_cost>
<line_cost>40</line_cost>
...
</div>
Then do this:
function calcSubtotal() {
const costs = document.querySelectorAll("line_cost");
let sum = 0
for( let i = 0 ; i < costs.length ; i ++) {
sum += parseFloat(costs[i].innerHTML);
}
setST(sum, "sub_total");
}
// Subtotal getter and setter
function setST(sum, item_id) {
document.getElementById(item_id).innerHTML = sum.toFixed(2);
calcDeliveryCharge();
}
function getSubTotal() {
return document.getElementById("sub_total").innerHTML;
}
function calcDeliveryCharge() {
const subTotal = getSubTotal();
setDeliveryCharge("delivery_charge", subTotal < 100 ? subTotal * 0.10 : 0);
}
function setDeliveryCharge(item_id, deliveryCharge){
document.getElementById(item_id).innerHTML = deliveryCharge.toFixed(2);
//calculateTAX();
}
function getDeliveryCharge() {
return document.getElementById("delivery_charge").innerHTML;
}
calcSubtotal();
calcDeliveryCharge();
line_cost {
display: block;
}
<div>
<line_cost>25</line_cost>
<line_cost>34</line_cost>
<line_cost>43</line_cost>
<line_cost>250</line_cost>
</div>
<br/>
<div>
<span>Sub Total: $
<span id="sub_total"></span>
</span>
<br/>
<span>Delivery Charge: $
<span id="delivery_charge"></span>
</span>
</div>

Calculate the price of the items, depending on its quantity

I'm trying to make block with the prices. The unit price varies depending on its quantity of units. For example:
Quantity — Price for each
1____________________$110
10___________________$105
20___________________$100
...
Number of items:__
Total:
Price for each:
There is a need to write a the text field into which the user enters the number of items, and everything is recalculating and summing on the fly.
Here is my realization of this task:
var price1 = 110,
price2 = 105,
price3 = 100,
qty1 = 1,
qty2 = 10,
qty3 = 20;
function conversion(val) {
var div = document.getElementById("div"),
price = document.getElementById("price");
if (isNaN(val)) {
div.innerHTML = "";
price.innerHTML = "";
} else {
switch (true) {
case (val <= 0):
{
div.innerHTML = "";
price.innerHTML = "";
break;
}
case (val >= qty1 && val < qty2):
{
div.innerHTML = val * price1;
price.innerHTML = price1;
break;
}
case (val >= qty2 && val < qty3):
{
div.innerHTML = val * price2;
price.innerHTML = price2;
break;
}
case (val >= qty3):
{
div.innerHTML = val * price3;
price.innerHTML = price3;
break;
}
}
}
}
<div>
Quantity — Price for each
</div>
<div>
<div>1 — $110</div>
<div>10 — $105</div>
<div>20 — $100</div>
</div>
<div>
Number of items:
<div>
<input id="txt" onblur="conversion(this.value)" onchange="conversion(this.value)" onkeypress="conversion(this.value)" onkeyup="conversion(this.value)" type="number">
</div>
</div>
<div>
Total:
<div id="div"></div>
</div>
<div>
Price for each:
<div id="price"></div>
</div>
How it can be properly implemented, taking into account the fact that the lines with the quantity and unit price can be from one to infinity (values are taken from the database)?
I think it is possible to record the price and quantity in data-atributes and parse it with JS. Like this:
...
<div data-quantity="10" data-price="105">
<span class="quantity">10</span>
<span class="price">105</span>
</div>
...
Thanks!
Using the data attribute is indeed a solution:
console.log(document.getElementById("test").dataset)
<div data-quantity="10" data-price="105" id="test">
<span class="quantity">10</span>
<span class="price">105</span>
</div>
It's not fully compatible with previous IE version though, so be careful with it.
I would however suggest that you look for a way of moving your calculations away from the DOM to speed up your calculations.
For instance, parsing the data to a JavaScript object and doing the calculations there would save you some DOM trips and thus speed:
console.clear();
//markup for product
function Product(name) {
return {
//Name of product
name : name,
//List of price ranges (populated later)
prices : [
],
//method for adding a price
newPrice : function newPrice(quantity, cost) {
//Push new price unto list
this.prices.push({
quantity : quantity,
cost : cost
});
//Sort list
this.prices = this.prices.sort(function (a, b) {
return a.quantity - b.quantity
});
},
//Get the price for a variable quantity of this product
get : function (quantity) {
//Loop through prices to find the most matching
var price = 0;
for (var i = 0; i < this.prices.length; i++) {
if (this.prices[i].quantity <= quantity) {
price = this.prices[i].cost;
} else {
break;
}
}
console.log('price per unit:', price, 'price for all', quantity, 'units:', price * quantity)
}
};
} //Make an instance
var myHotProduct = new Product('Fancy pants');
//Add some prices
myHotProduct.newPrice(0, 110);
myHotProduct.newPrice(10, 105);
myHotProduct.newPrice(20, 100);
//get some quantities
myHotProduct.get(0);
myHotProduct.get(1);
myHotProduct.get(9);
myHotProduct.get(10);
myHotProduct.get(19);
myHotProduct.get(20);
//Log everything we know about our product
console.log(myHotProduct);
Now you can get your prices as arrays and modify them outside of the limitations of data-.

addeventlistener Shopping Cart does not work

I'll keep things simple, within my jsfiddle I have a shopping cart using javascript. What I want is for somebody to click the button and it will add an item to the cart. Unfortunately the function will not invoke AdditemtoCart unless it's outside the function which is driving me nuts. Let me know what I'm doing wrong.
jsfiddle link : https://jsfiddle.net/w2z3rb9h/51/
<div id="cart" class="glyphicon glyphicon-shopping-cart">
<div id="money">
$</div>
<div id="length">
Items
</div>
</div>
<button name="button" id="addItem">
Add Item
</button>
HTML Code above
// [(START)Cart]-------->
var cart = [];
// [(END)Cart]---------->
// [(START)Factory]-------->
var Item = function(name, price, count) {
this.name = name;
this.price = price;
this.count = count;
};
// [(END)Cart]-------------->
// [(START)Adding Items to Cart]-------->
function addItemToCart(name, price, count){
for (var key in cart) {
if (cart[key].name === name) {
cart[key].count += count;
cart[key].price += price;
return;
}
}
var item = new Item(name, price, count);
cart.push(item);
}
// [(END)Adding Items to Cart]---------->
// [(START)Remove Item From Cart]-------->
function removeItemFromCart(name,price) {
for(var key in cart) {
if(cart[key].name === name) {
cart[key].count --;
cart[key].price -= price;
if(cart[key].count === 0) {
cart.splice(key,1);
}
break;
}
}
}
// [(END)Remove Item From Cart]-------->
// [(START)Remove All Item From Cart]-->
function removeItemFromCartAll(name){
for (var key in cart){
if(cart[key].name === name){
cart.splice(key, 1);
break;
}
}
}
// [(END)Remove All Item From Cart]---->
function call() {
addItemToCart("Apple", 1.2, 1);
alert("It works");
}
document.getElementById("addItem").addEventListener("mousedown", call);
// [(START)Get Cart Amount] ----------->
function cartlength() {
var x = 0;
for (var key in cart) {
x += cart[key].count;
}
document.getElementById("length").innerHTML = "Items:" + x;
}
//Invoked:Get Cart Amount
cartlength();
// [(END)Get Cart Amount] ----------->
// [(START)Price] ------------------->
function cartprice() {
var y = 0;
for (var key in cart) {
y += cart[key].price;
}
document.getElementById("money").innerHTML = "$" + y;
}
//Invoke: Price
cartprice();
// [(END)Price] --------------------->
When you click on addItem button it invokes call function, and inside addItemToCart and alert also invoked. You can test it adding alert inside addItemToCart. Item is inside cart array now. And you need to update cart div, invoking cartlength and cartprice functions. Update call method this way:
function call() {
addItemToCart("Apple", 1.2, 1);
cartlength();
cartprice();
alert("It works");
}

Categories

Resources