PageRenderTime 56ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/js/mortgagecalc.js

https://bitbucket.org/kennethgeris/centurion-homes
JavaScript | 421 lines | 341 code | 59 blank | 21 comment | 138 complexity | eedc3d44653a16f0985a38d9e1e99f16 MD5 | raw file
  1. pd = 'paydata'; /* SAVING CALCULATOR DATA */
  2. numDays = 60; /* DAYS UNTIL COOKIE EXPIRES (EG. 183 DAYS = 6 MONTHS) */
  3. /* FUNCTION THAT ADDS COMMAS TO THE CURRENCY VALUE (i.e. $1000000.00 -> $1,000,000.00) */
  4. function addCommas(currencyValue) {
  5. currencyValue = "" + currencyValue;
  6. var dollars = 0;
  7. var cents = "";
  8. if (currencyValue.indexOf(",") != -1) {
  9. return currencyValue;
  10. } else if (currencyValue.indexOf(".") != -1) {
  11. dollars = currencyValue.substring(0, currencyValue.indexOf("."));
  12. cents = currencyValue.substring(currencyValue.indexOf("."), currencyValue.length);
  13. } else if (currencyValue > 0) {
  14. dollars = currencyValue;
  15. } else {
  16. return currencyValue;
  17. }
  18. var returnValue = "";
  19. for (var i = 1; i <= dollars.length; i++) {
  20. if (i % 3 == 1 && i != 1) {
  21. returnValue = "," + returnValue;
  22. }
  23. returnValue = dollars.charAt(dollars.length - i) + returnValue;
  24. }
  25. returnValue += cents;
  26. return returnValue;
  27. }
  28. /* THE FOLLOWING TWO FUNCTIONS CHECK THAT ALL NUMERIC VALUES ARE REAL NUMBER AND REMOVE DOUBLE DECIMALS */
  29. function check(a)
  30. {
  31. var pest = 0;
  32. var b = "";
  33. for (i = 0; i <= a.length; i++)
  34. {
  35. var u = a.charAt(i);
  36. if ((u >= "0" && u <= "9") || u == ".")
  37. {
  38. if (u == ".") {
  39. var pest = pest + 1;
  40. if (pest == 2) {
  41. break;
  42. }
  43. }
  44. var b = b + u;
  45. }
  46. }
  47. return b;
  48. }
  49. function doSum(a) {
  50. a.value = check(a.value);
  51. }
  52. /* TESTS VERSIONS FOR WHICH WILL SUPPORT POP UP WINDOWS */
  53. function versTest()
  54. {
  55. var one = '';
  56. var two = '';
  57. if (
  58. (navigator.appName.substring(0, 8) == "Netscape" && (navigator.appVersion.substring(0, 3) == "3.0" || navigator.appVersion.substring(0, 3) == "4.0")))
  59. {
  60. var one = 'true';
  61. }
  62. if (
  63. (navigator.appName.substring(0, 9) == "Microsoft" && navigator.appVersion.substring(0, 3) == "3.0" && navigator.appVersion.indexOf("Macintosh") >= 0))
  64. {
  65. var two = 'true';
  66. }
  67. if (one == 'true' || two == 'true' ||
  68. (navigator.appName.substring(0, 9) == "Microsoft" && navigator.appVersion.indexOf("MSIE 3.0") >= 0 &&
  69. navigator.appVersion.indexOf("Windows 3.1") >= 0)
  70. )
  71. {
  72. return true;
  73. } else
  74. {
  75. return false;
  76. }
  77. }
  78. /* TESTS IF VERSION IS MSIE 3.0 FOR MAC */
  79. function msTest()
  80. {
  81. if (navigator.appName.substring(0, 9) == "Microsoft" && (navigator.appVersion.substring(0, 3) == "3.0" && navigator.appVersion.indexOf("Macintosh") >= 0))
  82. {
  83. return true;
  84. } else
  85. {
  86. return false;
  87. }
  88. }
  89. function nineTest()
  90. {
  91. if (navigator.appName.substring(0, 9) == "Microsoft" && (navigator.appVersion.substring(0, 3) == "3.0" || navigator.appVersion.indexOf("MSIE 3.0") >= 0) && (navigator.appVersion.indexOf("Macintosh") == -1 || navigator.appVersion.indexOf("Windows 3.1") == -1)
  92. )
  93. {
  94. return true;
  95. } else
  96. {
  97. return false;
  98. }
  99. }
  100. /* OPENS POP UP WINDOW TO DISPLAY VALIDATION MESSAGES IN NETSCAPE 3.0 AND 4.0 */
  101. function fixpro(n, q)
  102. {
  103. if (versTest() == true) {
  104. if (msTest() == true) {
  105. var winNam = '';
  106. } else {
  107. var slash = location.href.lastIndexOf("/") + 1;
  108. var filNam = location.href.substring(0, slash);
  109. var winNam = filNam + 'empty.html';
  110. }
  111. fix = window.open(winNam, 'FIX', 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=300,height=100');
  112. if (navigator.appName.substring(0, 8) == "Netscape") {
  113. fix.focus();
  114. }
  115. fix.document.write('<html><head><title>Calculators</title>');
  116. fix.document.write('</head><body bgcolor=ffffff><form name=fixer>');
  117. fix.document.write('<font size=2 face="Arial, Helvetica" color=306798>' + n + '</font><p><font size=2 face="Arial, Helvetica">' + q + '<p>');
  118. fix.document.write('<center><input type=button value=OK onClick=self.close()>');
  119. fix.document.write('</center></form></body></html>');
  120. fix.document.close();
  121. } else {
  122. alert(n + '\n' + q)
  123. }
  124. }
  125. /* FUNCTION CONFIRMS THAT THE VALUE ENTERED INTO A FIELD FALLS WITHIN THE PRE-DETERMINED MINIMUM AND MAXIMUM VALUES, AND DISPLAYS AN ERROR MESSAGE WITH THE ALLOWABLE NUMERIC RANGE FOR THE FIELD DATA IN A POP UP VALIDATION WINDOW */
  126. function checkNumber(quest, input, min, max, msg)
  127. {
  128. var str = input.value;
  129. for (var i = 0; i < str.length; i++) {
  130. var ch = str.substring(i, i + 1)
  131. if ((ch < "0" || "9" < ch) && ch != '.') {
  132. alert(msg);
  133. return false;
  134. }
  135. }
  136. if (input.value != "")
  137. {
  138. var num = 0 + str
  139. if (num < min || max < num) {
  140. var sendn = "Question " + quest + ": (" + msg + ")";
  141. var sendq = "You have entered " + input.value + ". Please enter a number between " + min + " and " + max + ".";
  142. fixpro(sendn, sendq);
  143. return false;
  144. }
  145. input.value = str;
  146. return true;
  147. }
  148. }
  149. /* CALLS UPON THE FUNCTIONS TO DETERMINE IF THE NUMBERS ENTERED ARE VALID AND TO CALCULATE THE RESULTS OF THE ENTERED DATA FOR EXAMPLE - MORTGAGE PAYMENT, GDS AND TDS RATIOS, AND LOAN TO VALUE. THIS FUNCTION IS EXECUTED EVERYTIME A VALUE IS CHANGED IN A FIELD */
  150. function computeField(quest, input, min, max, msage)
  151. {
  152. doSum(input);
  153. return (checkNumber(quest, input, min, max, msage));
  154. }
  155. /* RETURNS THE SELECTED INDEX VALUE OF SELECT LISTS IN THE CALCULATOR TO BE USED IN CALCULATIONS */
  156. function getIndex(n) {
  157. return n.selectedIndex;
  158. }
  159. function calcRdefine(intrate, compound, freq) {
  160. return Math.pow((1.0 + ((intrate / 100) / compound)), (compound / freq)) - 1.0;
  161. }
  162. function calcBal(mortgage, intrate, compound, freq, payment, term) {
  163. rdefine = calcRdefine(intrate, compound, freq);
  164. return (mortgage * (Math.pow((1.0 + rdefine), (term)))) - ((payment * ((Math.pow((1.0 + rdefine), (term))) - 1.0)) / rdefine);
  165. }
  166. /* ROUNDS OFF MONETARY NUMBERS TO TWO DECIMALS (PENNIES) */
  167. function roundPen(n)
  168. {
  169. if (n > 0) {
  170. pennies = n * 100;
  171. pennies = Math.round(pennies);
  172. strPennies = "" + pennies;
  173. len = strPennies.length;
  174. return strPennies.substring(0, len - 2) + "." + strPennies.substring(len - 2, len);
  175. } else
  176. return 0;
  177. }
  178. /* THIS FUNCTION CALCULATES THE LOAN TO VALUE RATIO */
  179. function LTVcalc(MORTGAGE, MORTGAGE2, APPRAISE) {
  180. return (MORTGAGE / APPRAISE) + (MORTGAGE2 / APPRAISE);
  181. }
  182. function Ratios(PAY1, PAY2, HEAT, TAX, DEBT, INCOME) {
  183. return (PAY1 / INCOME) + (PAY2 / INCOME) + (HEAT / INCOME) + (TAX / INCOME) + (DEBT / INCOME);
  184. }
  185. /* THIS FUNCTION CALCULATES THE MONTHLY MORTGAGE PAYMENT BASED ON THE USER'S INPUT */
  186. function calcPay(MORTGAGE, AMORTYEARS, INRATE, COMPOUND, FREQ) {
  187. var compound = COMPOUND / 12;
  188. var monTime = (AMORTYEARS * 12);
  189. var RATE = (INRATE * 1.0) / 100;
  190. var yrRate = RATE / COMPOUND;
  191. var rdefine = Math.pow((1.0 + yrRate), compound) - 1.0;
  192. var PAYMENT = (MORTGAGE * rdefine * (Math.pow((1.0 + rdefine), monTime))) / ((Math.pow((1.0 + rdefine), monTime)) - 1.0);
  193. if (FREQ == 12) {
  194. return PAYMENT;
  195. }
  196. if (FREQ == 26) {
  197. return PAYMENT / 2.0;
  198. }
  199. if (FREQ == 52) {
  200. return PAYMENT / 4.0;
  201. }
  202. if (FREQ == 24) {
  203. var compound2 = COMPOUND / FREQ;
  204. var monTime2 = (AMORTYEARS * FREQ);
  205. var rdefine2 = Math.pow((1.0 + yrRate), compound2) - 1.0;
  206. var PAYMENT2 = (MORTGAGE * rdefine2 * (Math.pow((1.0 + rdefine2), monTime2))) / ((Math.pow((1.0 + rdefine2), monTime2)) - 1.0);
  207. return PAYMENT2;
  208. }
  209. }
  210. function retTerm(n) {
  211. if (n == 0) {
  212. return 0;
  213. }
  214. if (n == 1) {
  215. return 6;
  216. }
  217. if (n == 2) {
  218. return 12;
  219. }
  220. if (n == 3) {
  221. return 24;
  222. }
  223. if (n == 4) {
  224. return 36;
  225. }
  226. if (n == 5) {
  227. return 60;
  228. }
  229. if (n == 6) {
  230. return 84;
  231. }
  232. if (n == 7) {
  233. return 120;
  234. }
  235. }
  236. function retFreq(n) {
  237. if (n == 0) {
  238. return 0;
  239. }
  240. if (n == 1) {
  241. return 12;
  242. }
  243. if (n == 2) {
  244. return 24;
  245. }
  246. if (n == 3) {
  247. return 26;
  248. }
  249. if (n == 4) {
  250. return 52;
  251. }
  252. }
  253. function calcTotal(MORTGAGE, LTV) {
  254. if (LTV > .75 && LTV <= .80) {
  255. return MORTGAGE * 1.0125;
  256. }
  257. if (LTV > .80 && LTV <= .85) {
  258. return MORTGAGE * 1.02;
  259. }
  260. if (LTV > .80) {
  261. return MORTGAGE * 1.025;
  262. }
  263. if (LTV <= .75) {
  264. return MORTGAGE
  265. }
  266. }
  267. /* SAVES COOKIE CONTAINING DATA TO BE USED IN AMORTIZATION SCHEDULE */
  268. function quickCook(MTGAMT, AMORTYEARS, RATE, TERM, FREQ, WHATYEAR)
  269. {
  270. if (WHATYEAR && WHATYEAR == -1) {
  271. var timeKindA = 0;
  272. } else {
  273. WHATYEAR = 0;
  274. var timeKindA = 1;
  275. }
  276. var AMORTPMT = calcPay(MTGAMT, AMORTYEARS, RATE, 2, FREQ);
  277. var intrate = RATE / 100;
  278. var INTFACTOR = Math.pow((1 + intrate / 2), (2 / FREQ)) - 1;
  279. var expire = new Date();
  280. expire.setTime(expire.getTime() + (numDays * 24 * 3600000));/* 2 MONTHS */
  281. var pdData = " ";
  282. pdData = pdData + '`' + MTGAMT + '`' + AMORTPMT + '`' + INTFACTOR + '`' + FREQ + '`' + ((AMORTYEARS * FREQ)) + '`' + 0 + '`' + 0 + '`' + (TERM / 12) + '`' + timeKindA + '`' + RATE * 1.0 / 100 + '`' + 0 + '`' + WHATYEAR + '`' + 0 + '`' + 0 + '`' + 0 + '`' + 0 + '`' + 0;
  283. document.cookie = pd + "=" + escape(pdData) + "; expires=" + expire.toGMTString() + "; path=/";
  284. }
  285. /* VALIDATES ALL THE FIELDS AND CALCULATES VALUES TO BE ENTERED INTO THE TEXT BOXES AT THE BOTTOM OF THE PAGE WHEN THE USER CLICKS ON COMPUTE OR COMPUTE AMORTIZATION */
  286. function compute(form, year) {
  287. term = retTerm(document.paycalc.desterm.selectedIndex);
  288. freq = retFreq(document.paycalc.PFREQ.selectedIndex);
  289. amortyears = document.paycalc.NAMORTYEARS.value;
  290. mortgage = document.paycalc.mortamt.value;
  291. intrate = document.paycalc.rate.value;
  292. var payment = calcPay(mortgage, amortyears, intrate, 2, freq);
  293. var intFact = Math.pow((1 + (intrate / 100) / 2), (2 / freq)) - 1;
  294. // need to determin the number of payments so we can correctly determin the Amortization period
  295. // and the remaing balance
  296. var principalBal = mortgage;
  297. var aYear = 0;
  298. var annualCount = 1;
  299. for (payAdd = 1; principalBal > 0; payAdd++) {
  300. var checkLump = 0;
  301. var printPayments = Math.ceil(1 / freq);//Expressed in Years
  302. var printYear = printPayments * freq;//Expressed in Payments
  303. //SET FLAG IF THIS PAYMENT IS AN ANNIVERSARY
  304. if ((payAdd - 1) / Math.floor(freq) == annualCount) {
  305. var aYear = 1;
  306. }
  307. //INTEREST AND PRINCIPAL PAYMENT
  308. var interestPayment = roundPen(principalBal * intFact) * 1.0;
  309. var principalPayment = roundPen(payment - interestPayment) * 1.0;
  310. var checkBal = (principalPayment > principalBal) ? principalBal : principalPayment;
  311. var principalBal = roundPen(principalBal - checkBal) * 1.0;
  312. //LUMPSUM PAYMENT IF REQUESTED
  313. if (aYear == 1 && 0 >= annualCount) {
  314. var checkLump = (lumpAmt > principalBal) ? principalBal : lumpAmt;
  315. var principalBal = roundPen(principalBal - checkLump) * 1.0;
  316. }
  317. //ELIMINATES BALANCE (ADDS IT TO PRINCIPAL PAID) IF LESS THAN HALF
  318. if (principalBal < ((interestPayment + principalPayment) / 2)) {
  319. var checkBal = checkBal + principalBal;
  320. var principalBal = 0;
  321. }
  322. //RESETS THE ANNIVERSARY
  323. if (aYear == 1) {
  324. var annualCount = annualCount + 1;
  325. var aYear = 0;
  326. }
  327. }
  328. var totalYears = (payAdd - 1) / freq;
  329. var oForm = document.forms["paycalc"];
  330. oForm.mainpay.value = '$' + addCommas(roundPen(payment));
  331. quickCook(mortgage, amortyears, intrate, term, freq, year);
  332. return true;
  333. }
  334. /* OPENS WINDOW USED TO DISPLAY HELP MESSAGES WHEN THE USER CLICKS ON A HELP BUTTON. THE HELP MESSAGE DISPLAYED IS DETERMINED IN THE ARRAY WHICH IS REFERENCED ACCORDING TO THE HELP BUTTON WHICH WAS CLICKED */
  335. function winopen(name)
  336. {
  337. var linkit = "help/" + name;
  338. if (versTest() == true || nineTest() == true) {
  339. qc = window.open(linkit, 'helpscreen', 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=250,height=180');
  340. if (navigator.appName.substring(0, 8) == "Netscape")
  341. {
  342. qc.focus();
  343. }
  344. } else {
  345. location.href = linkit;
  346. }
  347. }
  348. function StringArray(n)
  349. {
  350. this.length = n;
  351. for (var i = 1; i <= n; i++)
  352. this[i] = ''
  353. return this
  354. }
  355. function payBal()
  356. {
  357. if (navigator.appVersion.substring(0, 3) == 2.0 && navigator.appName.substring(0, 8) == "Netscape" && navigator.appVersion.indexOf("Macintosh") >= 0) {
  358. setTimeout("compute(document.forms[0])", 200);
  359. } else {
  360. compute(document.forms[0]);
  361. }
  362. }