The code below is a quick, working example of a compound interest table I wrote. My concern is mainly about separating the application data/logic from the UI code. I didn't use any frameworks on purpose, just because this is an exercise.
Here's the code
(function() {
"use strict";
function clearContents(tag) {
while (tag.firstChild) {
tag.removeChild(tag.firstChild);
}
}
function addValueToRow(rowTag, value) {
var newValue = document.createElement("td");
newValue.appendChild(document.createTextNode(value));
rowTag.appendChild(newValue);
}
function formatMoney(value) {
return value.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function main() {
var inputBoxes = document.getElementsByTagName("input");
var table = document.getElementById("results");
var monthlyContributionInput = document.getElementById("monthly-contribution");
var numberOfYearsInput = document.getElementById("year-count");
var annualInterestRateInput = document.getElementById("annual-interest-rate");
var updateTable = function(event) {
var rowcount = Number(numberOfYearsInput.value);
var monthlyContribution = Number(monthlyContributionInput.value);
var annualInterestRate = Number(annualInterestRateInput.value) / 100.0;
var interestFactor = 1 + annualInterestRate / 12.0;
var balance = 0;
var totalDeposit = 0;
var monthCount = 0;
var yearInterest = 0;
var perviousYearInterest = 0;
clearContents(table);
for (var row = 1; row <= rowcount; row += 1) {
var newRow = document.createElement("tr");
monthCount = 12 * row;
totalDeposit = 12.0 * monthlyContribution * row;
balance = monthlyContribution * (
(Math.pow(interestFactor, monthCount + 1) - 1) /
(interestFactor - 1) - 1);
perviousYearInterest = yearInterest;
yearInterest = balance - totalDeposit;
addValueToRow(newRow, "" + row);
addValueToRow(newRow, formatMoney(monthlyContribution * 12.0));
addValueToRow(newRow, formatMoney(yearInterest - perviousYearInterest));
addValueToRow(newRow, formatMoney(totalDeposit));
addValueToRow(newRow, formatMoney(balance - totalDeposit));
addValueToRow(newRow, formatMoney(balance));
table.appendChild(newRow);
}
};
for (var i = 0; i < inputBoxes.length; i += 1) {
inputBoxes[i].oninput = updateTable;
}
}
window.addEventListener("load", main, false);
})();
:root {
--system-font-stack: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
body {
font-family: var(--system-font-stack);
margin: 0;
padding: 1.5rem;
}
#user-inputs>div {
display: flex;
flex-direction: column;
margin-bottom: 0.75rem;
}
#user-inputs label {
margin-bottom: 0.25rem;
}
#user-inputs input {
width: 15rem;
}
#interest-table,
#interest-table thead,
#interest-table tr {
width: 100%;
}
#interest-table>thead>tr>td {
font-weight: bold;
}
#interest-table td {
font-size: 12px;
}
<!DOCTYPE html>
<html>
<head>
<title>Compound Interest Calculator</title>
</head>
<body>
<h1>Compound Interest Calculactor</h1>
<div id="user-inputs">
<div>
<label for="monthly-contribution">Monthly Contribution</label>
<input type="text" id="monthly-contribution" />
</div>
<div>
<label for="annual-interest-rate">Annual Interest Rate (%)</label>
<input type="text" id="annual-interest-rate" />
</div>
<div>
<label for="year-count">Number of Years</label>
<input type="text" id="year-count" />
</div>
<table id="interest-table">
<thead>
<tr>
<td>Year</td>
<td>Year Deposit</td>
<td>Year Interest</td>
<td>Total Deposit</td>
<td>Total Interest</td>
<td>Balance</td>
</tr>
</thead>
<tbody id="results">
</tbody>
</table>
<script src="_scripts/compound-interest.js"></script>
</body>
</html>