Input Checkbox Only Updates One Value But Other Inputs Don't Update? - javascript

So I have this app I made where it calculates the menu items total and includes a $5 delivery fee. The problem is the 4th option only includes the $5 fee in the total, but the other 3 options don't include the fee
Here's my codepen
https://codepen.io/shodoro/pen/dydNopX
Why is my 4th option, the smoothie $4 the only input checkbox that adds the delivery fee correctly?
The first 3 options don't include the $5 delivery fee in the total and I don't know how to fix it
Here's my JS
function updatePrice() {
let items = 0;
let deliveryFee = document.getElementById('fee')
let tax = document.getElementById('tax')
let tip = document.getElementById('tip')
tax = .1
tip = .2
document.querySelectorAll('input[type=checkbox]').forEach(checkBox => {
if (checkBox.checked) {
items += +checkBox.value
deliveryFee = 5
} else {
deliveryFee = 0
}
})
document.getElementById("price").textContent = `Food Total: $${(items).toFixed(2)}`;
document.getElementById("tax").textContent = `Tax (10%): $${(items * tax).toFixed(2)}`;
document.getElementById("tip").textContent = `Tip (20%): $${(items * tip).toFixed(2)}`;
document.getElementById("total").textContent = `Your order total is: $${((items * tax)+(items * tip)+(items)+(deliveryFee)).toFixed(2)}`;
}
Essential I want all options to include the delivery fee when clicking them, but also making sure the delivery fee resets to 0 whenever you uncheck all options.

That's because you are setting deliveryFee in a loop and so if, for example, the 12 piece wings item is checked, then it sets deliveryFee to 5 and then it's going to loop through to the next item (6 piece wings) and it will set deliveryFee to 0. So when it gets to the calculation for the total, it deliveryFee will be 0 and not 5. I think maybe you want something more like this:
function updatePrice() {
console.log('updatePrice');
let items = 0;
let deliveryFee = 0;
let tax = document.getElementById('tax')
let tip = document.getElementById('tip')
tax = .1
tip = .2
console.log('before forEach loop', items, deliveryFee);
document.querySelectorAll('input[type=checkbox]').forEach(checkBox => {
console.log(checkBox);
if (checkBox.checked) {
console.log('checked!')
items += +checkBox.value
if (deliveryFee == 0) {
console.log('First checked item, setting delivery fee to 5.')
deliveryFee = 5;
}
} else {
console.log('not checked!');
}
})
console.log('after forEach loop', items, deliveryFee);
if (items >= 10) {
deliveryFee = deliveryFee * 2;
}
let orderTotal = (items * tax)+(items * tip)+(items) + deliveryFee;
document.getElementById("price").textContent = `Food Total: $${(items).toFixed(2)}`;
document.getElementById("tax").textContent = `Tax (10%): $${(items * tax).toFixed(2)}`;
document.getElementById("tip").textContent = `Tip (20%): $${(items * tip).toFixed(2)}`;
document.getElementById("fee").textContent = `Delivery Fee: $${deliveryFee.toFixed(2)}`;
document.getElementById("total").textContent = `Your order total is: $${orderTotal}`;
}

Related

Develop a decreasing price function by step

I'm trying to configure my price list. The price unit must decrease depending the quantity you buy but should keep growing.
I was able to do it in excel, but now I would like to do a function in javascript.
my pricelist in the DB is like this:
min max price
1 9 50
10 19 45
20 29 40
30 49 35
50 79 30
80 90 25
The function depending the price is
qty price function
1-9 qty*50
10-19 (qty-9)*45+(9*50)
20-29 (qty-19)*40+(19*45)
...
80-90 (qty-79)*25+(79*30)
I would like to create a ES6 function that receive the quantity in parameter and return the total price.
UPDATE
I was able to create the function but I'm pretty sure that we can improve it.
let priceList= [
{"_id":1,"min":1,"max":9,"price":50},
{"_id":2,"min":10,"max":19,"price":45},
{"_id":3,"min":20,"max":29,"price":40},
{"_id":4,"min":30,"max":49,"price":35},
{"_id":5,"min":50,"max":79,"price":30},
{"_id":6,"min":80,"max":90,"price":25}
]
function sum(qty){
let sum = 0;
let prices = priceList.filter((x)=>x.min<=qty);
var price;
var priceArr=[];
const pricesLength = prices.length;
for (let i = 0; i < pricesLength ; i++) {
price = prices[i];
if(i==0){
priceArr.push(price.price * ((price.max < qty) ? price.max : qty));
} else {
priceArr.push(price.price * ((price.max <= qty) ? price.max - price.min + 1 : qty - price.min + 1) + priceArr[i-1]);
}
}
return priceArr[pricesLength-1];
}
https://jsfiddle.net/jm7teuqb/1/

Application that calculates price depending on quantity in JavaScript

