Loan Calculator

No meta description set.
/**
 * Loan Calculator Shortcode for WordPress
 * Shortcode:     
    
    
    
Payment Amount: 0.00
Total Interest: 0.00
Total Cost: 0.00
* Author: Senior Full-Stack Developer */ function loan_calculator_shortcode() { // Generate unique IDs for form elements $amount_id = 'loan-amount-' . wp_rand(1000, 9999); $rate_id = 'loan-rate-' . wp_rand(1000, 9999); $term_id = 'loan-term-' . wp_rand(1000, 9999); $type_id = 'loan-type-' . wp_rand(1000, 9999); ob_start(); // Start output buffering ?> <style> :root { --primary-color: var(--e-global-color-b876fc9, #6d5bff); --button-color: var(--primary-color); --font-family: var(--e-global-typography-text-font-family, 'Inter', sans-serif); } .loan-calculator-container { font-family: var(--font-family); max-width: 800px; margin: 0 auto; margin-top: 30px !important; padding: 25px; border-radius: 16px; background: rgba(255, 255, 255, 0.15); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.18); box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.15); transform: scale(0.95); opacity: 0; animation: fadeIn 0.3s ease-out forwards; } @keyframes fadeIn { to { transform: scale(1); opacity: 1; } } .loan-calculator-container h3 { margin-top: 0; color: #333; text-align: center; font-weight: 600; } .loan-input-group { margin-bottom: 20px; position: relative; } .loan-input-group label { display: block; margin-bottom: 8px; font-weight: 500; color: #555; } .loan-input-group input, .loan-input-group select { width: 100%; padding: 12px 15px; border: 1px solid #ddd; border-radius: 8px; font-size: 16px; transition: all 0.3s ease; background: rgba(255, 255, 255, 0.8); appearance: none; } .loan-input-group input:focus, .loan-input-group select:focus { border-color: var(--primary-color); box-shadow: 0 0 0 2px rgba(109, 91, 255, 0.2); outline: none; } .loan-buttons { display: flex; gap: 10px; margin-bottom: 25px; } .loan-button { flex: 1; padding: 12px; border: none; border-radius: 8px; font-size: 16px; font-weight: 500; cursor: pointer; transition: all 0.3s ease; } .loan-button.calculate { background-color: var(--button-color); color: white; } .loan-button.reset { background-color: #f0f0f0; color: #555; } .loan-button:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } .loan-button.calculate:hover { background-color: var(--primary-color); opacity: 0.9; } .loan-button.reset:hover { background-color: #e0e0e0; } .loan-results { padding: 20px; border-radius: 8px; background: rgba(109, 91, 255, 0.1); border: 1px solid rgba(109, 91, 255, 0.2); margin-bottom: 20px; display: none; } .loan-result-item { display: flex; justify-content: space-between; margin-bottom: 12px; } .loan-result-item:last-child { margin-bottom: 0; } .loan-result-label { font-weight: 500; color: #555; } .loan-result-value { font-weight: 600; color: var(--primary-color); } .loan-copy-btn { display: block; width: 100%; padding: 10px; background-color: rgba(109, 91, 255, 0.1); color: var(--primary-color); border: 1px solid var(--primary-color); border-radius: 8px; font-size: 14px; cursor: pointer; transition: all 0.3s ease; } .loan-copy-btn:hover { background-color: rgba(109, 91, 255, 0.2); } .loan-error { color: #ff4444; font-size: 13px; margin-top: 5px; display: none; } .loan-tooltip { display: inline-block; width: 16px; height: 16px; background: #ddd; border-radius: 50%; text-align: center; line-height: 16px; font-size: 11px; margin-left: 5px; cursor: help; position: relative; } .loan-tooltip-text { visibility: hidden; width: 200px; background-color: #555; color: #fff; text-align: center; border-radius: 6px; padding: 8px; position: absolute; z-index: 1; bottom: 125%; left: 50%; transform: translateX(-50%); opacity: 0; transition: opacity 0.3s; font-size: 13px; font-weight: normal; } .loan-tooltip:hover .loan-tooltip-text { visibility: visible; opacity: 1; } .loan-summary { margin-top: 15px; font-size: 14px; color: #666; line-height: 1.5; } @media (max-width: 480px) { .loan-calculator-container { padding: 20px; } .loan-buttons { flex-direction: column; } } </style> <div class="loan-calculator-container"> <div class="loan-input-group"> <label for="<?php echo esc_attr($amount_id); ?>"> <?php echo esc_html__('Loan Amount ', 'loan-calculator'); ?> <span class="loan-tooltip">? <span class="loan-tooltip-text"><?php echo esc_html__('The total amount you want to borrow', 'loan-calculator'); ?></span> </span> </label> <input type="number" id="<?php echo esc_attr($amount_id); ?>" placeholder="10000" min="100" step="100"> <div class="loan-error" id="<?php echo esc_attr($amount_id); ?>-error"></div> </div> <div class="loan-input-group"> <label for="<?php echo esc_attr($rate_id); ?>"> <?php echo esc_html__('Interest Rate (%)', 'loan-calculator'); ?> <span class="loan-tooltip">? <span class="loan-tooltip-text"><?php echo esc_html__('Annual interest rate for the loan', 'loan-calculator'); ?></span> </span> </label> <input type="number" id="<?php echo esc_attr($rate_id); ?>" placeholder="5.5" min="0.1" max="30" step="0.01"> <div class="loan-error" id="<?php echo esc_attr($rate_id); ?>-error"></div> </div> <div class="loan-input-group"> <label for="<?php echo esc_attr($term_id); ?>"> <?php echo esc_html__('Loan Term', 'loan-calculator'); ?> <span class="loan-tooltip">? <span class="loan-tooltip-text"><?php echo esc_html__('Duration of the loan in years', 'loan-calculator'); ?></span> </span> </label> <input type="number" id="<?php echo esc_attr($term_id); ?>" placeholder="5" min="1" max="30" step="1"> <div class="loan-error" id="<?php echo esc_attr($term_id); ?>-error"></div> </div> <div class="loan-input-group"> <label for="<?php echo esc_attr($type_id); ?>"> <?php echo esc_html__('Payment Frequency', 'loan-calculator'); ?> <span class="loan-tooltip">? <span class="loan-tooltip-text"><?php echo esc_html__('How often you make payments', 'loan-calculator'); ?></span> </span> </label> <select id="<?php echo esc_attr($type_id); ?>"> <option value="12"><?php echo esc_html__('Monthly', 'loan-calculator'); ?></option> <option value="26"><?php echo esc_html__('Bi-Weekly', 'loan-calculator'); ?></option> <option value="52"><?php echo esc_html__('Weekly', 'loan-calculator'); ?></option> </select> </div> <div class="loan-buttons"> <button class="loan-button calculate"><?php echo esc_html__('Calculate Payment', 'loan-calculator'); ?></button> <button class="loan-button reset"><?php echo esc_html__('Reset', 'loan-calculator'); ?></button> </div> <div class="loan-results" id="loan-results" aria-live="polite"> <div class="loan-result-item"> <span class="loan-result-label"><?php echo esc_html__('Payment Amount:', 'loan-calculator'); ?></span> <span class="loan-result-value" id="payment-amount">0.00</span> </div> <div class="loan-result-item"> <span class="loan-result-label"><?php echo esc_html__('Total Interest:', 'loan-calculator'); ?></span> <span class="loan-result-value" id="total-interest">0.00</span> </div> <div class="loan-result-item"> <span class="loan-result-label"><?php echo esc_html__('Total Cost:', 'loan-calculator'); ?></span> <span class="loan-result-value" id="total-cost">0.00</span> </div> <div class="loan-summary" id="loan-summary"></div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const amountInput = document.getElementById('<?php echo esc_js($amount_id); ?>'); const rateInput = document.getElementById('<?php echo esc_js($rate_id); ?>'); const termInput = document.getElementById('<?php echo esc_js($term_id); ?>'); const typeSelect = document.getElementById('<?php echo esc_js($type_id); ?>'); const calculateBtn = document.querySelector('.loan-button.calculate'); const resetBtn = document.querySelector('.loan-button.reset'); const resultsDiv = document.getElementById('loan-results'); const paymentAmountSpan = document.getElementById('payment-amount'); const totalInterestSpan = document.getElementById('total-interest'); const totalCostSpan = document.getElementById('total-cost'); const summaryDiv = document.getElementById('loan-summary'); const copyBtn = document.getElementById('loan-copy-btn'); // Error elements const amountError = document.getElementById('<?php echo esc_js($amount_id); ?>-error'); const rateError = document.getElementById('<?php echo esc_js($rate_id); ?>-error'); const termError = document.getElementById('<?php echo esc_js($term_id); ?>-error'); // Format currency function formatCurrency(amount) { return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'INR', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(amount); } // Calculate loan payment function calculatePayment(principal, annualRate, years, paymentsPerYear) { const ratePerPeriod = annualRate / 100 / paymentsPerYear; const totalPayments = years * paymentsPerYear; const payment = (principal * ratePerPeriod) / (1 - Math.pow(1 + ratePerPeriod, -totalPayments)); return payment; } // Animate number counting function animateValue(element, start, end, duration, isCurrency = true) { let startTimestamp = null; const step = (timestamp) => { if (!startTimestamp) startTimestamp = timestamp; const progress = Math.min((timestamp - startTimestamp) / duration, 1); const value = progress * (end - start) + start; element.textContent = isCurrency ? formatCurrency(value) : Math.round(value); if (progress < 1) { window.requestAnimationFrame(step); } }; window.requestAnimationFrame(step); } // Validate inputs function validateInputs() { let isValid = true; // Validate loan amount if (!amountInput.value || parseFloat(amountInput.value) < 100) { amountError.textContent = 'Please enter at least $100'; amountError.style.display = 'block'; isValid = false; } else { amountError.style.display = 'none'; } // Validate interest rate if (!rateInput.value || parseFloat(rateInput.value) <= 0 || parseFloat(rateInput.value) > 30) { rateError.textContent = 'Please enter rate between 0.1-30%'; rateError.style.display = 'block'; isValid = false; } else { rateError.style.display = 'none'; } // Validate loan term if (!termInput.value || parseInt(termInput.value) < 1 || parseInt(termInput.value) > 30) { termError.textContent = 'Please enter 1-30 years'; termError.style.display = 'block'; isValid = false; } else { termError.style.display = 'none'; } return isValid; } // Calculate loan function calculateLoan() { if (!validateInputs()) return; const principal = parseFloat(amountInput.value); const annualRate = parseFloat(rateInput.value); const years = parseInt(termInput.value); const paymentsPerYear = parseInt(typeSelect.value); // Calculate values const payment = calculatePayment(principal, annualRate, years, paymentsPerYear); const totalPayments = payment * years * paymentsPerYear; const totalInterest = totalPayments - principal; // Calculate percentages const interestPercent = (totalInterest / totalPayments) * 100; // Animate the results animateValue(paymentAmountSpan, 0, payment, 800); animateValue(totalInterestSpan, 0, totalInterest, 800); animateValue(totalCostSpan, principal, totalPayments, 800); // Generate summary summaryDiv.innerHTML = ` <p>For a ${years}-year loan at ${annualRate}% interest with ${paymentsPerYear === 12 ? 'monthly' : paymentsPerYear === 26 ? 'bi-weekly' : 'weekly'} payments, ${interestPercent.toFixed(1)}% of your total payment will go toward interest.</p> `; // Show results resultsDiv.style.display = 'block'; // Track usage if (typeof trackWPHUsage === 'function') { trackWPHUsage('Loan Calculator'); } } // Reset form function resetForm() { amountInput.value = ''; rateInput.value = ''; termInput.value = ''; typeSelect.value = '12'; resultsDiv.style.display = 'none'; amountError.style.display = 'none'; rateError.style.display = 'none'; termError.style.display = 'none'; summaryDiv.innerHTML = ''; } // Copy results function copyResults() { const payment = paymentAmountSpan.textContent; const interest = totalInterestSpan.textContent; const total = totalCostSpan.textContent; const summary = summaryDiv.textContent.replace(/\s+/g, ' ').trim(); const textToCopy = `Payment Amount: ${payment}\nTotal Interest: ${interest}\nTotal Cost: ${total}\n\n${summary}`; navigator.clipboard.writeText(textToCopy).then(() => { const originalText = copyBtn.textContent; copyBtn.textContent = 'Copied!'; setTimeout(() => { copyBtn.textContent = originalText; }, 2000); }); } // Event listeners calculateBtn.addEventListener('click', calculateLoan); resetBtn.addEventListener('click', resetForm); copyBtn.addEventListener('click', copyResults); // Allow Enter key to trigger calculation [amountInput, rateInput, termInput, typeSelect].forEach(input => { input.addEventListener('keypress', (e) => { if (e.key === 'Enter') { calculateLoan(); } }); }); }); </script> <?php return ob_get_clean(); } add_shortcode('loan_calculator', 'loan_calculator_shortcode');