interchanging and manipulating two form input values - javascript

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
})

Related

automatically compute base from the value of 2 inputs javascript

I'm starting to learn javascript, and I'm trying to make a calculator app to solve simple harmonic motion. and made a js code to solve automatically if there are values from the input fields.
similar mechanics on this website when you put values it automatically solves and you can delete the value to solve another one https://www.omnicalculator.com/physics/displacement
const mass_event = document.getElementById("mass");
const k_event = document.getElementById("spring-constant");
const period_event = document.getElementById("period");
mass_event.addEventListener("input", solve);
k_event.addEventListener("input", solve);
period_event.addEventListener("input", solve);
function solve () {
var mass = document.getElementById("mass").value;
var konstant = document.getElementById("spring-constant").value;
var time = document.getElementById("period").value;
m = Number(mass);
k = Number(konstant);
t = Number(time);
if (m && k != 0) {
period = (2 * Math.PI * Math.sqrt((m/k)));
document.getElementById("period").value = (period);
} else if (k && t != 0) {
mass_kg = (Math.pow(t, 2) * k) / (4 * Math.pow(Math.PI, 2));
document.getElementById("mass").value = (mass_kg);
} else if (m && t != 0) {
spring_constant = (4 * Math.pow(Math.PI, 2) * m) / (Math.pow(t, 2));
document.getElementById("spring-constant").value = (spring_constant);
}}
It works but when there are already 2 values you cant delete the input values to solve for another. I'm trying to do this so that i can remove the solve button

Re-selecting another value and clac but old result displays in JS

I'm studying calc. I'm having problem with re-selecting value and calc.
Here is my whole program
https://jsfiddle.net/diessses/c9ykmsf2/6/
When user select value then press submit. it works perfectly. However when user change such as 'cb_amount' , s_month and 's_year' Then click submit below code part displays OLD result. Other part result works fine. Could you teach me write code please?
// PAY_START_END_MONTH_FMT message
const PAY_START_END_MONTH_FMT = "If loan start Month is :start ,<br> Final loan paying will be :end ";
let s_month = document.getElementById(elementId.s_month).value;
if (s_month) {
let s_year = document.getElementById(elementId.s_year).value;
let date = new Date();
date.setMonth(s_month - 1);
date.setFullYear(s_year);
let startMonth = DateManager.formatDate(date, DateManager.getFormatString().YYYY_MM);
DateManager.addMonth(date, (years * 12) - 1);
let endMonth = DateManager.formatDate(date, DateManager.getFormatString().YYYY_MM);
document.getElementById("pay_start_end_month").innerHTML = PAY_START_END_MONTH_FMT.replace(":start", startMonth).replace(":end", endMonth);
}
// CB_SENTENCE_FMT message
const CB_SENTENCE_FMT = "Combined bonus amount will be :j_actual_cb_ttl. Paying times is :j_cbTimes . mothly paying is :j_monthly_bns_payment";
if (bSecondToLastTtl > 1) {
let j_actual_cb_ttl = ValueUtils.comma(bSecondToLastTtl);
let j_cbTimes = cbTimes;
let j_monthly_bns_payment = ValueUtils.comma(monthly_b);
document.getElementById("j_cb_sentence").innerHTML = CB_SENTENCE_FMT.replace(":j_actual_cb_ttl", j_actual_cb_ttl).replace(":j_cbTimes", j_cbTimes).replace(":j_monthly_bns_payment", j_monthly_bns_payment);
}
There are a lot of variables which you are have declaration as "const". Try changing those to "let". Read about it here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let. I have forked your code and tried, seems to be updating the data based on the new values.
Forked fiddle https://jsfiddle.net/b5g73x02/. Below is what I changed.
let cbTimes = years * 2; //
let diff = amount - downpayment;
let justDevideCbAmount = cb_amount / cbTimes;
let monthly_b = (Math.floor(justDevideCbAmount / 100) * 100);
let bSecondToLastTtl = monthly_b * cbTimes;
let paymentTimes = years * 12;
let interestMod = 10000 + (interest * 100);
let ttlWInterest = parseInt(((amount - downpayment) * interestMod )/ 10000);
let ttlWInterestNegativeCb = ttlWInterest - bSecondToLastTtl;
let jstDevideMonthly = ttlWInterestNegativeCb / paymentTimes;
let secondToLastMonthlyPayment = (Math.floor(jstDevideMonthly / 100) * 100);
let firstMonthlyPayment = ttlWInterestNegativeCb - (secondToLastMonthlyPayment * (paymentTimes - 1));
let jKinri = (interest / 100).toFixed(5);
let kinriFinal = ValueUtils.comma(parseInt(ttlWInterest - (amount - downpayment)));

