diff --git a/source/packages/com_mokosuitebackup/tmpl/profile/edit.php b/source/packages/com_mokosuitebackup/tmpl/profile/edit.php index 85ccad8..5ec55d5 100644 --- a/source/packages/com_mokosuitebackup/tmpl/profile/edit.php +++ b/source/packages/com_mokosuitebackup/tmpl/profile/edit.php @@ -17,6 +17,7 @@ use Joomla\CMS\Session\Session; HTMLHelper::_('behavior.formvalidator'); HTMLHelper::_('behavior.keepalive'); +HTMLHelper::_('bootstrap.modal'); $profileId = (int) $this->item->id; $token = Session::getFormToken(); @@ -274,7 +275,11 @@ document.addEventListener('DOMContentLoaded', function() { const emptyMsg = document.getElementById('remoteDestEmpty'); const loadingTr = document.getElementById('remoteDestLoading'); const modalEl = document.getElementById('remoteModal'); - const modal = bootstrap.Modal.getOrCreateInstance(modalEl); + // Lazy: resolve the Bootstrap modal at click-time. Bootstrap loads as a + // deferred ES module, so `bootstrap` is not defined yet at DOMContentLoaded; + // referencing it here would throw and abort the whole handler (leaving the + // table stuck at "Loading…" and the Add button unbound). + const getModal = () => bootstrap.Modal.getOrCreateInstance(modalEl); // Type badge colours const typeBadge = {sftp: 'bg-primary', s3: 'bg-warning text-dark', google_drive: 'bg-success'}; @@ -507,7 +512,7 @@ document.addEventListener('DOMContentLoaded', function() { } updateTypeFields(); - modal.show(); + getModal().show(); } // ---- Type selector toggles field visibility ---- @@ -587,7 +592,7 @@ document.addEventListener('DOMContentLoaded', function() { return; } - modal.hide(); + getModal().hide(); loadRemotes(); }) .catch(() => {