The Code
JavaScript
function getValues() {
//get the values from the page
var loanValue = document.getElementById("loanValue").value;
var termValue = document.getElementById("termValue").value;
var rateValue = document.getElementById("rateValue").value;
//parse into Doubles
var loanDouble = parseFloat(loanValue).toFixed(2);
var termDouble = parseFloat(termValue).toFixed(2);
var rateDouble = parseFloat(rateValue).toFixed(2);
//validate that entries are Doubles
if (
!Number.isNaN(loanDouble) &&
!Number.isNaN(termDouble) &&
!Number.isNaN(rateDouble)
) {
amortize(loanDouble, termDouble, rateDouble);
} else {
alert("YOU MUST ENTER NUMBERS!");
}
}
var returnArray = [];
function amortize(loanDouble, termDouble, rateDouble) {
var payment = calcPayment(loanDouble, rateDouble, termDouble);
var monthlyRate = 0.0;
var balance = loanDouble;
var totalInterest = 0;
var monthlyInterest = 0;
var monthlyPrinciple = 0;
var monthlyRate = calcMonthlyRate(rateDouble);
var fMonth = "";
var newTotalInterest = 0;
var newBalance = 0;
for (let month = 0; month < termDouble; month++) {
monthlyInterest = calcMonthlyInterest(balance, monthlyRate);
totalInterest = calcTotalInterest(totalInterest, monthlyInterest);
monthlyPrinciple = calcMonthlyPrinciple(payment, monthlyInterest);
newBalance = calcNewBalance(balance, monthlyPrinciple);
balance -= monthlyPrinciple;
fMonth = (month + 1).toString();
returnArray.push(
`<tr>
<td>#${fMonth}</td>
<td>$${payment}</td>
<td>$${monthlyPrinciple}</td>
<td>$${monthlyInterest}</td>
<td>$${totalInterest}</td>
<td>$${newBalance}</td>
</tr>`
);
}
TotalInterest = totalInterest;
TotalCost = loanDouble + totalInterest;
displayData(returnArray);
}
function calcPayment(loanDouble, rateDouble, termDouble) {
monthlyRate = calcMonthlyRate(rateDouble);
var loan = loanDouble;
var term = termDouble;
var payment = (loan * monthlyRate) / (1 - (Math.pow(1 + monthlyRate, -term)));
return payment.toFixed(2);
}
function calcMonthlyRate(rateDouble) {
monthlyRate = rateDouble / 1200;
return monthlyRate;
}
function calcMonthlyInterest(balance, monthlyRate) {
monthlyInterest = balance * monthlyRate;
return monthlyInterest.toFixed(2);
}
function calcMonthlyPrinciple(payment, monthlyInterest) {
monthlyPrinciple = payment - monthlyInterest;
return monthlyPrinciple.toFixed(2);
}
function calcTotalInterest(totalInterest, monthlyInterest) {
let a = parseFloat(totalInterest);
let b = parseFloat(monthlyInterest);
let x = a + b;
newTotalInterest = x.toFixed(2);
return newTotalInterest;
}
function calcNewBalance(balance, monthlyPrinciple) {
let x = balance - monthlyPrinciple;
newBalance = parseFloat(x);
return newBalance.toFixed(2);
}
function displayData(returnArray) {
let templateRows = "";
for (let i = 0; i < returnArray.length; i++) {
templateRows += `${returnArray[i]}`;
}
document.getElementById("results").innerHTML = templateRows;
}
//resets the table
function resetTable() {
let templateRows = "";
document.getElementById("results").innerHTML = templateRows;
}
This code displays without error thanks to: https://tohtml.com
An explanation:
The code is structured in 5 parts:
getValues()
getValues gets the user input from the page in
the form of strings by utilizing
getElementById to pull the values from the input
fields.
Then we apply parseFloat to the strings to get
Doubles to use for our purposes.
The if statement validates that all
inputs were indeed Doubles and only allows us to proceed
if that is the case. Otherwise, we get an error message telling us to fix the
input(s).
The Doubles are passed to the amortize() function.
amortize()
amortize takes in the parameters from
getValues() and sets up the formula for calculating the amortization.
It also
calls generates its other necessary variables by calling other functions[calcPayment(), calcMonthlyRate(), calcMonthlyInterest(), calcMonthlyPrinciple(), calcTotalInterest(), calcNewBalance()]
It runs the calculations on a month by month loop and builds an array of
results for each.
Finally, is passes that array to the displayData() function.
calcPayment()
calcPayment takes in the numerical values submitted by the user.
A "Relatively Simple" math formula is applied and we return the variable: 'payment' to be used in the amortize() function.
calcMonthlyRate()
calcMonthlyRate takes in rate.
The rate is divided by 1200 (12 months per year, and 100 per-cents).
Return monthlyRate to be used in the amortize() function.
calcMonthlyInterest()
calcMonthlyInterest takes in balance and monthlyRate
The monthly rate is applied to the balance and monthlyInterest is returned to be used in the amortize() function.
calcMonthlyPrinciple()
calcMonthlyPrinciple takes in payment and monthlyInterest
The payment amount minus the monthlyInterest equals the monthly principle.
Return monthlyPrinciple to be used in the amortize() function.
calcTotalInterest()
calcTotalInterest takes in monthlyInterest and totalInterest.
It exists to encapsulate the process for the rescursive adding of the current interest and then setting that new total interest to be used as a base in the next iteration.
Return newTotalInterest to be used in the amortize() function.
calcNewBalance()
calcNewBalance takes in balance and monthlyPrinciple.
Makes the current balance equal the previous blance minus the current principle.
Return newBalance to be used in the amortize() function.
displayData()
displayData displays the data, table layout style, onto the page. Most of the work was done in amortize(), so here it just loops over the passed in array (returnArray[i]) and prints one output per indexed entry.
The code is completed once the table on the APP page is filled with rows from the string templateRows.
resetTable()
resetTable is called by the Reset button, and simply assigns an empty string to templateRows, thus giving the table nothing to display.