1<section id="section1" class="bg-light1 cred-sim">
2 <div class="container-fluid container1200">
3 <div class="col-sm-12">
4 <h3>${titleSimulateYourMortgage.getData()}</h3>
5 <form class="form-horizontal cred-sim">
6 <div class="form-group">
7 <label for="selectField" class="col-sm-6 control-label">${labelINeedTheCreditFor.getData()}</label>
8 <div class="col-sm-6">
9 <select class="form-control" id="selectField">
10 <option value="purchase">${selectPurchase.getData()}</option>
11 <option value="renovation">${selectRenovation.getData()}</option>
12 </select>
13 </div>
14 </div>
15 <div class="form-group">
16 <label class="col-sm-6 control-label">${labelCalculateMy.getData()}</label>
17 <div class="input-wrapper col-sm-6">
18 <div class="radio-button"><input type="radio" name="whattocalculate" required="" value="loanAmount" onclick="updateInputFieldLabel()"> <label>${radioLoanAmount.getData()}</label>
19
20 </div>
21 <div class="radio-button"><input type="radio" name="whattocalculate" required="" value="monthlyPayment" onclick="updateInputFieldLabel()"> <label>${radioDownPayment.getData()}</label>
22 </div>
23 </div>
24 <div class="col-sm-6"></div>
25 <div class="col-sm-6 control-label validation-message" id="radioWarningMessage" style="display:none; color:red;"></div>
26 </div>
27 <div class="form-group" id="inputFieldContainer" style="display: none;">
28 <label for="inputFieldValue" class="col-sm-6 control-label" id="inputFieldLabel">${LabelLoanTerm.getData()}</label>
29 <div class="col-sm-6">
30 <input type="text" class="form-control" id="inputFieldValue">
31 </div>
32 <div class="col-sm-6"></div>
33 <div class="col-sm-6 control-label validation-message" id="inputValueWarningMessage" style="display:none; color:red;"></div>
34 </div>
35 <div class="form-group">
36 <label for="inputFieldPeriod" class="col-sm-6 control-label">${LabelLoanTerm.getData()}</label>
37 <div class="col-sm-6">
38 <input type="text" class="form-control" id="inputFieldPeriod">
39 </div>
40 <div class="col-sm-6"></div>
41 <div class="col-sm-6 control-label validation-message" id="inputPeriodWarningMessage" style="display:none; color:red;"></div>
42 </div>
43 <div class="button-wrapper">
44 <div class="btn-default btn-lg" onclick="validateAndShowResult()">${buttonSimulate.getData()}<i class="fas fa-chevron-right"></i></div>
45 </div>
46 </form>
47 </div>
48 </div>
49</section>
50<section id="section2" class="bg-light1 cred-sim" style="display: none;">
51 <div class="container-fluid container1200">
52 <div class="col-sm-12">
53 <div class="back">
54 <a href="#" onclick="showForm()">${buttonBack.getData()}</a>
55 </div>
56 <h3 id="simulationResultTitle">${titleSimulationLoanAmount.getData()}</h3>
57 <div class="slider-container" id="sliderContainer">
58 <div class="limits">
59 <div>${rangeMinYears.getData()}</div>
60 <div>${rangeMaxYears.getData()}</div>
61 </div>
62 <input type="range" class="slider" id="rangeSlider" min="10" max="40" step="5" value="20">
63 <div class="dots">
64 <div class="dot" data-value="10"></div>
65 <div class="dot" data-value="15"></div>
66 <div class="dot" data-value="20"></div>
67 <div class="dot" data-value="25"></div>
68 <div class="dot" data-value="30"></div>
69 <div class="dot" data-value="35"></div>
70 <div class="dot" data-value="40"></div>
71 </div>
72 <div class="values">
73 <div class="value-pos" id="prevValuePos">
74 <div class="slider-value">${loanTerm.getData()} <span><span id="prevValue"></span> ${year.getData()}</span></div>
75 <div class="extra-value" id="prevExtraValue"></div>
76 </div>
77 <div class="value-pos" id="currentValuePos">
78 <div class="slider-value" >${loanTerm.getData()} <span><span id="currentValue"></span> ${year.getData()}</span></div>
79 <div class="extra-value" id="currentExtraValue"></div>
80 <div class="triangle"></div>
81 </div>
82 <div class="value-pos" id="nextValuePos">
83 <div class="slider-value" >${loanTerm.getData()} <span><span id="nextValue"></span> ${year.getData()}</span></div>
84 <div class="extra-value" id="nextExtraValue"></div>
85 </div>
86 </div>
87 </div>
88 </div>
89 </div>
90</section>
91<section id="section3" class="bg-dark cred-sim" style="display: none;">
92 <div class="container-fluid container1200">
93 <div class="col-sm-6 col-sm-push-6">
94 <div id="pie-chart-1" class="pie-chart">
95 <div class="pie-wrapper">
96 <div class="pie" id="dynamicPieChart">
97 <div><span>${total.getData()}</span>
98 <h4 id="totalCost"></h4>
99 </div>
100 </div>
101 </div>
102 <div class="one-column-legend">
103 <div class="legend-item legend-item-value1">
104 <div class="legend-item-left">
105 <span id="summaryLoanAmountPieChart"></span>
106 <span class="dash">-</span>
107 <span>${loanAmount.getData()}</span>
108 </div>
109 </div>
110 <div class="legend-item legend-item-value2">
111 <div class="legend-item-left">
112 <span id="summaryTotalInterestPieChart"></span>
113 <span class="dash">-</span>
114 <span>${totalInterestPaid.getData()}</span>
115 </div>
116 </div>
117 <div class="legend-item">
118 <span>${interestRate.getData()} - </span>
119 <span id="summaryInterestRate"></span>
120 <!-- This is empty because it otherwise breaks the HTML structure if deleted. I have no idea why it happens, but I am leaving it like this hoping it holds together by the power of magic. -->
121 <button id="monthlyInterestTooltip" class="lfr-portal-tooltip btn-tooltip" data-html="true" data-tooltip-align="top" data-tooltip-delay="0" type="button" title="">
122
123 </button>
124 </div>
125 <div class="legend-item">
126 <span>${apr.getData()} - </span>
127 <span id="summaryJkp"></span>
128 <button id="jkpTooltip" class="lfr-portal-tooltip btn-tooltip" data-html="true" data-tooltip-align="top" data-tooltip-delay="0" type="button" title="">
129 <i class="far fa-info-circle"></i>
130 </button>
131 </div>
132 </div>
133 </div>
134 <div>${inaccuracyWarning.getData()}</div>
135 </div>
136 <div class="col-sm-6 col-sm-pull-6">
137 <div class="overview">
138 <div class="overview-title-1">${youPay.getData()}</div>
139 <div class="overview-value-1" id="summaryMonthlyPayment"></div>
140 <div class="overview-label-1">${perMonth.getData()}</div>
141 <div class="overview-value-2" id="summaryTotalInterest"></div>
142 <div class="overview-label-2">${onTotalInterest.getData()}</div>
143 <div class="overview-value-3" id="summaryTotalCost"></div>
144 <div class="overview-label-3">${inTotalToBank.getData()}</div>
145 <div class="overview-title-2">${youBorrow.getData()}</div>
146 <div class="overview-value-4" id="summaryLoanAmount"></div>
147 <div class="overview-label-5">${over.getData()}</div>
148 <div class="overview-value-5" id="summaryPeriod"></div>
149 <#if locale?contains("fr_")>
150 <a id="buttonSkedify" class="btn" href="/fr/assurances/rendez-vous?cnm=CreditSimulator" >${buttonMakeAnAppointment.getData()} <i class="far fa-calendar-alt"></i></a>
151 <#else>
152 <a id="buttonSkedify" class="btn" href="/verzekeringen/afspraak?cnm=CreditSimulator" >${buttonMakeAnAppointment.getData()} <i class="far fa-calendar-alt"></i></a>
153 </#if>
154 </div>
155 </div>
156 </div>
157</section>
158<style>
159 /*-<<< START input >>>-*/
160 .form-horizontal.cred-sim {
161 max-width: 900px;
162 margin: 50px auto;
163 }
164 #wrapper .cred-sim .form-control {
165 font-size: 16px;
166 height: 48px;
167 font-weight: bold;
168 }
169 #wrapper .cred-sim label {
170 font-size: 16px;
171 }
172 .form-horizontal.cred-sim .control-label {
173 font-weight: normal;
174 }
175 .btn-group .btn {
176 margin-right: 5px; /* Adjust spacing between buttons */
177 }
178
179 .btn-group .btn:last-child {
180 margin-right: 0; /* Remove margin from the last button */
181 }
182 .input-wrapper {
183 display: grid;
184 grid-template-columns: 1fr 1fr;
185 column-gap: 16px;
186 }
187 .radio-button {
188 display: grid;
189 height: 48px;
190 border: 1px solid #cecece;
191 background-color: #ffffff;
192 border-radius: 4px;
193 }
194 .radio-button input {
195 width: 100%;
196 height: 100%;
197 opacity: 0;
198 grid-row: 1;
199 grid-column: 1;
200 }
201 .radio-button label {
202 margin-bottom: 0;
203 line-height: 1;
204 padding-left: var(--spacer-2);
205 padding-right: var(--spacer-2);
206 grid-row: 1;
207 grid-column: 1;
208 text-align: center;
209 align-self: center;
210 border: 1px solid transparent;
211 border-radius: var(--border-radius-sm);
212 font-weight: normal;
213 }
214 .radio-button:has(input:checked) {
215 border: 2px solid #870930;
216 }
217 .radio-button:has(input:checked) label {
218 font-weight: bold;
219 color: #870930;
220 }
221 .cred-sim .button-wrapper {
222 justify-content: end;
223 display: flex;
224 margin-top: 40px;
225 }
226 #wrapper .cred-sim .btn-default {
227 color: #fff;
228 border-radius: 4px;
229 padding: 12px 16px;
230 display: flex;
231 gap: 12px;
232 align-items: center;
233 border-width: 1px;
234 }
235 #wrapper .cred-sim .btn-default:hover {
236 background-color: #4c0219;
237 border-color: #4c0219;
238 }
239 @media only screen and (min-width : 768px) {
240 .form-horizontal.cred-sim .control-label {
241 text-align: left;
242 }
243 }
244 /*-<<< STOP input >>>-*/
245
246 /*-<<< START slider >>>-*/
247 #wrapper .bg-light1.cred-sim {
248 padding-top: 25px;
249 padding-bottom: 0;
250 }
251 .back {
252 display: flex;
253 justify-content: start;
254 }
255 .back a {
256 display: flex;
257 align-items: center;
258 color: #4d4d4d;
259 gap: 8px;
260 font-size: 18px;
261 }
262 .back a::before {
263 content: "";
264 width: 13px;
265 height: 13px;
266 transform: rotate(45deg);
267 border: 3px solid transparent;
268 border-bottom-color: #ff6600;
269 border-left-color: #ff6600;
270 display: inline-block;
271 }
272 .slider-container {
273 width: calc(100% - 40px);
274 margin: 100px auto -1px;
275 position: relative;
276 }
277 .limits {
278 position: absolute;
279 top: -50px;
280 display: flex;
281 justify-content: space-between;
282 width: 100%;
283 color: #870930;
284 opacity: 0.7;
285 }
286 .slider {
287 width: 100%;
288 -webkit-appearance: none;
289 appearance: none;
290 height: 4px;
291 background: #DBB5C1;
292 outline: none;
293 opacity: 1;
294 transform: translateY(-10px) ;
295 }
296 .slider::-webkit-slider-thumb {
297 -webkit-appearance: none;
298 appearance: none;
299 width: 60px;
300 height: 60px;
301 background: transparent;
302 cursor: pointer;
303 box-shadow: none;
304 }
305 .slider::-moz-range-thumb {
306 width: 60px;
307 height: 60px;
308 background: transparent;
309 cursor: pointer;
310 appearance: none;
311 border-width: 0;
312 }
313 .slider::before {
314 display: none;
315 }
316 .values {
317 position: relative;
318 color: #870930;
319 font-weight: 400;
320 }
321 .values:after {
322 content: "";
323 display: block;
324 clear: both;
325 height: 60px;
326 }
327 .value-pos{
328 position: absolute;
329 display: flex;
330 flex-direction: column;
331 align-items: center;
332 transform: translatex(-50%);
333 }
334 .value-pos:not(#currentValuePos) {
335 visibility: hidden;
336 }
337 .slider-value {
338 display: flex;
339 flex-direction: column;
340 align-items: center;
341 width: max-content;
342 margin-top: 25px;
343 margin-bottom: 5px;
344 opacity: 0.7;
345 }
346 .extra-value {
347 text-align: center;
348 opacity: 0.7;
349 width: max-content;
350 color: #4c0219;
351 font-weight: bold;
352 margin-bottom: 25px;
353 }
354 div#currentValue,
355 div#currentExtraValue {
356 opacity: 1;
357 }
358 .triangle {
359 width: 0;
360 height: 0;
361 border-left: 14px solid transparent;
362 border-right: 14px solid transparent;
363 border-bottom: 18px solid #870930;
364 }
365 .dots {
366 position: absolute;
367 top: -13px;
368 width: 100%;
369 display: flex;
370 justify-content: space-between;
371 align-items: center;
372 pointer-events: none;
373 }
374 .dot {
375 width: 10px;
376 height: 10px;
377 background-color: #DBB5C1;
378 border-radius: 50%;
379 }
380 .dot.current {
381 background-color: #870930;
382 transform: scale(4);
383 display: flex;
384 justify-content: center;
385 align-items: center;
386 }
387 .dot.current::before {
388 content: "";
389 width: 14px;
390 height: 14px;
391 transform: rotate(45deg) scale(0.16);
392 border: 3px solid transparent;
393 border-bottom-color: white;
394 border-left-color: white;
395 display: inline-block;
396 position: absolute;
397 right: -1px;
398 }
399 .dot.current::after {
400 content: "";
401 width: 14px;
402 height: 14px;
403 transform: rotate(45deg) scale(0.16);
404 border: 3px solid transparent;
405 border-top-color: white;
406 border-right-color: white;
407 display: inline-block;
408 position: absolute;
409 left: -1px;
410 }
411 section.bg-dark.cred-sim {
412 padding-top: 25px;
413 }
414 section.bg-dark.cred-sim p {
415 font-weight: 100;
416 }
417 section.bg-dark.cred-sim h4 {
418 margin-bottom: 15px;
419 }
420 section.bg-dark.cred-sim .col-sm-6 {
421 margin: 40px 0;
422 }
423 #wrapper .btn#buttonSkedify {
424 border-radius: 4px;
425 padding: 12px 16px;
426 font-size: 1.6rem;
427 display: inline-flex;
428 align-items: center;
429 max-width: fit-content;
430 gap: 12px;
431 }
432 #wrapper .btn#buttonSkedify:hover,
433 #wrapper .btn#buttonSkedify:active,
434 #wrapper .btn#buttonSkedify:focus {
435 color: #f2e9ec;
436 border-color: #f2e9ec;
437 }
438 .overview {
439 display: grid;
440 grid-template-columns: 1fr 1fr;
441 grid-template-rows: repeat(10, 24px);
442 }
443 [class^="overview-value"] {
444 font-weight: bold;
445 }
446 [class^="overview-label"] {
447 font-size: 14px !important;
448 }
449 .overview-title-1 {
450 grid-column: 1;
451 grid-row: 1;
452 }
453 .overview-value-1 {
454 grid-column: 1;
455 grid-row: 3;
456 }
457 .overview-label-1 {
458 grid-column: 1;
459 grid-row: 4;
460 }
461 .overview-value-2 {
462 grid-column: 1;
463 grid-row: 6;
464 }
465 .overview-label-2 {
466 grid-column: 1;
467 grid-row: 7;
468 }
469 .overview-value-3 {
470 grid-column: 1;
471 grid-row: 9;
472 }
473 .overview-label-3 {
474 grid-column: 1;
475 grid-row: 10;
476 }
477 .overview-title-2 {
478 grid-column: 2;
479 grid-row: 1;
480 }
481 .overview-value-4 {
482 grid-column: 2;
483 grid-row: 3;
484 }
485 .overview-label-5 {
486 grid-column: 2;
487 grid-row: 5;
488 }
489 .overview-value-5 {
490 grid-column: 2;
491 grid-row: 6;
492 }
493 #buttonSkedify {
494 grid-column: 2;
495 grid-row: 9 / 12;
496 }
497 @media only screen and (min-width : 768px) {
498 .back {
499 justify-content: end;
500 }
501 .slider-container {
502 width: calc(100% - 150px);
503 }
504 .value-pos:not(#currentValuePos) {
505 visibility: visible;
506 }
507 .dot.previous,
508 .dot.next {
509 transform: scale(2);
510 }
511 section.bg-dark.cred-sim {
512 padding-top: 40px;
513 }
514 section.bg-dark.cred-sim .col-sm-6:first-child {
515 border-left: 1px solid #ffffff;
516 padding-left: 30px;
517 }
518 section.bg-dark.cred-sim .col-sm-6:last-child {
519 padding-right: 30px;
520 }
521 .validation-message {
522 padding-left: 15px;
523 }
524 }
525
526 @media only screen and (min-width : 992px) {
527 .limits {
528 top: -60px;
529 }
530 .value-pos:not(#currentValuePos) {
531 visibility: visible;
532 }
533 .value {
534 margin-top: 40px;
535 }
536 div#currentValue,
537 div#currentExtraValue {
538 font-size: 1.8rem;
539 }
540 .dot.previous,
541 .dot.next {
542 transform: scale(2.6);
543 }
544 .dot.current {
545 transform: scale(6);
546 }
547 section.bg-dark.cred-sim {
548 padding-top: 65px;
549 }
550 section.bg-dark.cred-sim .col-sm-6:first-child {
551 padding-left: 50px;
552 }
553 section.bg-dark.cred-sim .col-sm-6:last-child {
554 padding-right: 50px;
555 }
556 .validation-message {
557 padding-left: 15px;
558 }
559 }
560 @media only screen and (min-width : 1200px) {
561 .slider-container {
562 width: 1000px;
563 }
564 .slider-value {
565 display: block;
566 }
567 div#currentValue,
568 div#currentExtraValue {
569 font-size: 2rem;
570 }
571 section.bg-dark.cred-sim .col-sm-6:first-child {
572 padding-left: 80px;
573 }
574 section.bg-dark.cred-sim .col-sm-6:last-child {
575 padding-right: 80px;
576 }
577 .validation-message {
578 padding-left: 15px;
579 }
580 }
581 /*-<<< STOP slider >>>-*/
582
583 /*-<<< START piechart & legend >>>-*/
584 .pie {
585 height: 230px;
586 width: 230px;
587 border-radius: 50%;
588 background: conic-gradient(#F2E9EC 0% 25%, #C38498 25% 100% );
589 }
590 .pie-chart {
591 margin-bottom: 25px;
592 }
593 .pie-chart .row {
594 align-items: center;
595 }
596 .pie-wrapper {
597 width: 100%;
598 display: flex;
599 justify-content: center;
600 }
601 .no-chart .pie-wrapper {
602 display: none;
603 }
604 .pie {
605 display: flex;
606 justify-content: center;
607 align-items: center;
608 margin-bottom: 25px;
609 }
610 .pie::after {
611 content: '';
612 position: absolute;
613 height: 190px;
614 width: 190px;
615 border-radius: 50%;
616 background-color: #870930;
617 }
618 .pie>div {
619 z-index: 1;
620 text-align: center;
621 margin-top: -2px;
622 }
623 .pie span h4 {
624 margin-bottom: 0;
625 }
626 button.btn-tooltip {
627 background-color: transparent;
628 border-width: 0;
629 }
630 .legend-item {
631 display: flex;
632 align-items: baseline;
633 margin-bottom: 8px;
634 gap: 5px;
635 }
636 .legend-item-left,
637 .legend-item-right {
638 width: 50%;
639 }
640 .one-column-legend {
641 display: grid;
642 grid-template-rows: min-content min-content;
643 justify-content: center;
644 }
645 .one-column-legend .legend-item-left {
646 width: 100%;
647 }
648 .legend-item-left {
649 display: grid;
650 grid-template-columns: min-content min-content min-content auto;
651 align-items: baseline;
652 }
653 .legend-item-left span {
654 margin-left: 8px;
655 }
656 .legend-item-left::before {
657 content: "";
658 width: 12px;
659 height: 12px;
660 border-radius: 50%;
661 }
662 .legend-header .legend-item-left::before {
663 color: transparent;
664 }
665 .legend-item-left::before {
666 font-size: var(--font-size-xs);
667 }
668 .legend-item-value1 .legend-item-left::before {
669 background-color: #F2E9EC;
670 }
671 .legend-item-value2 .legend-item-left::before {
672 background-color: #C38498;
673 }
674 @media only screen and (min-width : 1200px) {
675 .pie-chart {
676 display: grid;
677 grid-template-columns: auto auto;
678 align-items: center;
679 }
680 span.dash {
681 display:none;
682 }
683 .legend-item-left {
684 grid-template-columns: min-content auto;
685 }
686 .legend-item-left span:last-child {
687 grid-row: 2;
688 grid-column: 2;
689 }
690 .pie-wrapper {
691 grid-row: 1;
692 grid-column: 2;
693 }
694 .pie {
695 width: 200px;
696 height: 200px;
697 margin-bottom: 0;
698 }
699 .pie::after {
700 width: 160px;
701 height: 160px;;
702 }
703 .one-column-legend {
704 grid-row: 1;
705 grid-column: 1;
706 padding-right: 20px;
707 }
708 }
709 /*-<<< STOP piechart & legend >>>-*/
710
711
712</style>
713
714<script>
715 let purchase10YearLoanPercentage = Number(${purchase10YearLoanPercentage.getData()});
716 let purchase15YearLoanPercentage = Number(${purchase15YearLoanPercentage.getData()});
717 let purchase20YearLoanPercentage = Number(${purchase20YearLoanPercentage.getData()});
718 let purchase25YearLoanPercentage = Number(${purchase25YearLoanPercentage.getData()});
719 let purchase30YearLoanPercentage = Number(${purchase30YearLoanPercentage.getData()});
720 let purchase35YearLoanPercentage = Number(${purchase35YearLoanPercentage.getData()});
721 let purchase40YearLoanPercentage = Number(${purchase40YearLoanPercentage.getData()});
722
723 let renovation10YearLoanPercentage = Number(${renovation10YearLoanPercentage.getData()});
724 let renovation15YearLoanPercentage = Number(${renovation15YearLoanPercentage.getData()});
725 let renovation20YearLoanPercentage = Number(${renovation20YearLoanPercentage.getData()});
726 let renovation25YearLoanPercentage = Number(${renovation25YearLoanPercentage.getData()});
727 let renovation30YearLoanPercentage = Number(${renovation30YearLoanPercentage.getData()});
728 let renovation35YearLoanPercentage = Number(${renovation35YearLoanPercentage.getData()});
729 let renovation40YearLoanPercentage = Number(${renovation40YearLoanPercentage.getData()});
730
731 let enterLoanAmountLabel = "${enterLoanAmount.getData()}";
732 let enterMonthlyPaymentLabel = "${enterMonthlyPayment.getData()}";
733 let calculationTypeWarning = "${calculationTypeWarning.getData()}";
734 let emptyLoanAmountWarning = "${emptyLoanAmountWarning.getData()}";
735 let emptyMonthlyPaymentWarning = "${emptyMonthlyPaymentWarning.getData()}";
736 let invalidLoanAmountWarning = "${invalidLoanAmountWarning.getData()}";
737 let invalidMonthlyPaymentWarning = "${invalidMonthlyPaymentWarning.getData()}";
738 let emptyLoanPeriodWarning = "${emptyLoanPeriodWarning.getData()}";
739 let invalidLoanPeriodWarning = "${invalidLoanPeriodWarning.getData()}";
740 let yearLabel = "${year.getData()}";
741 let monthlyInterestTooltipContent = "${interestRateTooltipContent.getData()}";
742 let titleSimulationLoanAmount = "${titleSimulationLoanAmount.getData()}"
743 let titleSimulationDownPayment = "${titleSimulationDownPayment.getData()}"
744 let jkpTooltipContent;
745
746 if (window.location.href.includes("/fr/")) {
747 jkpTooltipContent = "Le TAEG (taux annuel effectif global) est un indicateur qui vous renseigne sur le coût total du crédit. Il vous aide à comparer les propositions de différents prêteurs.";
748 } else {
749 jkpTooltipContent = "Het JKP (jaarlijks kostenpercentage) is een indicator die u informeert over de totale kosten van het krediet. Het helpt u om de voorstellen van verschillende kredietverstrekkers te vergelijken.";
750 }
751
752 document.getElementById("monthlyInterestTooltip").title = monthlyInterestTooltipContent;
753 document.getElementById("jkpTooltip").title = jkpTooltipContent;
754
755 const slider = document.getElementById('rangeSlider');
756 const prevValue = document.getElementById('prevValue');
757 const currentValue = document.getElementById('currentValue');
758 const nextValue = document.getElementById('nextValue');
759 const prevExtraValue = document.getElementById('prevExtraValue');
760 const currentExtraValue = document.getElementById('currentExtraValue');
761 const nextExtraValue = document.getElementById('nextExtraValue');
762 const prevValuePos = document.getElementById('prevValuePos');
763 const currentValuePos = document.getElementById('currentValuePos');
764 const nextValuePos = document.getElementById('nextValuePos');
765 const dots = document.querySelectorAll('.dot');
766
767 const extraValuesMap = {
768 10: '100,000',
769 15: '150,000',
770 20: '200,000',
771 25: '250,000',
772 30: '300,000',
773 35: '350,000',
774 40: '400,000'
775 };
776
777 function updateInputFieldLabel() {
778 const inputFieldContainer = document.getElementById('inputFieldContainer');
779 const inputFieldLabel = document.getElementById('inputFieldLabel');
780 const loanAmountRadio = document.querySelector('input[name="whattocalculate"][value="loanAmount"]');
781 const monthlyPaymentRadio = document.querySelector('input[name="whattocalculate"][value="monthlyPayment"]');
782
783 inputFieldContainer.style.display = 'block';
784
785 if (loanAmountRadio.checked) {
786 inputFieldLabel.textContent = enterLoanAmountLabel;
787 inputFieldLabel.style.textAlign = 'left';
788 } else if (monthlyPaymentRadio.checked) {
789 inputFieldLabel.textContent = enterMonthlyPaymentLabel;
790 inputFieldLabel.style.textAlign = 'left';
791 }
792
793 document.getElementById('warningMessage').style.display = 'none';
794 document.getElementById('inputWarningMessage').style.display = 'none';
795 }
796
797 function validateAndShowResult() {
798 const calculationTypeValue = document.getElementById("selectField").value;
799 if (calculationTypeValue === "purchase") {
800 durationAndTotalInterestPercentageMap.set(10, [purchase10YearLoanPercentage]);
801 durationAndTotalInterestPercentageMap.set(15, [purchase15YearLoanPercentage]);
802 durationAndTotalInterestPercentageMap.set(20, [purchase20YearLoanPercentage]);
803 durationAndTotalInterestPercentageMap.set(25, [purchase25YearLoanPercentage]);
804 durationAndTotalInterestPercentageMap.set(30, [purchase30YearLoanPercentage]);
805 durationAndTotalInterestPercentageMap.set(35, [purchase35YearLoanPercentage]);
806 durationAndTotalInterestPercentageMap.set(40, [purchase40YearLoanPercentage]);
807 } else {
808 durationAndTotalInterestPercentageMap.set(10, [renovation10YearLoanPercentage]);
809 durationAndTotalInterestPercentageMap.set(15, [renovation15YearLoanPercentage]);
810 durationAndTotalInterestPercentageMap.set(20, [renovation20YearLoanPercentage]);
811 durationAndTotalInterestPercentageMap.set(25, [renovation25YearLoanPercentage]);
812 durationAndTotalInterestPercentageMap.set(30, [renovation30YearLoanPercentage]);
813 durationAndTotalInterestPercentageMap.set(35, [renovation35YearLoanPercentage]);
814 durationAndTotalInterestPercentageMap.set(40, [renovation40YearLoanPercentage]);
815 }
816
817 addMonthlyInterestToDurationAndTotalInterestPercentageMap();
818
819 const loanAmountRadio = document.querySelector('input[name="whattocalculate"][value="loanAmount"]');
820 const monthlyPaymentRadio = document.querySelector('input[name="whattocalculate"][value="monthlyPayment"]');
821 const radioWarningMessage = document.getElementById('radioWarningMessage');
822 const inputValueWarningMessage = document.getElementById('inputValueWarningMessage');
823 const inputPeriodWarningMessage = document.getElementById('inputPeriodWarningMessage');
824
825 const inputFieldValue = document.getElementById('inputFieldValue').value;
826 const inputFieldPeriod = document.getElementById('inputFieldPeriod').value;
827
828 radioWarningMessage.style.display = 'none';
829 inputValueWarningMessage.style.display = 'none';
830 inputPeriodWarningMessage.style.display = 'none';
831
832 if (!loanAmountRadio.checked && !monthlyPaymentRadio.checked) {
833 radioWarningMessage.style.display = 'block';
834 radioWarningMessage.style.textAlign = 'left';
835 radioWarningMessage.textContent = calculationTypeWarning;
836 } else {
837 let isValid = true;
838
839 if (loanAmountRadio.checked && !inputFieldValue) {
840 inputValueWarningMessage.style.display = 'block';
841 inputValueWarningMessage.style.textAlign = 'left';
842 inputValueWarningMessage.textContent = emptyLoanAmountWarning;
843 isValid = false;
844 } else if (monthlyPaymentRadio.checked && !inputFieldValue) {
845 inputValueWarningMessage.style.display = 'block';
846 inputValueWarningMessage.style.textAlign = 'left';
847 inputValueWarningMessage.textContent = emptyMonthlyPaymentWarning;
848 isValid = false;
849 } else {
850 if (loanAmountRadio.checked) {
851 const valueNumber = Number(inputFieldValue);
852 if (isNaN(valueNumber) || valueNumber < 50000 || valueNumber > 1000000) {
853 inputValueWarningMessage.style.display = 'block';
854 inputValueWarningMessage.style.textAlign = 'left';
855 inputValueWarningMessage.textContent = invalidLoanAmountWarning;
856 isValid = false;
857 }
858 } else {
859 const valueNumber = Number(inputFieldValue);
860 if (isNaN(valueNumber) || valueNumber < 300 || valueNumber > 2000) {
861 inputValueWarningMessage.style.display = 'block';
862 inputValueWarningMessage.style.textAlign = 'left';
863 inputValueWarningMessage.textContent = invalidMonthlyPaymentWarning;
864 isValid = false;
865 }
866 }
867 }
868
869 const validPeriods = [10, 15, 20, 25, 30, 35, 40];
870 if (!inputFieldPeriod) {
871 inputPeriodWarningMessage.style.display = 'block';
872 inputPeriodWarningMessage.style.textAlign = 'left';
873 inputPeriodWarningMessage.textContent = emptyLoanPeriodWarning;
874 isValid = false;
875 } else {
876 const periodValue = Number(inputFieldPeriod);
877 if (!validPeriods.includes(periodValue)) {
878 inputPeriodWarningMessage.style.display = 'block';
879 inputPeriodWarningMessage.style.textAlign = 'left';
880 inputPeriodWarningMessage.textContent = invalidLoanPeriodWarning;
881 isValid = false;
882 }
883 }
884
885 if (isValid) {
886 document.getElementById('section1').style.display = 'none';
887 document.getElementById('section2').style.display = 'block';
888 document.getElementById('section3').style.display = 'block';
889
890 showResult(true);
891 }
892 }
893 }
894
895 function formatCurrency(value, isFrenchLanguage) {
896 if (!isFrenchLanguage) {
897 let [integerPart, decimalPart] = Number(value).toFixed(2).split('.');
898 integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, '.');
899
900 return integerPart + ',' + decimalPart;
901 } else {
902 let [integerPart, decimalPart] = Number(value).toFixed(2).split('.');
903 integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
904
905 return integerPart + ',' + decimalPart;
906 }
907 }
908
909 function updateValues() {
910 const current = parseInt(slider.value);
911 const next = current + 5 <= 40 ? current + 5 : '';
912 const prev = current - 5 >= 10 ? current - 5 : '';
913 prevValue.textContent = prev ? prev : '';
914 currentValue.textContent = current ? current : '';
915 nextValue.innerHTML = next ? next : '';
916 prevExtraValue.textContent = prev ? "€ " + extraValuesMap[prev] : '';
917 currentExtraValue.textContent = current ? "€ " + extraValuesMap[current] : '';
918 nextExtraValue.textContent = next ? "€ " + extraValuesMap[next] : '';
919
920 const sliderWidth = slider.offsetWidth;
921 const min = parseInt(slider.min);
922 const max = parseInt(slider.max);
923
924 const prevPosition = ((prev - min) / (max - min)) * sliderWidth;
925 const currentPosition = ((current - min) / (max - min)) * sliderWidth;
926 const nextPosition = ((next - min) / (max - min)) * sliderWidth;
927
928 prevValuePos.style.left = prevPosition + "px";
929 currentValuePos.style.left = currentPosition + "px";
930 nextValuePos.style.left = nextPosition + "px";
931
932
933 dots.forEach(dot => {
934 dot.classList.remove('previous', 'next', 'current');
935 var dotValue = parseInt(dot.getAttribute('data-value'));
936 if (dotValue === prev) {
937 dot.classList.add('previous');
938 } else if (dotValue === next) {
939 dot.classList.add('next');
940 } else if (dotValue === current) {
941 dot.classList.add('current');
942 }
943 });
944 }
945
946 function adjustParentHeight() {
947 const parent = document.getElementById('sliderContainer');
948 const child = document.getElementById('currentValuePos');
949 parent.style.height = child.offsetHeight + 'px';
950 }
951
952 slider.addEventListener('input', function () {
953 showResult(false);
954 });
955 window.addEventListener('resize', function () {
956 showResult(false);
957 });
958 window.addEventListener('resize', adjustParentHeight);
959
960 updateValues();
961 adjustParentHeight();
962
963 const durationAndTotalInterestPercentageMap = new Map();
964
965 function addMonthlyInterestToDurationAndTotalInterestPercentageMap() {
966 for (let [key, value] of durationAndTotalInterestPercentageMap) {
967 value.push(getMonthlyInterestPercentageFromTotalInterestPercentage(value[0]));
968 }
969 }
970
971 function getAmountOfPayments(loanAmountPeriodInYears) {
972 return 12 * Number(loanAmountPeriodInYears);
973 }
974
975 function getMonthlyInterestPercentageFromTotalInterestPercentage(totalInterestPercentage) {
976 return ((Math.pow((1 + (totalInterestPercentage / 100)), (1 / 12)) - 1).toFixed(7)) * 100;
977 }
978
979 function getMonthlyPaymentAmount(loanAmount, loanAmountPeriodInYears) {
980 const amountOfPayments = getAmountOfPayments(loanAmountPeriodInYears);
981 const monthlyInterestRate = durationAndTotalInterestPercentageMap.get(Number(loanAmountPeriodInYears))[1] / 100;
982
983 return ((loanAmount * monthlyInterestRate) / (1 - (1 / (Math.pow(1 + monthlyInterestRate, amountOfPayments))))).toFixed(2);
984 }
985
986 function getTotalRepaymentLoan(monthlyPaymentAmount, loanAmountPeriodInYears) {
987 return monthlyPaymentAmount * getAmountOfPayments(loanAmountPeriodInYears);
988 }
989
990 function getTotalPaymentFromMonthlyPaymentAmount(monthlyPaymentAmount, loanPeriodAmountInYears) {
991 let monthlyInterestRate = Number(durationAndTotalInterestPercentageMap.get(Number(loanPeriodAmountInYears))[1]) / 100;
992 let loanAmountPeriod = Number(Number(loanPeriodAmountInYears) * 12);
993
994 return Number(((monthlyPaymentAmount / monthlyInterestRate) * (1 - (1 / (Math.pow(1 + monthlyInterestRate, loanAmountPeriod))))).toFixed(2));
995 }
996
997 function getNotaryAndRegistrationCost(loanAmount) {
998 const mortgageRightsCost1 = loanAmount * (110 / 100) * (1 / 100);
999 const mortgageRightsCost2 = loanAmount * (0.3 / 100);
1000
1001 return (mortgageRightsCost1 + mortgageRightsCost2 + lumpSumForTheLegalCertaintyOffice + flatRateDeedCosts).toFixed(2);
1002 }
1003
1004 function getInitialCost(loanAmount, loanAmountPeriodInYears) {
1005 const notaryAndRegistrationCost = getNotaryAndRegistrationCost(loanAmount);
1006 const oneTimeSingleDayInterbankInterest = loanAmount * ((durationAndTotalInterestPercentageMap.get(Number(loanAmountPeriodInYears))[1] / 100) / 30);
1007 return (Number(notaryAndRegistrationCost) + oneTimeFileCosts + oneTimeEstimationCosts + oneTimeSingleDayInterbankInterest).toFixed(2);
1008 }
1009
1010 function getDates(loanPaymentPeriodInYears) {
1011 const currentYear = new Date().getFullYear();
1012 const startingDate = new Date(Date.UTC(currentYear, 0, 1));
1013
1014 const paymentDates = [startingDate];
1015 for (let i = 0; i <= 12 * loanPaymentPeriodInYears; i++) {
1016 let tempDate = new Date(startingDate.getUTCFullYear(), startingDate.getUTCMonth(), startingDate.getUTCDay());
1017 tempDate.setUTCMonth(startingDate.getUTCMonth() + i);
1018 tempDate.setUTCDate(1);
1019
1020 paymentDates.push(tempDate);
1021 }
1022
1023 return paymentDates;
1024 }
1025
1026 function getTotalCost(loanAmount, loanPaymentPeriodInYears) {
1027 const additionalInsurance = calculateAdditionalInsurance(Number(loanAmount), Number(loanPaymentPeriodInYears));
1028 const totalRepaymentLoan = getTotalRepaymentLoan(getMonthlyPaymentAmount(loanAmount, loanPaymentPeriodInYears), loanPaymentPeriodInYears)
1029 const totalRecurrentAnnualCost = (Math.floor((2 / 3) * loanPaymentPeriodInYears)) * Number(additionalInsurance);
1030 const totalFireInsuranceCost = fireInsurance * loanPaymentPeriodInYears;
1031 const totalInitialCost = Number(getInitialCost(loanAmount, loanPaymentPeriodInYears));
1032
1033 return totalRepaymentLoan + totalRecurrentAnnualCost + totalFireInsuranceCost + totalInitialCost;
1034 }
1035
1036 function getExtendedInternalRateOfReturn(loanAmount, loanPaymentPeriodInYears) {
1037 const additionalInsurance = calculateAdditionalInsurance(loanAmount, loanPaymentPeriodInYears);
1038 const currentYear = new Date().getUTCFullYear();
1039 const startingDate = new Date(Date.UTC(currentYear, 0, 1));
1040
1041 const dates = getDates(loanPaymentPeriodInYears);
1042 const payments = [-loanAmount, Number(getInitialCost(loanAmount, loanPaymentPeriodInYears)) + fireInsurance + Number(additionalInsurance)];
1043 const monthlyPaymentAmount = Number(getMonthlyPaymentAmount(loanAmount, loanPaymentPeriodInYears));
1044
1045 for (let i = 2; i < dates.length; i++) {
1046 if (dates[i].toUTCString() !== startingDate.toUTCString()) {
1047 if (dates[i].getUTCMonth() === 0 && dates[i].getUTCDate() === 1) {
1048 let amount = Number(fireInsurance) + Number(monthlyPaymentAmount);
1049 if (dates[i].getUTCFullYear() <= (currentYear + (Math.floor((2 / 3) * loanPaymentPeriodInYears) - 1))) {
1050 amount += Number(additionalInsurance);
1051 }
1052 payments.push(Number(amount));
1053 } else {
1054 payments.push(Number(monthlyPaymentAmount));
1055 }
1056 }
1057 }
1058
1059 return getInternalRateOfReturn(payments, dates, 0.01).toFixed(2);
1060 }
1061
1062 function getInternalRateOfReturn(values, dates, guess) {
1063
1064 var irrResult = function (values, dates, rate) {
1065 var r = rate + 1;
1066 var result = values[0];
1067 for (var i = 1; i < values.length; i++) {
1068 let diffTime = Math.abs(dates[i] - dates[0]);
1069 let diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
1070 result += values[i] / Math.pow(r, diffDays / 365);
1071 }
1072 return result;
1073 }
1074
1075 var irrResultDeriv = function (values, dates, rate) {
1076 var r = rate + 1;
1077 var result = 0;
1078 for (var i = 1; i < values.length; i++) {
1079 let diffTime = Math.abs(dates[i] - dates[0]);
1080 let diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
1081 var frac = diffDays / 365;
1082 result -= frac * values[i] / Math.pow(r, frac + 1);
1083 }
1084 return result;
1085 }
1086
1087 var positive = false;
1088 var negative = false;
1089 for (var i = 0; i < values.length; i++) {
1090 if (values[i] > 0) positive = true;
1091 if (values[i] < 0) negative = true;
1092 }
1093
1094 if (!positive || !negative) return 'POSNEG';
1095
1096 var guess = (typeof guess === 'undefined') ? 0.1 : guess;
1097 var resultRate = guess;
1098
1099 var epsMax = 1e-10;
1100
1101 var iterMax = 50;
1102
1103 var newRate, epsRate, resultValue;
1104 var iteration = 0;
1105 var contLoop = true;
1106 do {
1107 resultValue = irrResult(values, dates, resultRate);
1108 newRate = resultRate - resultValue / irrResultDeriv(values, dates, resultRate);
1109 epsRate = Math.abs(newRate - resultRate);
1110 resultRate = newRate;
1111 contLoop = (epsRate > epsMax) && (Math.abs(resultValue) > epsMax);
1112 } while (contLoop && (++iteration < iterMax));
1113
1114 if (contLoop) return '#NUM!';
1115
1116 return resultRate * 100;
1117 }
1118
1119 function simulateCreditScore(value, paymentPeriodInYears, isValueTotalLoanAmount) {
1120 const resultValuesMap = new Map();
1121
1122 let loanAmount;
1123 let monthlyPayment;
1124 if (isValueTotalLoanAmount === true) {
1125 loanAmount = Number(value);
1126 monthlyPayment = Number(getMonthlyPaymentAmount(loanAmount, paymentPeriodInYears));
1127 } else {
1128 monthlyPayment = Number(value);
1129 loanAmount = getTotalPaymentFromMonthlyPaymentAmount(monthlyPayment, paymentPeriodInYears);
1130 }
1131
1132 let totalRepayment = Number(getTotalRepaymentLoan(monthlyPayment, paymentPeriodInYears));
1133 let totalCost = Number(getTotalCost(loanAmount, paymentPeriodInYears).toFixed(2));
1134 let extendedInternalRateOfReturn = Number(getExtendedInternalRateOfReturn(loanAmount, paymentPeriodInYears)).toFixed(2);
1135
1136 let lowerLoanAmount;
1137 let lowerMonthlyPayment;
1138 let lowerPaymentPeriod;
1139 let upperLoanAmount;
1140 let upperMonthlyPayment;
1141 let upperPaymentPeriod;
1142
1143 lowerPaymentPeriod = paymentPeriodInYears - 5;
1144 if (lowerPaymentPeriod < 10) {
1145 lowerPaymentPeriod = 10;
1146 }
1147
1148 lowerLoanAmount = Number(getTotalPaymentFromMonthlyPaymentAmount(monthlyPayment, lowerPaymentPeriod));
1149 lowerMonthlyPayment = Number(getMonthlyPaymentAmount(loanAmount, lowerPaymentPeriod));
1150
1151 upperPaymentPeriod = Number(paymentPeriodInYears) + 5;
1152 if (upperPaymentPeriod > 40) {
1153 upperPaymentPeriod = 40;
1154 }
1155
1156 upperLoanAmount = Number(getTotalPaymentFromMonthlyPaymentAmount(monthlyPayment, upperPaymentPeriod));
1157 upperMonthlyPayment = Number(getMonthlyPaymentAmount(loanAmount, upperPaymentPeriod));
1158
1159 resultValuesMap.set("loanAmount", loanAmount);
1160 resultValuesMap.set("monthlyPayment", monthlyPayment);
1161 resultValuesMap.set("currentPaymentPeriod", paymentPeriodInYears);
1162 resultValuesMap.set("totalRepayment", totalRepayment);
1163 resultValuesMap.set("totalCost", totalCost);
1164 resultValuesMap.set("extendedInternalRateOfReturn", extendedInternalRateOfReturn);
1165 resultValuesMap.set("lowerLoanAmount", lowerLoanAmount);
1166 resultValuesMap.set("lowerMonthlyPayment", lowerMonthlyPayment);
1167 resultValuesMap.set("lowerPaymentPeriod", lowerPaymentPeriod);
1168 resultValuesMap.set("upperLoanAmount", upperLoanAmount);
1169 resultValuesMap.set("upperMonthlyPayment", upperMonthlyPayment);
1170 resultValuesMap.set("upperPaymentPeriod", upperPaymentPeriod);
1171
1172 return resultValuesMap;
1173 }
1174
1175 function showForm() {
1176 document.getElementById('section1').style.display = 'block';
1177 document.getElementById('section2').style.display = 'none';
1178 document.getElementById('section3').style.display = 'none';
1179 }
1180
1181 function showResult(isInputFromForm) {
1182 let simulationType = document.querySelector('input[name="whattocalculate"]:checked').value;
1183 let value = document.getElementById("inputFieldValue").value;
1184 let period;
1185 if (isInputFromForm === true) {
1186 period = document.getElementById("inputFieldPeriod").value;
1187 } else {
1188 period = slider.value;
1189 }
1190
1191 let isValueTotalLoanAmount;
1192 let simulationResultTitle;
1193 if (simulationType === 'loanAmount') {
1194 isValueTotalLoanAmount = true;
1195 simulationResultTitle = titleSimulationLoanAmount;
1196 } else {
1197 isValueTotalLoanAmount = false;
1198 simulationResultTitle = titleSimulationDownPayment;
1199 }
1200 document.getElementById("simulationResultTitle").textContent = simulationResultTitle;
1201
1202 const result = simulateCreditScore(value, period, isValueTotalLoanAmount);
1203
1204 let lowerPaymentAmount;
1205 let paymentAmount;
1206 let upperPaymentAmount;
1207
1208 if (isValueTotalLoanAmount === true) {
1209 lowerPaymentAmount = result.get("lowerMonthlyPayment");
1210 paymentAmount = result.get("monthlyPayment");
1211 upperPaymentAmount = result.get("upperMonthlyPayment");
1212 } else {
1213 lowerPaymentAmount = result.get("lowerLoanAmount");
1214 paymentAmount = result.get("loanAmount");
1215 upperPaymentAmount = result.get("upperLoanAmount");
1216 }
1217
1218 let lowerPaymentPeriod = result.get("lowerPaymentPeriod");
1219 let currentPaymentPeriod = result.get("currentPaymentPeriod");
1220 let upperPaymentPeriod = result.get("upperPaymentPeriod");
1221
1222 let totalCost = result.get("totalCost");
1223
1224 const previousExtraValue = document.getElementById("prevExtraValue");
1225 const currentExtraValue = document.getElementById("currentExtraValue");
1226 const nextExtraValue = document.getElementById("nextExtraValue");
1227
1228 const previousValue = document.getElementById("prevValue");
1229 const currentValue = document.getElementById("currentValue");
1230 const nextValue = document.getElementById("nextValue");
1231
1232 const totalCostValue = document.getElementById("totalCost");
1233
1234 previousExtraValue.textContent = "€ " + formatCurrency(lowerPaymentAmount);
1235 currentExtraValue.textContent = "€ " + formatCurrency(paymentAmount);
1236 nextExtraValue.textContent = "€ " + formatCurrency(upperPaymentAmount);
1237
1238 previousValue.textContent = lowerPaymentPeriod;
1239 currentValue.textContent = currentPaymentPeriod;
1240 nextValue.textContent = upperPaymentPeriod;
1241
1242 totalCostValue.textContent = "€ " + totalCost;
1243
1244 const summaryMonthlyPayment = document.getElementById("summaryMonthlyPayment");
1245 const summaryTotalInterest = document.getElementById("summaryTotalInterest");
1246 const summaryTotalCost = document.getElementById("summaryTotalCost");
1247 const summaryLoanAmount = document.getElementById("summaryLoanAmount");
1248 const summaryPeriod = document.getElementById("summaryPeriod");
1249 const summaryLoanAmountPieChart = document.getElementById("summaryLoanAmountPieChart");
1250 const summaryTotalInterestPieChart = document.getElementById("summaryTotalInterestPieChart");
1251 const summaryTotalCostPieChart = document.getElementById("totalCost");
1252 const summaryInterestRate = document.getElementById("summaryInterestRate");
1253 const summaryJkp = document.getElementById("summaryJkp");
1254
1255 const totalInterest = Number(result.get("totalCost")).toFixed(2) - Number(result.get("loanAmount")).toFixed(2);
1256
1257 summaryMonthlyPayment.textContent = "€ " + formatCurrency(result.get("monthlyPayment"));
1258 summaryTotalInterest.textContent = "€ " + formatCurrency(totalInterest.toFixed(2));
1259 summaryTotalCost.textContent = "€ " + formatCurrency(result.get("totalCost"));
1260 summaryLoanAmount.textContent = "€ " + formatCurrency(result.get("loanAmount"));
1261 summaryPeriod.textContent = result.get("currentPaymentPeriod") + " " + yearLabel;
1262 summaryLoanAmountPieChart.textContent = "€ " + formatCurrency(result.get("loanAmount"));
1263 summaryTotalCostPieChart.textContent = "€ " + formatCurrency(result.get("totalCost"));
1264 summaryTotalInterestPieChart.textContent = "€ " + formatCurrency(totalInterest.toFixed(2));
1265 summaryInterestRate.textContent = formatCurrency(durationAndTotalInterestPercentageMap.get(Number(period))[0].toFixed(2)) + "%";
1266 summaryJkp.textContent = formatCurrency(result.get("extendedInternalRateOfReturn")) + "%";
1267
1268 const percentageOfAmount = (Number(result.get("loanAmount")) / Number(result.get("totalCost"))) * 100;
1269 document.getElementById("dynamicPieChart").style.background = 'conic-gradient(#F2E9EC 0% ' + percentageOfAmount + '%, #C38498 ' + percentageOfAmount + '% 100%)';
1270
1271 document.getElementById("rangeSlider").value = currentPaymentPeriod;
1272
1273 const current = parseInt(slider.value);
1274 const next = current + 5 <= 40 ? current + 5 : '';
1275 const prev = current - 5 >= 10 ? current - 5 : '';
1276
1277 const sliderWidth = slider.offsetWidth;
1278 const min = parseInt(slider.min);
1279 const max = parseInt(slider.max);
1280
1281 const prevPosition = ((prev - min) / (max - min)) * sliderWidth;
1282 const currentPosition = ((current - min) / (max - min)) * sliderWidth;
1283 const nextPosition = ((next - min) / (max - min)) * sliderWidth;
1284
1285
1286 prevValuePos.style.left = prevPosition + 'px';
1287 currentValuePos.style.left = currentPosition + 'px';
1288 nextValuePos.style.left = nextPosition + 'px';
1289
1290 if (previousValue.textContent === currentValue.textContent) {
1291 prevValuePos.style.display = 'none';
1292 } else {
1293 prevValuePos.style.display = '';
1294 }
1295
1296 if (nextValue.textContent === currentValue.textContent) {
1297 nextValuePos.style.display = 'none';
1298 } else {
1299 nextValuePos.style.display = '';
1300 }
1301
1302 dots.forEach(dot => {
1303 dot.classList.remove('previous', 'next', 'current');
1304 var dotValue = parseInt(dot.getAttribute('data-value'));
1305 if (dotValue === prev) {
1306 dot.classList.add('previous');
1307 } else if (dotValue === next) {
1308 dot.classList.add('next');
1309 } else if (dotValue === current) {
1310 dot.classList.add('current');
1311 }
1312 });
1313
1314 adjustParentHeight();
1315 }
1316
1317 function calculateAdditionalInsurance(loanAmount, paymentPeriodInYears) {
1318 if (loanAmount <= 50000) {
1319 if (paymentPeriodInYears === 10) {
1320 return 69.33;
1321 } else if (paymentPeriodInYears === 15) {
1322 return 69.26;
1323 } else if (paymentPeriodInYears === 20) {
1324 return 74.94;
1325 } else if (paymentPeriodInYears === 25) {
1326 return 82.33;
1327 } else if (paymentPeriodInYears === 30) {
1328 return 90.9;
1329 } else if (paymentPeriodInYears === 35) {
1330 return 107.4;
1331 } else {
1332 return 132.4;
1333 }
1334 } else if (loanAmount > 50000 && loanAmount <= 100000) {
1335 if (paymentPeriodInYears === 10) {
1336 return 85.86;
1337 } else if (paymentPeriodInYears === 15) {
1338 return 86.19;
1339 } else if (paymentPeriodInYears === 20) {
1340 return 94.74;
1341 } else if (paymentPeriodInYears === 25) {
1342 return 105.79;
1343 } else if (paymentPeriodInYears === 30) {
1344 return 118.65;
1345 } else if (paymentPeriodInYears === 35) {
1346 return 143.43;
1347 } else {
1348 return 180.92;
1349 }
1350 } else if (loanAmount > 100000 && loanAmount <= 150000) {
1351 if (paymentPeriodInYears === 10) {
1352 return 119.49;
1353 } else if (paymentPeriodInYears === 15) {
1354 return 120.07
1355 } else if (paymentPeriodInYears === 20) {
1356 return 134.3;
1357 } else if (paymentPeriodInYears === 25) {
1358 return 152.71;
1359 } else if (paymentPeriodInYears === 30) {
1360 return 174.17;
1361 } else if (paymentPeriodInYears === 35) {
1362 return 215.45;
1363 } else {
1364 return 277.95;
1365 }
1366 } else if (loanAmount > 150000 && loanAmount <= 200000) {
1367 if (paymentPeriodInYears === 10) {
1368 return 153.14;
1369 } else if (paymentPeriodInYears === 15) {
1370 return 153.95;
1371 } else if (paymentPeriodInYears === 20) {
1372 return 173.88;
1373 } else if (paymentPeriodInYears === 25) {
1374 return 199.65;
1375 } else if (paymentPeriodInYears === 30) {
1376 return 229.67;
1377 } else if (paymentPeriodInYears === 35) {
1378 return 287.49;
1379 } else {
1380 return 374, 96;
1381 }
1382 } else if (loanAmount > 200000 && loanAmount <= 250000) {
1383 if (paymentPeriodInYears === 10) {
1384 return 174.58;
1385 } else if (paymentPeriodInYears === 15) {
1386 return 175.53;
1387 } else if (paymentPeriodInYears === 20) {
1388 return 199.09;
1389 } else if (paymentPeriodInYears === 25) {
1390 return 229.59;
1391 } else if (paymentPeriodInYears === 30) {
1392 return 265.09;
1393 } else if (paymentPeriodInYears === 35) {
1394 return 333.55;
1395 } else {
1396 return 437.26;
1397 }
1398 } else if (loanAmount > 250000 <= 300000) {
1399 if (paymentPeriodInYears === 10) {
1400 return 205.51;
1401 } else if (paymentPeriodInYears === 15) {
1402 return 206.67;
1403 } else if (paymentPeriodInYears === 20) {
1404 return 235.47;
1405 } else if (paymentPeriodInYears === 25) {
1406 return 272.74;
1407 } else if (paymentPeriodInYears === 30) {
1408 return 316.14;
1409 } else if (paymentPeriodInYears === 35) {
1410 return 399.8;
1411 } else {
1412 return 526.56;
1413 }
1414 } else {
1415 if (paymentPeriodInYears === 10) {
1416 return 236.44;
1417 } else if (paymentPeriodInYears === 15) {
1418 return 237.8;
1419 } else if (paymentPeriodInYears === 20) {
1420 return 271.86;
1421 } else if (paymentPeriodInYears === 25) {
1422 return 315.9;
1423 } else if (paymentPeriodInYears === 30) {
1424 return 367.2;
1425 } else if (paymentPeriodInYears === 35) {
1426 return 466.07;
1427 } else {
1428 return 615.85;
1429 }
1430 }
1431 }
1432
1433 const lumpSumForTheLegalCertaintyOffice = 1160;
1434 const flatRateDeedCosts = 1572.57;
1435 const oneTimeFileCosts = 350;
1436 const oneTimeEstimationCosts = 300;
1437 const fireInsurance = 350;
1438</script>