1/** 2 * Get this, they created that JavaScript while the plugin was having problems in 2015. That JavaScript performs 3 * ALL of the calculator functions so technically, the mortgage calculator plugin is not actually used. If I build out 4 * an identical form and drop it in the JavaScript is the thing that handles everything. The plugin never actually sees 5 * the light of day aside from outputting the form on the front end. 6 * 7 * Their plan was to remove the JS when the plugin was working again but they just never did. 8 * 9 * TL;DR The responsive mortgage calculator plugin has only ever been used to output a form on the front end and we've 10 * just been overriding the functionality with JS because no one ever removed the "temporary" fix from 5 years ago. 11 * 12 * https://artscience.atlassian.net/browse/IC-544 13 * https://bitbucket.org/artscience/ixact-wam-wordpress/commits/ac68419128e428e9f12f43a4624ec0ee49339526 14 */ 15jQuery(document).ready(function() { 16 17 // Get the results divs. 18 detailsDiv = jQuery('#lidd_mc_details'); 19 resultDiv = jQuery('#lidd_mc_results'); 20 summaryDiv = jQuery('#lidd_mc_summary'); 21 22 jQuery(".lidd_mc_form").submit(function(event) { 23 24 // Prevent the form from being submitted. 25 event.preventDefault(); 26 27 // Formatting function for outputting numbers with commas. 28 function numberWithCommas(x) { 29 return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); 30 } 31 32 // Formatting function for currency codes 33 function validateCurrencyCode(code) { 34 return code.replace(/[^A-Za-z]/, ""); 35 } 36 37 // Initialize variables. 38 var error = false; // Marker. Assume there is an error. 39 var period; // Store the payment period. 40 var showSummary = false; // Record whether the summary is displayed or not. 41 42 // Get variables. 43 var ta = jQuery('#lidd_mc_total_amount').val(); 44 var dp = jQuery('#lidd_mc_down_payment').val(); 45 var ir = jQuery('#lidd_mc_interest_rate').val(); 46 var am = jQuery('#lidd_mc_amortization_period').val(); 47 var pp = jQuery('#lidd_mc_payment_period option:selected').val(); 48 var cp = jQuery('#lidd_mc_compounding_period').val(); 49 var currency = jQuery('#lidd_mc_currency').val(); 50 var currency_code = jQuery('#lidd_mc_currency_code').val(); 51 52 // Get the error reporting spans. 53 var ta_error = jQuery('#lidd_mc_total_amount-error'); 54 var dp_error = jQuery('#lidd_mc_down_payment-error'); 55 var ir_error = jQuery('#lidd_mc_interest_rate-error'); 56 var am_error = jQuery('#lidd_mc_amortization_period-error'); 57 58 // Make sure the results divs are in their default states. 59 detailsDiv.hide(); 60 resultDiv.html(''); 61 summaryDiv.html(''); 62 63 // ********************** // 64 // ***** VALIDATION ***** // 65 66 // A function to trigger an error. 67 function triggerError(element, message) { 68 error = true; 69 element.text(message); 70 element.addClass('lidd_mc_error'); 71 } 72 73 // A function to remove an error. 74 function removeError(element) { 75 element.text(''); 76 element.removeClass('lidd_mc_error'); 77 } 78 79 // Make sure total amount * 100 is an integer, or round it to one. 80 if (jQuery.isNumeric(+ta) && ta > 0) { 81 ta = Math.abs(Math.round((+ta) * 100) / 100); 82 removeError(ta_error); 83 } else { 84 triggerError(ta_error, 'Please enter the total amount of the mortgage.'); 85 } 86 // Down payment. If it is set, it must be less than the total amount. 87 if (+dp == 0 || (jQuery.isNumeric(+dp) && +dp < ta)) { 88 dp = Math.abs(Math.round((+dp) * 100) / 100); 89 removeError(dp_error); 90 } else { 91 triggerError(dp_error, 'Please enter a down payment amount or leave blank.'); 92 } 93 // Interest rate. Positve value less than 100%. Leaves room for loan sharks. 94 if (jQuery.isNumeric(+ir) && (+ir) < 100 && (+ir) > 0) { 95 ir = +ir; 96 removeError(ir_error); 97 } else { 98 triggerError(ir_error, 'Please enter an interest rate.'); 99 } 100 // Validate the payment period, just in case. 101 switch (pp) { 102 case '52': 103 pp = 52; 104 period = 'Weekly'; 105 break; 106 case '26': 107 pp = 26; 108 period = 'Bi-Weekly'; 109 break; 110 default: 111 pp = 12; 112 period = 'Monthly'; 113 break; 114 } 115 // Amortization period. 50 years is absurdly long, but meh... 116 if (jQuery.isNumeric(+am) && Math.abs(+am) < 50 && (+am) !== 0) { 117 // The amortization period needs to fit nicely with the payment periods if there are decimals. 118 am = Math.abs(Math.ceil((+am) * pp) / pp); 119 removeError(am_error); 120 } else { 121 triggerError(am_error, 'Please enter an amortization period.'); 122 } 123 // Compounding period 124 switch (cp) { 125 case '1': 126 cp = 1; 127 break; 128 case '2': 129 cp = 2; 130 break; 131 case '4': 132 cp = 4; 133 break; 134 case '12': 135 default: 136 cp = 12; 137 break; 138 } 139 // Currency 140 switch (currency) { 141 case 'â¬': // Euro 142 currency = 'â¬'; 143 break; 144 case '£': // Pound 145 curency = '£'; 146 break; 147 case 'Â¥': // Yen 148 currency = 'Â¥'; 149 break; 150 case '¤': // Generic 151 currency = '¤'; 152 break; 153 case '$': // Dollar 154 default: 155 currency = '$'; 156 break; 157 } 158 // Currency Code 159 if (currency_code) { 160 currency_code = validateCurrencyCode(currency_code); 161 } else { 162 currency_code = ''; 163 } 164 165 // ***** END VALIDATION ***** // 166 // ************************** // 167 168 // If there are no errors, continue with the calculation. 169 if (error === false) { 170 171 // Calculate the total amount of the loan. 172 var loan = ta - dp; 173 174 // Calculate the number of payments. This is amortization * payment period 175 var np = am * pp; 176 177 // Convert the interest rate to a decimal. (Nominal Rate) 178 var rNom = (+ir) / 100; 179 180 // Calculate the rate per payment period 181 var rPeriod = (Math.pow((1 + (rNom / +cp)), (+cp / pp))) - 1; 182 183 // Calculate the total interest rate for the duration of the loan. 184 var rFactor = Math.pow((rPeriod + 1), np); 185 186 // Calculate the payments. 187 var payment = loan * ((rPeriod * rFactor) / (rFactor - 1)); 188 189 // Set the result for output. 190 var result = numberWithCommas(parseFloat(Math.round(payment * 100) / 100).toFixed(2)); 191 192 // Summarize the data. 193 var summary = '<p>For a mortgage of <b class="lidd_mc_b">' + currency + numberWithCommas(parseInt(ta - dp).toFixed(2)) + '</b> amortized over <b class="lidd_mc_b">'; 194 // Determine the payment period in years. 195 summary += (Math.floor(am)) + '</b> years'; 196 // Check for weeks or months. 197 if ((am - Math.floor(am) > 0)) { 198 var remainder = (np > pp) ? np % pp : pp % np; 199 if (period === 'Monthly') { 200 summary += ' and <b class="lidd_mc_b">' + remainder + '</b> months'; 201 } else if (period === 'Weekly') { 202 summary += ' and <b class="lidd_mc_b">' + remainder + '</b> weeks'; 203 } else { 204 summary += ' and <b class="lidd_mc_b">' + (remainder * 2) + '</b> weeks'; 205 } 206 } 207 summary += ', your <b class="lidd_mc_b">' + period + '</b> payment is:</p>'; 208 summary += '<p>Mortgage Payment: <b class="lidd_mc_b">' + currency + result + '</b></p>'; 209 summary += '<p>Total Mortgage with Interest: <b class="lidd_mc_b">' + currency + numberWithCommas(parseFloat(Math.round((payment * np) * 100) / 100).toFixed(2)) + '</b></p>'; 210 211 if (dp > 0) { 212 summary += '<p>Total with Down Payment: <b class="lidd_mc_b">' + currency + numberWithCommas(parseFloat(dp + Math.round((payment * np) * 100) / 100).toFixed(2)) + '</b></p>'; 213 } 214 215 // Print to the messaging areas. 216 resultDiv.html('<p>Payments: <b class="lidd_mc_b">' + currency + result + ' ' + currency_code + '</b></p>'); 217 summaryDiv.html(summary); 218 219 // Show the details div. 220 detailsDiv.show(); 221 222 // Show the summary div when the result div is clicked. 223 if (document.getElementById('lidd_mc_inspector') != null) { 224 225 jQuery('#lidd_mc_inspector').click(function() { 226 if (showSummary === false) { 227 summaryDiv.show(); 228 showSummary = true; 229 } else { 230 summaryDiv.hide(); 231 showSummary = false;
232 } 233 }); 234 235 } 236 237 } 238 239 }); 240 241});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.