Smart Start Loan Calculator:
The Code
/* CONTROL: */
function getValues() {
// retrieve user input
let loanAmount = document.getElementById("loanAmount").value;
let term = document.getElementById("term").value;
let interestRate = document.getElementById("interestRate").value;
let returnObject = calculateTotals(loanAmount, term, interestRate);
let payoffArray = calculatePayoffSchedule(returnObject);
displayTotals(returnObject);
displayScheduleTable(payoffArray);
}
/* LOGIC: */
function calculateTotals(loanAmount, term, interestRate) {
// convert user input to Numbers; can be accomplished a number of ways, as shown with each of the parameters below
loanAmount = Number(loanAmount);
term = (term * 1);
interestRate = parseFloat(interestRate);
let monthlyRate = interestRate/1200;
let totalInterest = loanAmount * monthlyRate * term;
let totalCost = loanAmount + totalInterest;
let yourPayment = (loanAmount * monthlyRate)/(1-(1 + monthlyRate)**(-(term)));
let returnObject = {};
returnObject.loanAmount = loanAmount;
returnObject.term = term;
returnObject.monthlyRate = monthlyRate;
returnObject.totalInterest = totalInterest;
returnObject.totalCost = totalCost;
returnObject.yourPayment = yourPayment;
return returnObject;
}
function calculatePayoffSchedule(returnObject) {
//create array to hold values for table rows
let payoffArray = [];
// Before 1st iteration remaining balance = loanAmount
let remainingBalance = returnObject.loanAmount;
let interest;
let principal;
let interestToDate = 0;
for (let i = 1; i <= returnObject.term; i++) {
interest = remainingBalance * returnObject.monthlyRate;
principal = returnObject.yourPayment - interest;
interestToDate = interest + interestToDate;
remainingBalance -= principal;
payoffArray.push(i, returnObject.yourPayment.toFixed(2), principal.toFixed(2), interest.toFixed(2), interestToDate.toFixed(2), remainingBalance.toFixed(2));
}
return payoffArray;
}
/* DISPLAY: */
function displayTotals(returnObject) {
document.getElementById("yourPayment").innerHTML = ` $${returnObject.yourPayment.toFixed(2)}`;
document.getElementById("totalPrincipal").innerHTML = ` $${returnObject.loanAmount.toFixed(2)}`;
document.getElementById("totalInterest").innerHTML = ` $${returnObject.totalInterest.toFixed(2)}`;
document.getElementById("totalCost").innerHTML = ` $${returnObject.totalCost.toFixed(2)}`;
}
/* Create a tabel template with the following columns:
Month (display numbers 1 through returnObject.term), Payment, Principle, Interest, Interest to date, Remaining Balance */
//To the document set the values of the table data (id="results")
function displayScheduleTable(payoffArray) {
// Get the table body element from the page
let tableBody = document.getElementById("results");
// Get the template element from the page
let templateRow = document.getElementById("payoffTemplate");
// Clear the table first
tableBody.innerHTML = "";
for (let index = 0; index < payoffArray.length; index += 6) {
// Make a copy/fragment of the template row with importNode
let tableRow = document.importNode(templateRow.content, true);
// Get just the td and put them into an array to check its length
let rowCols = tableRow.querySelectorAll("td");
rowCols[0].classList.add(payoffArray[index]);
rowCols[0].textContent = (payoffArray[index]);
rowCols[1].classList.add(payoffArray[index+1]);
rowCols[1].textContent = payoffArray[index+1];
rowCols[2].classList.add(payoffArray[index+2]);
rowCols[2].textContent = payoffArray[index+2];
rowCols[3].classList.add(payoffArray[index+3]);
rowCols[3].textContent = payoffArray[index+3];
rowCols[4].classList.add(payoffArray[index+4]);
rowCols[4].textContent = payoffArray[index+4];
rowCols[5].classList.add(payoffArray[index+5]);
rowCols[5].textContent = payoffArray[index+5];
tableBody.appendChild(tableRow);
}
}

The Smart Start Loan Calculator application illustrates several core JavaScript concepts and techniques—such as DOM manipulation, iterative processing with for loops, type conversion, and data encapsulation. It also demonstrates the principle of separation of concerns by organizing the code into modular functions, each with a distinct responsibility, which makes the code easier to read, test, and maintain.
This app is structured in five functions:
getValues()
This function serves as the central controller of the app, capturing the information the user enters about their loan, then passing that information to other parts of the app. This occurs by accessing the Document Object Model (DOM), through the .getElementById() method, and retrieving the value from each of the corresponding form fields. These and other values are stored in variables that are passed as parameters to the subsequent functions invoked here.
The following two functions perform the business logic of the app.
calculateTotals()
This function first converts the user input from strings to numbers, ensuring that calculations can be performed accurately and reliably. This task can be accomplished in various ways, as demonstrated with each of the parameters passed into this function.
Additional relevant information, such as the total interest and monthly payment, is then generated by performing basic math operations. The resulting values are stored and returned in an object, ensuring downstream functions have easy access to this data.
calculatePayoffSchedule()
This function takes in the returnObject, and uses its information to create a month-by-month breakdown of the loan repayment. Using a for loop, it calculates and updates new values for the relevant data, then “pushes” a list of these values (specifically, the payment month number, monthly payment amount, the principal, interest, total interest to date, and the remaining balance) into the end of an array.
This process repeats for each month in the payment period defined by the term of the loan. After the last iteration, the completed payoffArray is returned, and will be used by the last function.
The last two functions are responsible for presenting the information calculated in the logic functions to the user's browser.
displayTotals()
This function also extracts the computed values from the returnObject, and manipulates the DOM to prominently present the corresponding values of the monthly payment amount, total principal, total interest, and total cost of the loan to the user. The .getElementbyId().innerHTML method, locates and injects the information into the desired section of HTML, while a template literal is used to format the data to appear as US currency, rounded to the nearest cent using the .toFixed(2) method.
displayScheduleTable()
This function generates and inserts the the Payoff Schedule table with the help of a template created in the app's html page. Using a for loop, the template rows are populated with the corresponding data for each column defined in the table header row. Only the number of rows called for are generated, based on the length of the payoffArray.