I have a Mortgage Calculator form that has the Financed Amount, Interest Rate, and Term Length.
I want to prepopulate it with default values, and when ones of the values changes, update the monthly payment amount.
As I have it now, it will only run the function when Submit is clicked. How do I set it to run when any of the fields are changed?
<html>
<form action="">
<label>APR%: <input type="text" value="4" id="apr" name="APR"/></label>
<label>Loan Term: <input type="text" value="30" id="trm" name="APR"/></label>
<label>Loan Amount: <input type="text" value="450000" id="amt" name="amt"/></lablel>
<input type="text" id="pmt" name="mPmt"/>
<input type="button" id="sbt" value="Submit" />
<input type="reset" id="rst" value="Reset Form" />
</form>
</html>
<script>
var term;
var apr;
var amt;
var mPmt;
window.onload = function()
{
document.getElementById("apr").focus();
document.getElementById("sbt").onclick = getValues;
};
//use toFixed(2) to set the precision of the mPayment. Use it on an int.
function getValues()
{
term = document.getElementById("trm").value;
apr = document.getElementById("apr").value;
amt = document.getElementById("amt").value;
apr /= 1200;
term *= 12;
mPmt = calculatePayment();
document.getElementById("pmt").value = "$" + mPmt.toFixed(2);
};
function calculatePayment()
{
var payment = amt*(apr * Math.pow((1 + apr), term))/(Math.pow((1 + apr), term) - 1);
return payment;
}
</script>
You can use the change or/and keyup event listeners.
HTML
<form id='calculator'>
<label for='apr'>APR%:
<input type="number" value="4" id="apr" name="APR"/>
</label>
<label for='trm'>Loan Term:
<input type="number" value="30" id="trm" name="APR"/>
</label>
<label for='amt'>Loan Amount:
<input type="number" value="450000" id="amt" name="amt" step='100'/>
</label>
<input type="text" id="pmt" name="mPmt" readonly/>
<input type="button" id="sbt" value="Submit" />
<input type="reset" id="rst" value="Reset Form" />
</form>
JS
function getValues() {
const term = Number(document.querySelector("#trm").value);
const apr = Number(document.querySelector("#apr").value);
const amt = Number(document.querySelector("#amt").value);
const pmt = document.querySelector("#pmt")
mPmt = calculatePayment(term * 12, apr / 1200, amt);
// a temporary fix e.g. for APR of 0% or an empty loan term
if (!isNaN(mPmt) && isFinite(mPmt)) {
pmt.value = '$' + mPmt.toFixed(2);
} else {
pmt.value = ''
}
}
function calculatePayment(term, apr, amt) {
const payment = amt * (apr * Math.pow((1 + apr), term))/(Math.pow((1 + apr), term) - 1);
return payment;
}
window.addEventListener('DOMContentLoaded', () => {
const calculator = document.querySelector('#calculator');
// listen for keyup and change events
['keyup', 'change'].forEach((type) => {
// add the listeners to the form
calculator.addEventListener(type, (event) => {
// check if the event was fired from an input number box
if (event.target.matches('input[type="number"]')) {
getValues();
}
})
})
document.querySelector("#apr").focus();
})
Note I have added a temporary fix for the result being $NaN (Not a number) or $Infinity. This occurs when the APR is 0% or say the loan term is just an empty box. It probably needs a better fix, but I am limited for time.
1 Like
Hi @jeremy58, instead of listening to click events of the submit button, you might listen to input events of the entire form:
HTML
<form id="my-form">
...
</form>
JS
const form = getElementById('my-form')
form.addEventListener('input', getValues)
(x-post)
1 Like
How about something like the following?
var term;
var apr;
var amt;
var mPmt;
window.onload = function() {
// Call getValues() when the page loads to prepopulate the monthly payment amount
getValues();
// Add event listeners to each input element to update the monthly payment amount when the values change
document.getElementById("apr").addEventListener("change", getValues);
document.getElementById("trm").addEventListener("change", getValues);
document.getElementById("amt").addEventListener("change", getValues);
};
function getValues() {
term = document.getElementById("trm").value;
apr = document.getElementById("apr").value;
amt = document.getElementById("amt").value;
apr /= 1200;
term *= 12;
mPmt = calculatePayment();
document.getElementById("pmt").value = "$" + mPmt.toFixed(2);
};
function calculatePayment() {
var payment = amt*(apr * Math.pow((1 + apr), term))/(Math.pow((1 + apr), term) - 1);
return payment;
}