Price of property * $ Down payment % Loan Amount * Annual interest rate * % Amortization Period Annual Monthly Number of years * Annual property taxes $ Annual hazard insurance $ Monthly private mortgage insurance $ Calculate Reset document.addEventListener('DOMContentLoaded', function() { (function($) { $('input[name="property_price"],input[name="loan_amount"]').val($('.fwre-property-price').data('price')); $('.mod-fwre-mcalculator input[name="property_price"]').keyup(fwmortgage_loan_standalone_calculation); $('.mod-fwre-mcalculator input[name="down_payment"]').keyup(fwmortgage_loan_standalone_calculation); $('.calculator-block-button button.btn-primary').click(function() { var form = this.form; var fields = ['property_price', 'loan_amount', 'interest_rate', 'number_of_years']; for (var i = 0; fields.length > i; i++) { if (form[fields[i]].value.replace(/\s+/, '') == '' || parseInt(form[fields[i]].value) == 0) { form[fields[i]].focus(); alert('Required fields are not filled in properly'); return false; } } fwre_lightbox($(this)); var $link = $(this).closest('.calculator-block-button').find('a'); if (!$link.length) { $link = $('', { 'style': 'display:none', 'href': 'javascript:', 'class': 'fwre-lightbox', 'data-type': 'func', 'data-func': 'fwre_calc_table()' }); $(this).after($link); } $link.click(); }); window.fwre_calc_table = function() { var form = $('.mod-fwre-mcalculator form')[0]; /* gathering data */ var property_price = check_numeric_value(form.property_price.value); var down_payment = check_numeric_value(form.down_payment.value); var loan_amount = check_numeric_value(form.loan_amount.value); var interest_rate = check_numeric_value(form.interest_rate.value); var number_of_years = check_numeric_value(form.number_of_years.value); /* making calculations */ if (down_payment > 100) { down_payment = 100; form.down_payment.value = 100; } if (property_price > 0) if (down_payment > 0) loan_amount = Math.round(property_price * (100-down_payment)) / 100; else loan_amount = property_price; else if (loan_amount > 0) if (down_payment > 0) property_price = Math.round(loan_amount / (100-down_payment)) / 100; else property_price = loan_amount; var end_date = date('M') + ', ' + (date('Y') * 1 + number_of_years * 1); var amortization_schedule = form.amortization_schedule.value; if (amortization_schedule == '1') { var qty_payments = number_of_years; var rate = interest_rate/100; var property_taxes = 0; if (form.annual_property_taxes) property_taxes = Math.round(check_numeric_value(form.annual_property_taxes.value) * 100) /100; var hazard_insurance = 0; if (form.annual_hazard_insurance) hazard_insurance = Math.round(check_numeric_value(form.annual_hazard_insurance.value) * 100) /100; var private_mortgage_insurance = 0; if (form.monthly_private_mortgage_insurance) private_mortgage_insurance = Math.round(check_numeric_value(form.monthly_private_mortgage_insurance.value) * 12 * 100) /100; } else { var qty_payments = number_of_years * 12; var rate = interest_rate/12/100; var property_taxes = 0; if (form.annual_property_taxes) property_taxes = Math.round(check_numeric_value(form.annual_property_taxes.value) /12 * 100) /100; var hazard_insurance = 0; if (form.annual_hazard_insurance) hazard_insurance = Math.round(check_numeric_value(form.annual_hazard_insurance.value) /12 * 100) /100; var private_mortgage_insurance = 0; if (form.monthly_private_mortgage_insurance) private_mortgage_insurance = Math.round(check_numeric_value(form.monthly_private_mortgage_insurance.value) * 100) /100; } var payment = Math.round(loan_amount * rate / (1 - Math.pow((1 + rate), (-qty_payments))) * 100) /100; var payment_total = payment + property_taxes + hazard_insurance + private_mortgage_insurance; var all_payments = payment_total * qty_payments; /* drawing result */ var $report = $('', { 'id': 'fwrealestate-mortgage-wrapper', 'class': 'request-info-wrapper fwcss' }); $('#fwre-lightbox-body').append($report); $report.html('\ \ \ Loan Information\ \ \ Price of property:\ $'+number_format(property_price, 2, '.', ',')+'\ \ \ Down payment ('+down_payment+'%):\ $'+number_format(property_price - loan_amount, 2, '.', ',')+'\ \ \ Loan Amount:\ $'+number_format(loan_amount, 2, '.', ',')+'\ \ \ Interest rate:\ '+number_format(interest_rate, 3, '.', ',')+'%\ \ \ Loan term:\ '+number_of_years+' Years\ \ \ Payoff date:\ '+end_date+'\ \ \ You have '+qty_payments+' payment periods that total:\ $'+number_format(all_payments, 2, '.', ',')+'\ \ \ \ \ Payment Information\ \ \ Principal and interest payment:\ $'+number_format(payment, 2, '.', ',')+'\ \ \ Property Taxes:\ $'+number_format(property_taxes, 2, '.', ',')+'\ \ \ Hazard insurance:\ $'+number_format(hazard_insurance, 2, '.', ',')+'\ \ \ Private Mortgage Insurance:\ $'+number_format(private_mortgage_insurance, 2, '.', ',')+'\ \ \ Total payments:\ $'+number_format(payment_total, 2, '.', ',')+'\ \ \ \ \ Amortization Schedule'); /* adding a table */ var $table = $('', { 'class': 'table table-striped' }); var $row = $(''); var $col = $(''); $row.append($col); $col.html('Years'); if (amortization_schedule != '1') { var $col = $(''); $row.append($col); $col.html('Months'); } var $col = $('th'); $row.append($col); $col.html('Beginning Balance'); var $col = $('th'); $row.append($col); $col.html('Interest'); var col = $('th'); $row.append($col); $col.html('Payment'); var $col = $('th'); $row.append($col); $col.html('Ending Balance'); $table.append($row); var current_year = 1; var current_month = 0; var balance = loan_amount; var total_interest = 0; var total_payment = 0; for (var i = 0; i < qty_payments; i++) { var $row = $(''); if (amortization_schedule != '1') { current_month++; if (current_month == 13) { current_month = 1; current_year++; } var $col = $(''); $col.addClass('fwrealestate-amount'); $col.html(current_year); $row.append($col); var $col = $('', { 'class': 'fwrealestate-amount' }); $col.html(current_month); $row.append($col); } else { var $col = $('', { 'class': 'fwrealestate-amount' }); $col.html(i + 1); $row.append($col); } var $col = $('', { 'class': 'fwrealestate-amount' }); $col.html('$'+number_format(balance, 0, '.', ',')+''); $row.append($col); var sum_interest = 0; var sum_payment = 0; var start_balance = balance; sum_interest = balance * rate; balance -= payment - sum_interest; sum_payment = payment; if (i + 1 == qty_payments) { sum_payment = start_balance; balance = 0; } var $col = $('', { 'class': 'fwrealestate-amount' }); $col.html('$'+number_format(sum_interest, 2, '.', ',')+''); $row.append($col); var $col = $('', { 'class': 'fwrealestate-amount' }); $col.html('$'+number_format(sum_payment, 2, '.', ',')+''); $row.append($col); var $col = $('', { 'class': 'fwrealestate-amount' }); $col.html('$'+number_format(balance, 0, '.', ',')+''); $row.append($col); $table.append($row); } $report.append($table); } window.check_numeric_value = function(val) { if (isNaN(val)) return 0 else return val; } window.print_loan_info = function() { $('#fwrealestate-mortgage-wrapper').printElement({ overrideElementCSS:[ '/components/com_fwrealestate/assets/css/bootstrap.css', '/components/com_fwrealestate/assets/css/fwre-design-styles.css', '/components/com_fwrealestate/assets/css/all.min.css', ] }); } function fwmortgage_loan_standalone_calculation() { var $property_price = $('.mod-fwre-mcalculator input[name="property_price"]'); var $down_payment = $('.mod-fwre-mcalculator input[name="down_payment"]'); var $loan_amount = $('.mod-fwre-mcalculator input[name="loan_amount"]'); var property_price = check_numeric_value($property_price.val()); var down_payment = check_numeric_value($down_payment.val()); if (down_payment > 100) { down_payment = 100; $down_payment.val(100); } if (property_price > 0) if (down_payment > 0) $loan_amount.val(Math.round(property_price * (100-down_payment)) / 100); else $loan_amount.val(property_price); else $loan_amount.val(0); } })(jQuery); }); function date(format, timestamp) { // http://kevin.vanzonneveld.net // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com) // + parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html) // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + improved by: MeEtc (http://yass.meetcweb.com) // + improved by: Brad Touesnard // + improved by: Tim Wiel // + improved by: Bryan Elliott // + improved by: Brett Zamir (http://brett-zamir.me) // + improved by: David Randall // + input by: Brett Zamir (http://brett-zamir.me) // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + improved by: Brett Zamir (http://brett-zamir.me) // + improved by: Brett Zamir (http://brett-zamir.me) // + improved by: Theriault // + derived from: gettimeofday // + input by: majak // + bugfixed by: majak // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + input by: Alex // + bugfixed by: Brett Zamir (http://brett-zamir.me) // + improved by: Theriault // + improved by: Brett Zamir (http://brett-zamir.me) // + improved by: Theriault // + improved by: Thomas Beaucourt (http://www.webapp.fr) // + improved by: JT // + improved by: Theriault // + improved by: Rafał Kukawski (http://blog.kukawski.pl) var that = this, jsdate, f, formatChr = /\\?([a-z])/gi, formatChrCb, // Keep this here (works, but for code commented-out // below for file size reasons) //, tal= [], _pad = function (n, c) { if ((n = n + "").length < c) { return new Array((++c) - n.length).join("0") + n; } else { return n; } }, txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], txt_ordin = { 1: "st", 2: "nd", 3: "rd", 21: "st", 22: "nd", 23: "rd", 31: "st" }; formatChrCb = function (t, s) { return f[t] ? f[t]() : s; }; f = { // Day d: function () { // Day of month w/leading 0; 01..31 return _pad(f.j(), 2); }, D: function () { // Shorthand day name; Mon...Sun return f.l().slice(0, 3); }, j: function () { // Day of month; 1..31 return jsdate.getDate(); }, l: function () { // Full day name; Monday...Sunday return txt_words[f.w()] + 'day'; }, N: function () { // ISO-8601 day of week; 1[Mon]..7[Sun] return f.w() || 7; }, S: function () { // Ordinal suffix for day of month; st, nd, rd, th return txt_ordin[f.j()] || 'th'; }, w: function () { // Day of week; 0[Sun]..6[Sat] return jsdate.getDay(); }, z: function () { // Day of year; 0..365 var a = new Date(f.Y(), f.n() - 1, f.j()), b = new Date(f.Y(), 0, 1); return Math.round((a - b) / 864e5) + 1; }, // Week W: function () { // ISO-8601 week number var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3), b = new Date(a.getFullYear(), 0, 4); return 1 + Math.round((a - b) / 864e5 / 7); }, // Month F: function () { // Full month name; January...December return txt_words[6 + f.n()]; }, m: function () { // Month w/leading 0; 01...12 return _pad(f.n(), 2); }, M: function () { // Shorthand month name; Jan...Dec return f.F().slice(0, 3); }, n: function () { // Month; 1...12 return jsdate.getMonth() + 1; }, t: function () { // Days in month; 28...31 return (new Date(f.Y(), f.n(), 0)).getDate(); }, // Year L: function () { // Is leap year?; 0 or 1 var y = f.Y(), a = y & 3, b = y % 4e2, c = y % 1e2; return 0 + (!a && (c || !b)); }, o: function () { // ISO-8601 year var n = f.n(), W = f.W(), Y = f.Y(); return Y + (n === 12 && W < 9 ? -1 : n === 1 && W > 9); }, Y: function () { // Full year; e.g. 1980...2010 return jsdate.getFullYear(); }, y: function () { // Last two digits of year; 00...99 return (f.Y() + "").slice(-2); }, // Time a: function () { // am or pm return jsdate.getHours() > 11 ? "pm" : "am"; }, A: function () { // AM or PM return f.a().toUpperCase(); }, B: function () { // Swatch Internet time; 000..999 var H = jsdate.getUTCHours() * 36e2, // Hours i = jsdate.getUTCMinutes() * 60, // Minutes s = jsdate.getUTCSeconds(); // Seconds return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3); }, g: function () { // 12-Hours; 1..12 return f.G() % 12 || 12; }, G: function () { // 24-Hours; 0..23 return jsdate.getHours(); }, h: function () { // 12-Hours w/leading 0; 01..12 return _pad(f.g(), 2); }, H: function () { // 24-Hours w/leading 0; 00..23 return _pad(f.G(), 2); }, i: function () { // Minutes w/leading 0; 00..59 return _pad(jsdate.getMinutes(), 2); }, s: function () { // Seconds w/leading 0; 00..59 return _pad(jsdate.getSeconds(), 2); }, u: function () { // Microseconds; 000000-999000 return _pad(jsdate.getMilliseconds() * 1000, 6); }, // Timezone e: function () { // Timezone identifier; e.g. Atlantic/Azores, ... return 'UTC'; }, I: function () { // DST observed?; 0 or 1 // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC. // If they are not equal, then DST is observed. var a = new Date(f.Y(), 0), // Jan 1 c = Date.UTC(f.Y(), 0), // Jan 1 UTC b = new Date(f.Y(), 6), // Jul 1 d = Date.UTC(f.Y(), 6); // Jul 1 UTC return 0 + ((a - c) !== (b - d)); }, O: function () { // Difference to GMT in hour format; e.g. +0200 var a = jsdate.getTimezoneOffset(); return (a > 0 ? "-" : "+") + _pad(Math.abs(a / 60 * 100), 4); }, P: function () { // Difference to GMT w/colon; e.g. +02:00 var O = f.O(); return (O.substr(0, 3) + ":" + O.substr(3, 2)); }, T: function () { // Timezone abbreviation; e.g. EST, MDT, ... return 'UTC'; }, Z: function () { // Timezone offset in seconds (-43200...50400) return -jsdate.getTimezoneOffset() * 60; }, // Full Date/Time c: function () { // ISO-8601 date. return 'Y-m-d\\Th:i:sP'.replace(formatChr, formatChrCb); }, r: function () { // RFC 2822 return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb); }, U: function () { // Seconds since UNIX epoch return jsdate.getTime() / 1000 | 0; } }; this.date = function (format, timestamp) { that = this; jsdate = ( (typeof timestamp === 'undefined') ? new Date() : // Not provided (timestamp instanceof Date) ? new Date(timestamp) : // JS Date() new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int) ); return format.replace(formatChr, formatChrCb); }; return this.date(format, timestamp); } function number_format(number, decimals, dec_point, thousands_sep) { // http://kevin.vanzonneveld.net // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + bugfix by: Michael White (http://getsprink.com) // + bugfix by: Benjamin Lupton // + bugfix by: Allan Jensen (http://www.winternet.no) // + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) // + bugfix by: Howard Yeend // + revised by: Luke Smith (http://lucassmith.name) // + bugfix by: Diogo Resende // + bugfix by: Rival // + input by: Kheang Hok Chin (http://www.distantia.ca/) // + improved by: davook // + improved by: Brett Zamir (http://brett-zamir.me) // + input by: Jay Klehr // + improved by: Brett Zamir (http://brett-zamir.me) // + input by: Amir Habibi (http://www.residence-mixte.com/) // + bugfix by: Brett Zamir (http://brett-zamir.me) // + improved by: Theriault var n = !isFinite(+number) ? 0 : +number, prec = !isFinite(+decimals) ? 0 : Math.abs(decimals), sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, dec = (typeof dec_point === 'undefined') ? '.' : dec_point, s = '', toFixedFix = function (n, prec) { var k = Math.pow(10, prec); return '' + Math.round(n * k) / k; }; // Fix for IE parseFloat(0.55).toFixed(0) = 0; s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.'); if (s[0].length > 3) { s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep); } if ((s[1] || '').length < prec) { s[1] = s[1] || ''; s[1] += new Array(prec - s[1].length + 1).join('0'); } return s.join(dec); }