// Custom JavaScript for Delphi Database document.addEventListener('DOMContentLoaded', function() { // Initialize tooltips if any if (window.bootstrap && bootstrap.Tooltip) { var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); tooltipTriggerList.forEach(function (tooltipTriggerEl) { new bootstrap.Tooltip(tooltipTriggerEl); }); } // Auto-hide alerts after 5 seconds var alerts = document.querySelectorAll('.alert:not(.alert-permanent)'); alerts.forEach(function(alert) { setTimeout(function() { var bsAlert = new bootstrap.Alert(alert); bsAlert.close(); }, 5000); }); // Confirm delete actions var deleteButtons = document.querySelectorAll('[data-confirm-delete]'); deleteButtons.forEach(function(button) { button.addEventListener('click', function(e) { var message = this.getAttribute('data-confirm-delete') || 'Are you sure you want to delete this item?'; if (!confirm(message)) { e.preventDefault(); } }); }); // Form validation enhancement var forms = document.querySelectorAll('.needs-validation'); Array.prototype.slice.call(forms).forEach(function(form) { form.addEventListener('submit', function(event) { if (!form.checkValidity()) { event.preventDefault(); event.stopPropagation(); } form.classList.add('was-validated'); }, false); }); // Dynamic form field enabling/disabling var toggleFields = document.querySelectorAll('[data-toggle-field]'); toggleFields.forEach(function(element) { element.addEventListener('change', function() { var targetSelector = this.getAttribute('data-toggle-field'); var targetField = document.querySelector(targetSelector); if (targetField) { targetField.disabled = !this.checked; } }); }); // Auto-compute Amount = Quantity × Rate in ledger add form var qtyInput = document.querySelector('form[action*="/ledger"] .js-qty'); var rateInput = document.querySelector('form[action*="/ledger"] .js-rate'); var amountInput = document.querySelector('form[action*="/ledger"] .js-amount'); function recomputeAmount() { if (!qtyInput || !rateInput || !amountInput) return; var q = parseFloat(qtyInput.value); var r = parseFloat(rateInput.value); if (!isNaN(q) && !isNaN(r)) { var amt = (q * r); amountInput.value = amt.toFixed(2); } } if (qtyInput) qtyInput.addEventListener('input', recomputeAmount); if (rateInput) rateInput.addEventListener('input', recomputeAmount); // Generic select-all for answer tables document.querySelectorAll('.js-answer-table').forEach(function(form) { var selectAll = form.querySelector('.js-select-all'); if (!selectAll) return; selectAll.addEventListener('change', function() { var checkboxes = form.querySelectorAll('input[type="checkbox"][name]'); checkboxes.forEach(function(cb) { if (cb !== selectAll) cb.checked = selectAll.checked; }); }); }); // Submit selection to alternate endpoints using data-action document.querySelectorAll('.js-submit-to').forEach(function(link) { link.addEventListener('click', function(e) { e.preventDefault(); var container = link.closest('.table-responsive') || document; var form = container.querySelector('form.js-answer-table'); if (!form) form = document.querySelector('form.js-answer-table'); if (!form) return; var original = form.getAttribute('action'); var action = link.getAttribute('data-action'); if (action) form.setAttribute('action', action); try { form.submit(); } finally { if (original) form.setAttribute('action', original); } }); }); // Field help: show contextual help from data-help on focus function attachFieldHelp(container) { if (!container) return; var helpEl = container.querySelector('#fieldHelp'); if (!helpEl) return; container.querySelectorAll('input, select, textarea').forEach(function(field) { field.addEventListener('focus', function() { var text = field.getAttribute('data-help'); if (text) helpEl.textContent = text; }); field.addEventListener('blur', function() { // Optionally keep last help, or reset }); }); } // Attach help to known forms/sections document.querySelectorAll('form').forEach(function(form) { attachFieldHelp(form.closest('.card-body') || form); }); }); // Utility functions function formatDate(dateString) { if (!dateString) return ''; var date = new Date(dateString); return date.toLocaleDateString(); } function formatCurrency(amount) { if (!amount) return '$0.00'; return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount); } function showLoading(button) { if (button) { button.disabled = true; button.innerHTML = 'Loading...'; } } function hideLoading(button, originalText) { if (button) { button.disabled = false; button.innerHTML = originalText; } }