Find minimum time duration

I have an array of time duration strings as below, and would like to find the minimum time.
group = ["41:04", "54:50", "01:03:50"] // note this is mix of **mm:ss** and **HH:mm:ss**
I am using moment:
group.map(tid => moment.duration(tid,'hh:mm:ss').asSeconds());
but it interprets the first two elements as "hh:mm" instead of "mm:ss", and results in:
[147840, 197400, 3830]
However, the first element "41:04" is the shortest time duration.
Is there any way to get this right using moment? Or what is the best way to find the minimum time duration?
Note that if i concatenate zeros to the string by myself (ie, 00:41:04), it will be correct.
You could calculate the seconds elapsed using simple mathematics without using any libraries.
For example;
41:04 = 41 * 60 + 04
01:03:50 = 01 * (60 ^ 2) + 03 * 60 + 50
Creating simple function to calculate seconds elapsed.
const getSeconds = str => {
const sp = str.split(":");
let sum = 0;
sp.map((d, k) => {
sum += Number(d) * 60 ** (sp.length - 1 - k);
});
return sum;
};
Now you could loop through your array to get the seconds.
const min = group.reduce((d, k) => {
const a = getSeconds(d),
b = getSeconds(k);
return a < b ? d : k;
});
As a whole you could check out the code snippet below;
const group = ["50:04","41:04", "54:50", "01:03:50"];
const getSeconds = str => {
const sp = str.split(":");
let sum = 0;
sp.map((d, k) => {
sum += Number(d) * 60 ** (sp.length - 1 - k);
});
return sum;
};
const min = group.reduce((d, k) => {
const a = getSeconds(d),
b = getSeconds(k);
return a < b ? d : k;
});
console.log(min);
There might be more elegant solutions. But this is what I came up with. :D

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));
}
}
});

Why is my number coming up as 0? [duplicate]

This question already has answers here:
How do I get the value of text input field using JavaScript?
(16 answers)
Closed 6 years ago.
I am trying to make a calculator that calculates the amount of calories that have been burned in a certain amount of time, but whenever I run it, I get 0 as the output. I have tried setting the calorieCountOut variable to an arbitrary number, and then it works fine, but every time I run it with this code here, I get 0. Here is my code:
const AGECONST = 0.2017;
const WEIGHTCONST = 0.09036;
const HRCONST = 0.6309;
const SUBTRACTCONST = 55.0969;
const TIMECONST = 4.184;
//var gender = document.getElementById("gender").innerHTML;
var gender = "male";
var weight = document.getElementById("weight");
var age = document.getElementById("age");
var time = document.getElementById("time");
var hr = 140;//dummy number
function calculate(){
if (gender = "male"){
var calorieCount = ((age * AGECONST) - (weight * WEIGHTCONST) + (hr * HRCONST) - SUBTRACTCONST) * time / TIMECONST;
}
//else if (gender = "female"){
//}
var calorieCountOut = calorieCount.toString();
document.getElementById("output").innerHTML = calorieCountOut;
}
Try getElementById('myId').value for the value inside the control instead of the control itself as an object.
Right now you assign a html object to a variable, but what you want (i assume) is the number stored in that html object.

Categories

Resources