The Code for Loan Calculator

                        
                            // CONTROLLER FUNCTION(S)
                            // Get UI values
                            function getValues() {
                                let loanValue = document.getElementById("loanValue").value;
                                let monthsValue = document.getElementById("monthsValue").value;
                                let rateValue = document.getElementById("rateValue").value;
                            
                                // convert to Numbers
                                loanValue = Number(loanValue);
                                monthsValue = Number(monthsValue);
                                rateValue = Number(rateValue);
                            
                                // if valid input, calculate loan payments and display
                                if (validateInput(loanValue, monthsValue, rateValue)) {
                                    let results = getPayments(loanValue, rateValue, monthsValue);
                                    displayResults(results);
                                }
                            }
                            
                            
                            // LOGIC FUNCTION(S)
                            function getPayments(amount, rate, term) {
                                let loanPaymentObj = {};
                                loanPaymentObj.Payments = [];
                                loanPaymentObj.Payment = calcPayment(amount, rate, term);
                            
                                // first month
                                let balance = amount;
                                let totalInterest = 0.0;
                                let monthlyInterest = 0.0;
                                let monthlyPrincipal = 0.0;
                                let monthlyRate = calcMonthlyRate(rate);
                            
                                // loop over each month until term of loan
                                for (let index = 1; index <= term; index++) {
                                    monthlyInterest = calcMonthlyInterest(balance, monthlyRate);
                                    totalInterest += monthlyInterest;
                                    monthlyPrincipal = loanPaymentObj.Payment - monthlyInterest;
                                    balance -= monthlyPrincipal;
                            
                                    let paymentObj = {};
                            
                                    paymentObj.Month = index;
                                    paymentObj.Payment = loanPaymentObj.Payment;
                                    paymentObj.MonthlyPrincipal = monthlyPrincipal;
                                    paymentObj.MonthlyInterest = monthlyInterest;
                                    paymentObj.TotalInterest = totalInterest;
                                    paymentObj.Balance = balance;
                                    
                                    loanPaymentObj.Payments.push(paymentObj);
                                }
                            
                                loanPaymentObj.TotalInterest = totalInterest;
                                loanPaymentObj.TotalCost = amount + totalInterest;
                                loanPaymentObj.Amount = amount;
                            
                                return loanPaymentObj;
                            }
                            
                            function calcPayment(amount, rate, term) {
                                let monthlyRate = calcMonthlyRate(rate);
                                
                                let payment = (amount * monthlyRate) / (1 - Math.pow(1 + monthlyRate, -term));
                            
                                return payment;
                            }
                            
                            function calcMonthlyRate(rate) {
                                return rate/1200;
                            }
                            
                            function calcMonthlyInterest(balance, monthlyRate) {
                                return balance * monthlyRate;
                            }
                            
                            function validateInput(loanValue, monthsValue, rateValue) {
                                let output = true;
                            
                                // months is integer
                                if (!Number.isInteger(monthsValue)) {
                                    alert("Term length (months) must be an integer!")
                                    output = false;
                                }
                            
                                // check values are greater than 0
                                if (loanValue <= 0 || monthsValue <= 0 || rateValue <= 0) {
                                    alert("You must enter a value greater than 0!")
                                    output = false;
                                }
                            
                                // check loan upper limit
                                if (loanValue > 1000000) {
                                    alert("Maximum loan value is £1,000,000")
                                    output = false;
                                }
                            
                                // check months upper limit
                                if (monthsValue > 600) {
                                    alert("Maximum term length is 600 months")
                                    output = false;
                                }
                            
                                // check rate upper limit
                                if (rateValue > 100) {
                                    alert("Maximum rate is 100%")
                                    output = false;
                                }
                            
                                return output;
                            }
                             
                            
                            // VIEW FUNCTION(S)
                            function displayResults(results) {
                                // display results overview
                                let monthlyPayments = document.getElementById("monthlyPaymentsValue");
                                let totalPrincipal = document.getElementById("totalPrincipalValue");
                                let totalInterest = document.getElementById("totalInterestValue");
                                let totalCost = document.getElementById("totalCostValue");
                            
                                monthlyPayments.innerHTML = results.Payment.toLocaleString('en-UK', { style: 'currency', currency: 'GBP' });
                                totalPrincipal.innerHTML = results.Amount.toLocaleString('en-UK', { style: 'currency', currency: 'GBP' });
                                totalInterest.innerHTML = results.TotalInterest.toLocaleString('en-UK', { style: 'currency', currency: 'GBP' });
                                totalCost.innerHTML = results.TotalCost.toLocaleString('en-UK', { style: 'currency', currency: 'GBP' });
                            
                                //TABLE
                                // get the table body element from the page
                                let tableBody = document.getElementById("results");
                                // get the template row
                                let templateRow = document.getElementById("loanTemplate");
                                // clear the table first
                                tableBody.innerHTML="";
                            
                                results.Payments.forEach(element => {
                                    let tableRow = document.importNode(templateRow.content, true);
                                    let rowCols = tableRow.querySelectorAll("td");
                            
                                    rowCols[0].textContent = element.Month;
                                    rowCols[1].textContent = element.Payment.toLocaleString('en-UK', { style: 'currency', currency: 'GBP' });
                                    rowCols[2].textContent = element.MonthlyPrincipal.toLocaleString('en-UK', { style: 'currency', currency: 'GBP' });
                                    rowCols[3].textContent = element.MonthlyInterest.toLocaleString('en-UK', { style: 'currency', currency: 'GBP' });
                                    rowCols[4].textContent = element.TotalInterest.toLocaleString('en-UK', { style: 'currency', currency: 'GBP' });
                                    rowCols[5].textContent = element.Balance.toLocaleString('en-UK', { style: 'currency', currency: 'GBP' });
                            
                                    tableBody.appendChild(tableRow);
                                });
                            }
                        
                    

The Code is structured into seven functions.

getValues

This functions retrieves the user input from the page with getElementById, and converts the inputs to a number type. The inputs are validated with the validateInput function, and if they are valid, the getPayments and displayResults functions are executed.

getPayments

This is the main function of the app, which takes in three arguments that are the three inputs from the user. The function creates an object for the loan which has five parameters to store the required information. The '.Payments' parameter is an array of an additional object which is the payment information for each individual month, and in turn has six parameters itself. The function uses a 'for loop' to loop over the term period and make the necessary function calls to calculate the required loan information.

calcPayment

This function calculates the regular monthly payment amount and used the 'Math.pow' function.

calcMonthlyRate

This function calculated the monthly rate from the annual interest rate.

calcMonthlyInterest

This function calculates the interest in a given month.

validateInput

This function takes in three parameters which are the user inputs. The function uses 'if statements' to determine if the values are appropriate. If the user inputs are found to be problematic, the function returns a boolean false value.

displayResults

displayResults takes in one parameter, a results object. The tables where the results are to be inserted and a template structure of the HTML rows are retrieved from the document using getElementById. A 'foreach' loop iterates over each element in the '.Payments' parameter of the results object, and inserts the corresponding results to the table, using the appendChild function.