I have this exercise that I am struggling to comprehend the logic to achieve the outcome when qty is more than 3:
An application to calculate the price of pizzas (listed below) that will be purchased during a promotional period. The number of pizzas will be entered by the user.
One large pizza will cost $6.45.
Two large pizzas will cost $12.00.
Three large pizzas will cost $14.00.
Four or more pizzas will use a combination of the above prices to ensure the best price for the customer. For example, the best price for five pizzas would be two pizzas ($12.00) + three pizzas ($14.00).
The algorithm must also take account of all possible situations by using sequence, selection and iteration structures.
Below is my code so far:
let calcOrder = () => {
// get inputs
var qty = document.getElementById("quantity").value;
var price = 6.45;
var price2 = 12.0;
var price3 = 14.0;
var totalPrice;
// validate missing, non-digit, negative inputs
if (qty == "") {
document.getElementById("message").innerHTML = "Missing input";
} else if (isNaN(qty)) {
document.getElementById("message").innerHTML = "Numbers only";
} else if (qty < 0) {
document.getElementById("message").innerHTML =
"Negative numbers are not allowed";
} else {
//calc total
if (qty == 1)
{
totalPrice = price;
}
else if (qty == 2)
{
totalPrice = price2;
}
else if (qty == 3)
{
totalPrice = price3;
}
//output total
document.getElementById("message").innerHTML =
`Total price is $${totalPrice}`;
}
// prevent form from submission
return false;
};
Thank you
you can use division and mod operation to calculate the price:
(this example assuming all check you did valid input are already done)
const qte = document.getElementById("quantity").value;
const price = 6.45;
const price2 = 12.0;
const price3 = 14.0;
let totalPrice;
const total3 = parseInt("" + qte / 3 + "", 10) * price3;
const total2 = parseInt("" + (qte % 3) / 2 + "", 10) * price2;
const total1 = parseInt("" + ((qte % 3) % 2) + "", 10) * price;
totalPrice = total1 + total2 + total3;
document.getElementById("message").innerHTML =
`Total price is $${totalPrice}`;
what is actually happening in the code
well it is basic mathematics, if you want to know how many 3s in your number you divide by 3 and take the integer part or floor of the result, basic division. for example 10 = 3*3 + 1 so you have 3 as a result of that division.
since you only want to apply the price of 3 pizza as top priority you do this division then multiply by the price for 3.
then come the priority for the price of 2 pizzas, but you not interested for the total number of pizzas, only what was left after you payed with the price of 3 pizzas so you do the mod operator (%) with 3 to get was left unpaid, for example 8 = 3*2 + 2, this give us 2 pizzas left unpaid so you apply the price of 2 pizzas.
the you check if a single pizza is left after you paid for 2 pizzas (which would only happen if only a single pizza was left after you paid for 3). if there is single pizza you pay for it otherwise you add nothing.
ps: after paying for pizzas in multiple of three, you only add the price of 2 pizzas or a single one, but never both, otherwise price of 3 pizzas would apply instead.
hope the explanation is clear, if not leave a comment and i'll try to adjust what was not clear.

interchanging and manipulating two form input values

I've created a calculator that requires a value in either months or years in order to perform a calculation. The calculator works with one exception: It is required that the two input fields update based on the value of each other. here's an example of the behavior I am attempting to recreate:
https://www.bankrate.com/calculators/mortgages/loan-calculator.aspx
I apologize in advance if the following example reads poorly, but here it goes:
If a user enters 72 'months', the 'years' input will divide months by 12 and display the result. After doing a little tooling around, I found that using [a, b] = [b*12, a/12] gets me halfway there. The problem I'm running into is that once values have been entered, the value of the most recently updated input is updated with the previous value (including the calculation). For example, User enters 60 months > years is populated with the value of 5 > user changes months to a value of 72 > years is populated with a value of 6 > months is automatically populated with a value of 60 (years remains at a value of 6)
Here's the JS:
const loan = () => {
let principal = document.getElementById('principal')
let interestRate = document.getElementById('interestRate')
let terms = document.getElementById('terms')
let termsInYears = document.getElementById('termsInYears')
let payment = document.getElementById('payment')
let total = document.getElementById('total')
let totalInterest = document.getElementById('totalInterest')
let closingCosts = document.getElementById('closingCosts')
let netAfterFees = document.getElementById('netAfterFees')
let totalFeesAndInterest = document.getElementById('totalFeesAndInterest')
let trueCost = document.getElementById('trueCost')
let amount = parseFloat(principal.value)
let interest = parseFloat(interestRate.value) / 100 / 12
let payments = parseFloat(terms.value)
let fees = parseFloat(closingCosts.value)
if(!fees) {
closingCosts.value = 0
}
[terms.value, termsInYears.value] = [termsInYears.value*12, terms.value/12]
let x = Math.pow(1 + interest, payments)
let monthly = (amount * x * interest) / (x-1)
let totalPay = (monthly * payments)
if (isFinite(monthly) && payment) {
payment.innerHTML = monthly.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
netAfterFees.innerHTML = (amount - fees).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
total.innerHTML = (totalPay).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
totalInterest.innerHTML = ((monthly * payments) - amount).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
totalFeesAndInterest.innerHTML = (totalPay - amount + fees).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
trueCost.innerHTML = (((totalPay - amount + fees) / amount)*100).toFixed(2)
} else {
payment.innerHTML = '0'
netAfterFees.innerHTML = '0'
total.innerHTML = '0'
totalInterest.innerHTML = '0'
totalFeesAndInterest.innerHTML = '0'
trueCost.innerHTML = '0'
}
}
I can't speak on the quality of the working calculator given my experience level. However, it does work. I'm just having one heck of a time getting past this [likely silly] input exchange.
Any help would be greatly appreciated!
I ended up solving this issue using querySelector and then adding an event listener for each input:
document.querySelector('#terms').addEventListener('input', (e) => {
termsInYears.value = e.target.value / 12
})
document.querySelector('#termsInYears').addEventListener('input', (e) => {
terms.value = e.target.value * 12
})

