/** * Modal Alerts - Bootstrap Modal replacement for native alert() and confirm() * Fixes Chrome auto-dismiss issue with native dialogs * * Usage: * showAlert('Message', 'success'); * showConfirm('Delete this?', function() { }); */ (function () { 'use strict'; // Create and inject modal HTML into page if not already present function ensureModalsExist() { if (document.getElementById('globalAlertModal')) { return; // Already exists } const modalsHTML = ` `; // Inject modals at end of body document.body.insertAdjacentHTML('beforeend', modalsHTML); } /** * Show an alert message using Bootstrap modal * @param {string} message - The message to display * @param {string|object} typeOrOptions - Type ('success', 'error', 'warning', 'info') or options object * @param {string} title - Optional custom title */ window.showAlert = function (message, typeOrOptions, title) { ensureModalsExist(); let type = 'info'; let isHtml = false; if (typeof typeOrOptions === 'object' && typeOrOptions !== null) { type = typeOrOptions.type || 'info'; isHtml = typeOrOptions.isHtml || false; title = typeOrOptions.title || title; } else if (typeof typeOrOptions === 'string') { type = typeOrOptions; } const modal = document.getElementById('globalAlertModal'); const header = document.getElementById('globalAlertModalHeader'); const titleEl = document.getElementById('globalAlertModalTitle'); const bodyEl = document.getElementById('globalAlertModalBody'); const iconEl = document.getElementById('globalAlertModalIcon'); // Configuration for different types const types = { 'success': { title: 'Success', icon: 'fa-check-circle', headerClass: 'bg-success text-white', btnClose: 'btn-close-white' }, 'error': { title: 'Error', icon: 'fa-exclamation-triangle', headerClass: 'bg-danger text-white', btnClose: 'btn-close-white' }, 'warning': { title: 'Warning', icon: 'fa-exclamation-circle', headerClass: 'bg-warning text-dark', btnClose: '' }, 'info': { title: 'Notice', icon: 'fa-info-circle', headerClass: 'bg-info text-white', btnClose: 'btn-close-white' } }; const config = types[type] || types['info']; // Update header styling header.className = 'modal-header ' + config.headerClass; const closeBtn = header.querySelector('.btn-close'); closeBtn.className = 'btn-close ' + config.btnClose; // Update icon iconEl.className = 'fas ' + config.icon + ' me-2'; // Update title titleEl.textContent = title || config.title; // Update body - support HTML or text if (isHtml || message.includes('

') || message.includes('