The below source code is deployed on this post:
https://ericsweeten.wordpress.com/wp-content/uploads/2022/07/amortization.html
<!DOCTYPE html>
<html lang="en">
<title>Mortgage Amortization Table</title>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<style>
table{
border: 1;
margin-left: auto;
margin-right: auto;
vertical-align: middle;
}
</style>
</head>
<body>
<div class="col text-center">
<p>Only enter numbers (no special characters like $ and %).</p>
</div>
<table id="values" border="1">
<tr>
<td>Starting balance</td>
<td><input type="text" value="200000" placeholder="Enter starting balance" id="startingBal"></td>
</tr>
<tr>
<td class = "select"># of years
</td>
<td align="center">
<select id="numberOfYears">
<option value="30">30</option>
<option value="15">15</option>
<option value="10">10</option>
</select>
</td>
</tr>
<tr>
<td>Interest rate</td>
<td><input type="text" value="3.75" placeholder="Enter interest rate" id="interestRate"></td>
</tr>
<tr>
<td>Payment</td>
<td id="payment"></td>
</tr>
<tr>
<td>Final Payment</td>
<td id="paymentFinal"></td>
</tr>
</table>
<div class="col text-center">
<button onclick="loadTable()" class="btn btn-primary">Calculate</button>
</div>
<font size = 2>
<table id="myTable" class="table table-dark">
<tr>
<th> Month</th>
<th> Balance </th>
<th> Toward Interest </th>
<th> Toward Principal </th>
<th> Remaining </th>
<th> % Remaining </th>
</tr>
</table>
</font>
<script>
var monthlyPayment = 0;
var interest = 0;
var formatter = new Intl.NumberFormat('en-US',
{
style: 'currency',
currency: 'USD',
});
function loadTable()
{
var tbl = document.getElementById('myTable');
var startingBalance = parseFloat(document.getElementById('startingBal').value);
var balance = startingBalance;
var years = parseInt(document.getElementById('numberOfYears').value);
clearTable(tbl);
calculatePayment();
for (var section = 0; section < years; section++)
{
for (var month = 0; month < 12; month++)
{
var tr = tbl.insertRow();
var td = tr.insertCell();
td.innerHTML = month + 1;
td = tr.insertCell();
var interestTimesBalance = interest * balance;
td.innerHTML = formatter.format(balance.toFixed(2));
td = tr.insertCell();
td.innerHTML = formatter.format(interestTimesBalance.toFixed(2));
td = tr.insertCell();
td.innerHTML = formatter.format((monthlyPayment - interestTimesBalance).toFixed(2));
balance += interestTimesBalance;
balance -= monthlyPayment;
td = tr.insertCell();
var num = parseFloat(balance.toFixed(2));
if (section == years - 1 && month == 11)
{
var paymentFinal = 0;
var finalPayment = parseFloat(monthlyPayment);
paymentFinal = num < 0 ? paymentFinal = finalPayment + num : paymentFinal = finalPayment;
document.getElementById("paymentFinal").innerText = formatter.format(paymentFinal.toFixed(2));
num = 0;
}
td.innerHTML = formatter.format(num);
td = tr.insertCell();
num = ((balance / startingBalance) * 100).toFixed(2);
if (num < 0) num = 0;
td.innerHTML = num + "%";
if (month % 2 == 1)
{
tr.style.backgroundColor = 'black';
}
else
{
tr.style.backgroundColor = "rgb(234, 232, 228)";
}
tbl.appendChild(tr);
}
var delimeter = tbl.insertRow();
delimeter.style.backgroundColor = 'rgba(100,100,100,0)';
var col = delimeter.insertCell();
col.innerHTML = " ~ End of year " + (section + 1);
tbl.appendChild(delimeter);
}
}
function clearTable(table)
{
var rows = table.rows;
var i = rows.length;
while (--i)
{
table.deleteRow(i);
}
}
function calculatePayment()
{
var P = parseFloat(document.getElementById("startingBal").value).toFixed(2);
document.getElementById("startingBal").innerText = P;
interest = parseFloat(document.getElementById("interestRate").value) / 100 / 12; //monthly interest rate
var select = document.getElementById('numberOfYears');
var N = parseInt(select.options[select.selectedIndex].value) * 12; //number of payments months
//monthly mortgage payment
monthlyPayment = P * interest * (Math.pow(1 + interest, N)) / (Math.pow(1 + interest, N) - 1);
document.getElementById("payment").innerText = formatter.format(monthlyPayment.toFixed(2));
}
</script>
</body>
</html>