| |
| <?php
|
| <?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function mortgage_calculator_shortcode() {
|
| ob_start();
|
| ?>
|
| <style>
|
| .mc-wrap { max-width: 720px; margin: 0 auto; padding: 1rem 0; font-size: 15px; font-family: inherit; }
|
| .mc-card { background:
|
| .mc-section-title { font-size: 12px; font-weight: 600; color:
|
| .mc-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
|
| .mc-grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; }
|
| .mc-field { display: flex; flex-direction: column; gap: 4px; }
|
| .mc-field label { font-size: 13px; color:
|
| .mc-input-wrap { position: relative; }
|
| .mc-input-wrap .mc-prefix { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); font-size: 14px; color:
|
| .mc-input-wrap .mc-suffix { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); font-size: 14px; color:
|
| .mc-input-wrap input { padding-left: 22px; width: 100%; box-sizing: border-box; }
|
| .mc-input-wrap.mc-pct input { padding-left: 10px; padding-right: 28px; }
|
| .mc-wrap input[type="number"],
|
| .mc-wrap input[type="text"] {
|
| width: 100%;
|
| box-sizing: border-box;
|
| border: 1px solid
|
| border-radius: 8px;
|
| padding: 8px 10px;
|
| font-size: 14px;
|
| color:
|
| background:
|
| outline: none;
|
| transition: border-color 0.15s;
|
| }
|
| .mc-wrap input[type="number"]:focus { border-color:
|
| .mc-toggle-row { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
|
| .mc-toggle-row label { font-size: 14px; color:
|
| .mc-wrap input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; accent-color:
|
| .mc-btn {
|
| width: 100%;
|
| padding: 11px;
|
| font-size: 15px;
|
| font-weight: 500;
|
| background:
|
| color:
|
| border: 1px solid
|
| border-radius: 8px;
|
| cursor: pointer;
|
| margin-top: 0.25rem;
|
| transition: background 0.15s;
|
| }
|
| .mc-btn:hover { background:
|
| .mc-results { display: none; margin-top: 1rem; }
|
| .mc-results.mc-visible { display: block; }
|
| .mc-metrics { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-bottom: 1rem; }
|
| .mc-metric { background:
|
| .mc-metric .mc-mlabel { font-size: 12px; color:
|
| .mc-metric .mc-mval { font-size: 20px; font-weight: 500; color:
|
| .mc-metric .mc-mval.mc-total { color:
|
| .mc-breakdown { border-top: 1px solid
|
| .mc-brow { display: flex; justify-content: space-between; padding: 6px 0; font-size: 14px; border-bottom: 1px solid
|
| .mc-brow:last-child { border-bottom: none; font-weight: 600; }
|
| .mc-brow span:first-child { color:
|
| @media (max-width: 540px) {
|
| .mc-grid-2, .mc-grid-3, .mc-metrics { grid-template-columns: 1fr; }
|
| }
|
| </style>
|
|
|
| <div class="mc-wrap">
|
|
|
| <!-- Loan Details -->
|
| <div class="mc-card">
|
| <p class="mc-section-title">Loan details</p>
|
| <div class="mc-grid-2" style="margin-bottom:12px;">
|
| <div class="mc-field">
|
| <label for="mc_principal">Loan amount</label>
|
| <div class="mc-input-wrap">
|
| <span class="mc-prefix">$</span>
|
| <input type="number" id="mc_principal" placeholder="300000" min="0" step="1000">
|
| </div>
|
| </div>
|
| <div class="mc-field">
|
| <label for="mc_term">Loan term (years)</label>
|
| <input type="number" id="mc_term" placeholder="30" min="1" max="50">
|
| </div>
|
| </div>
|
| <div class="mc-grid-2">
|
| <div class="mc-field">
|
| <label for="mc_rate">Interest rate</label>
|
| <div class="mc-input-wrap mc-pct">
|
| <input type="number" id="mc_rate" placeholder="6.75" min="0" max="30" step="0.01">
|
| <span class="mc-suffix">%</span>
|
| </div>
|
| </div>
|
| <div class="mc-field" style="justify-content:flex-end; padding-bottom:4px;">
|
| <div class="mc-toggle-row">
|
| <input type="checkbox" id="mc_interest_only">
|
| <label for="mc_interest_only">Interest-only payment</label>
|
| </div>
|
| </div>
|
| </div>
|
| </div>
|
|
|
| <!-- Monthly Escrow -->
|
| <div class="mc-card">
|
| <p class="mc-section-title">Monthly escrow</p>
|
| <div class="mc-grid-3">
|
| <div class="mc-field">
|
| <label for="mc_insurance">Homeowner's insurance</label>
|
| <div class="mc-input-wrap">
|
| <span class="mc-prefix">$</span>
|
| <input type="number" id="mc_insurance" placeholder="150" min="0">
|
| </div>
|
| </div>
|
| <div class="mc-field">
|
| <label for="mc_taxes">Real estate taxes</label>
|
| <div class="mc-input-wrap">
|
| <span class="mc-prefix">$</span>
|
| <input type="number" id="mc_taxes" placeholder="400" min="0">
|
| </div>
|
| </div>
|
| <div class="mc-field">
|
| <label for="mc_pmi">Mortgage insurance (PMI)</label>
|
| <div class="mc-input-wrap">
|
| <span class="mc-prefix">$</span>
|
| <input type="number" id="mc_pmi" placeholder="0" min="0">
|
| </div>
|
| </div>
|
| </div>
|
| </div>
|
|
|
| <!-- Second Mortgage -->
|
| <div class="mc-card">
|
| <p class="mc-section-title">Second mortgage (optional)</p>
|
| <div class="mc-grid-3">
|
| <div class="mc-field">
|
| <label for="mc_second_bal">Balance</label>
|
| <div class="mc-input-wrap">
|
| <span class="mc-prefix">$</span>
|
| <input type="number" id="mc_second_bal" placeholder="0" min="0">
|
| </div>
|
| </div>
|
| <div class="mc-field">
|
| <label for="mc_second_rate">Interest rate</label>
|
| <div class="mc-input-wrap mc-pct">
|
| <input type="number" id="mc_second_rate" placeholder="8.0" min="0" max="30" step="0.01">
|
| <span class="mc-suffix">%</span>
|
| </div>
|
| </div>
|
| <div class="mc-field">
|
| <label for="mc_second_term">Term (years)</label>
|
| <input type="number" id="mc_second_term" placeholder="15" min="1" max="30">
|
| </div>
|
| </div>
|
| </div>
|
|
|
| <button class="mc-btn" onclick="mcCalculate()">Calculate payment</button>
|
|
|
| <!-- Results -->
|
| <div class="mc-results mc-card" id="mc_results">
|
| <p class="mc-section-title">Payment breakdown</p>
|
| <div class="mc-metrics">
|
| <div class="mc-metric">
|
| <p class="mc-mlabel">Principal & interest</p>
|
| <p class="mc-mval" id="mc_res_pi">—</p>
|
| </div>
|
| <div class="mc-metric">
|
| <p class="mc-mlabel">Escrow (taxes + ins + PMI)</p>
|
| <p class="mc-mval" id="mc_res_escrow">—</p>
|
| </div>
|
| <div class="mc-metric">
|
| <p class="mc-mlabel">Total monthly payment</p>
|
| <p class="mc-mval mc-total" id="mc_res_total">—</p>
|
| </div>
|
| </div>
|
| <div class="mc-breakdown" id="mc_breakdown"></div>
|
| </div>
|
|
|
| </div>
|
|
|
| <script>
|
| function mcFmt(n) {
|
| return '$' + n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
| }
|
| function mcCalcPI(principal, annualRate, years, interestOnly) {
|
| if (!principal || !annualRate) return principal * (annualRate / 1200) || 0;
|
| var r = annualRate / 1200;
|
| if (interestOnly) return principal * r;
|
| var n = years * 12;
|
| return principal * (r * Math.pow(1 + r, n)) / (Math.pow(1 + r, n) - 1);
|
| }
|
| function mcCalculate() {
|
| var principal = parseFloat(document.getElementById('mc_principal').value) || 0;
|
| var rate = parseFloat(document.getElementById('mc_rate').value) || 0;
|
| var term = parseFloat(document.getElementById('mc_term').value) || 30;
|
| var io = document.getElementById('mc_interest_only').checked;
|
| var insurance = parseFloat(document.getElementById('mc_insurance').value) || 0;
|
| var taxes = parseFloat(document.getElementById('mc_taxes').value) || 0;
|
| var pmi = parseFloat(document.getElementById('mc_pmi').value) || 0;
|
| var secondBal = parseFloat(document.getElementById('mc_second_bal').value) || 0;
|
| var secondRate = parseFloat(document.getElementById('mc_second_rate').value) || 0;
|
| var secondTerm = parseFloat(document.getElementById('mc_second_term').value) || 15;
|
|
|
| var pi1 = mcCalcPI(principal, rate, term, io);
|
| var pi2 = secondBal > 0 ? mcCalcPI(secondBal, secondRate, secondTerm, false) : 0;
|
| var escrow = insurance + taxes + pmi;
|
| var total = pi1 + pi2 + escrow;
|
|
|
| document.getElementById('mc_res_pi').textContent = mcFmt(pi1 + pi2);
|
| document.getElementById('mc_res_escrow').textContent = mcFmt(escrow);
|
| document.getElementById('mc_res_total').textContent = mcFmt(total);
|
|
|
| var rows = [
|
| ['P&I — 1st mortgage' + (io ? ' (interest only)' : ''), pi1]
|
| ];
|
| if (pi2 > 0) rows.push(['P&I — 2nd mortgage', pi2]);
|
| if (insurance > 0) rows.push(["Homeowner's insurance", insurance]);
|
| if (taxes > 0) rows.push(['Real estate taxes', taxes]);
|
| if (pmi > 0) rows.push(['Mortgage insurance (PMI)', pmi]);
|
| rows.push(['Total monthly payment', total]);
|
|
|
| var html = '';
|
| rows.forEach(function(row, i) {
|
| html += '<div class="mc-brow"><span>' + row[0] + '</span><span>' + mcFmt(row[1]) + '</span></div>';
|
| });
|
| document.getElementById('mc_breakdown').innerHTML = html;
|
| document.getElementById('mc_results').classList.add('mc-visible');
|
| }
|
| </script>
|
| <?php
|
| return ob_get_clean();
|
| }
|
| add_shortcode( 'mortgage_calculator', 'mortgage_calculator_shortcode' );
|
| |
| |
Comments