Files
delphi-database-v2/static/js/custom.js
HotSwapp aeb0be6982 feat(reports): add Envelope, Phone Book (address+phone) and Rolodex Info reports
- PDF builders in app/reporting.py (envelope, phone+address, rolodex info)
- Endpoints in app/main.py with auth, filtering, logging, Content-Disposition
- New HTML template report_phone_book_address.html
- Rolodex bulk actions updated with buttons/links
- JS helper to submit selections to alternate endpoints

Tested via docker compose build/up and health check.
2025-10-07 17:50:03 -05:00

153 lines
5.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Custom JavaScript for Delphi Database
document.addEventListener('DOMContentLoaded', function() {
// Initialize tooltips if any
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return 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 = '<span class="spinner-border spinner-border-sm me-2"></span>Loading...';
}
}
function hideLoading(button, originalText) {
if (button) {
button.disabled = false;
button.innerHTML = originalText;
}
}