Push to array inside a for in Javascript

I have an object, this.items, that I am running a for in on, then using the find method to get all the products by id. I'm attempting to set a salesTax amount based on a conditional (if taxPercent > 0), but the loop is going through more than the expected amount of times and thus the taxPercent is larger than required.
total() {
let total = 0
let tax = []
let importDuty = .05
for (let productId in this.items) {
total += this.inventory.products.find(product => {
if (product.taxPercent > 0) {
tax.push(product.price * product.taxPercent)
}
return product.id == productId
}).price * this.items[productId]
}
tax = tax.reduce((a, b) => a + b, 0)
let importDutyToApply = total * importDuty
total = total + importDutyToApply + tax
let response = {
'total': total,
'tax': tax
}
return response
}
I'm wondering how I can set the total tax to apply for any items that do not have the taxPercent set to 0. So, if I had three items and one of them required a 10 percent tax on $100, the total should be $10. Likewise if I had many items with some requiring the 10 percent tax and others not, it would only add up for the ones that require it. Any thoughts?
The function you pass to find gets called a load of times. You just want to add tax for the product it found, not for everything it looked at on the way.
const product = this.inventory.products.find( product => product.id == productId );
if (product.taxPercent > 0) {
tax.push(product.price * product.taxPercent)
}
total += product.price * this.items[productId]

Can I force percentages to sum up to a exact value?

I have a fixed tax value, say USD 50,00, and I want to divide this tax among people. So, one person can select how much of the tax he will pay. Once this person selects its quota, the remaining of the tax is divided among the others.
I have made a javascript(I am using EmberJs) function to do this automatically but sometimes the value is evaluated to more than USD 50 and sometimes less.
My function:
percentageFromValue(person, selectedValue){
selectedValue = selectedValue.replace(/[R$\s]/g,'');
selectedValue = selectedValue.replace(/[,]/g,'.');
selectedValue = parseFloat(selectedValue);
let taxValue= this.get('taxValue');
///nao deixar valor utrapasse o valor da taxa
if(selectedValue> taxValue)
valor = taxValue;
let personPercentage = (selectedValue*100.0 / taxValue);
personPercentage = parseFloat(personPercentage );
let parcialSum= 0;
person.set('pctTax',personPercentage.toFixed(2));
let remainingPercent= 100.0 - personPercentage ;
let totalPersons = this.get('persons.length');
let pctPerPerson= remainingPercent/ (totalPersons - 1);
let valuePerPerson= (pctPerPerson* taxValue) / 100.0;
this.get('persons').forEach(r =>{
if(person.get('id') != r.get('id')){
r.set('pctTax',pctPerPerson);
r.set('value',valuePerPerson.toFixed(2));
}
});
},
How Can I make this automatic redistributions to always sum up to USD 50,00??
This is more of a rounding problem than a programming problem.
Say you want to divide a $50 tax among three people... 50/3 = 16.6666666... assuming it's a currency and you round up to two decimals, each person pays $16.66 and the sum is 16.66 * 3 = 49.98.
If there is no requirement of having all people paying the exact same amount of tax every time, I'd just add/subtract the rounding difference from the first person:
let remainingPercent= 100.0 - personPercentage ;
let totalPersons = this.get('persons.length');
let pctPerPerson= remainingPercent/ (totalPersons - 1);
let valuePerPerson= (pctPerPerson* taxValue) / 100.0;
let roundingError = taxValue - pctPerPerson * totalPersons;
this.get('persons').forEach(r =>{
if(person.get('id') != r.get('id')){
r.set('pctTax',pctPerPerson);
if (this.indexOf(r) == 0) {
r.set('value',valuePerPerson.toFixed(2) + roundingError);
} else {
r.set('value',valuePerPerson.toFixed(2));
}
}
});

Categories

Resources