Quelltext des aktuellen Standes
<?php
/**
* Wiederverwendbares Bestätigungs-Modal (ersetzt natives confirm()).
*
* Nutzung im Template:
* <?php $this->insert('partials/confirm_modal'); ?> – oder per include
*
* Aufruf aus JS:
* itConfirm({ title, text, confirmLabel, confirmClass, onConfirm })
* itConfirmSubmit(buttonEl, title, text) // sendet das umschließende <form>
*/
if (defined('IT_CONFIRM_MODAL_RENDERED')) {
return;
}
define('IT_CONFIRM_MODAL_RENDERED', true);
?>
<div class="it-confirm-overlay" id="itConfirmOverlay" aria-hidden="true">
<div class="it-confirm" role="dialog" aria-modal="true" aria-labelledby="itConfirmTitle">
<div class="it-confirm-body">
<p class="it-confirm-title" id="itConfirmTitle"><?= $this->te('Bestätigen') ?></p>
<p class="it-confirm-text" id="itConfirmText"></p>
</div>
<div class="it-confirm-actions">
<button type="button" class="btn btn-default btn-sm" id="itConfirmCancel"><?= $this->te('Abbrechen') ?></button>
<button type="button" class="btn btn-danger btn-sm" id="itConfirmOk"><?= $this->te('Bestätigen') ?></button>
</div>
</div>
</div>
<style>
.it-confirm-overlay { position:fixed; inset:0; background:rgba(15,23,42,0.45); z-index:1090;
display:none; align-items:center; justify-content:center; padding:1rem; }
.it-confirm-overlay.open { display:flex; }
.it-confirm { background:var(--color-bg); border-radius:0.5rem; max-width:430px; width:100%; overflow:hidden;
box-shadow:0 20px 50px rgba(0,0,0,.3); animation:itConfirmPop .15s ease; }
@keyframes itConfirmPop { from { transform:scale(.96); opacity:0; } to { transform:scale(1); opacity:1; } }
.it-confirm-body { padding:1.4rem 1.4rem 1rem; }
.it-confirm-title { font-size:1.02rem; font-weight:700; color:var(--gray-900); margin:0 0 0.4rem; }
.it-confirm-text { font-size:0.88rem; color:var(--gray-500); margin:0; line-height:1.5; }
.it-confirm-actions { display:flex; justify-content:flex-end; gap:0.6rem; padding:0.9rem 1.4rem;
background:var(--gray-50); border-top:1px solid var(--gray-100); }
</style>
<script>
(function () {
var overlay = document.getElementById('itConfirmOverlay');
var titleEl = document.getElementById('itConfirmTitle');
var textEl = document.getElementById('itConfirmText');
var okBtn = document.getElementById('itConfirmOk');
var noBtn = document.getElementById('itConfirmCancel');
var onOk = null;
function close() { overlay.classList.remove('open'); overlay.setAttribute('aria-hidden', 'true'); onOk = null; }
window.itConfirm = function (opts) {
opts = opts || {};
titleEl.textContent = opts.title || 'Bestätigen';
textEl.textContent = opts.text || '';
okBtn.textContent = opts.confirmLabel || 'Bestätigen';
okBtn.className = 'btn btn-sm ' + (opts.confirmClass || 'btn-danger');
onOk = typeof opts.onConfirm === 'function' ? opts.onConfirm : null;
overlay.classList.add('open');
overlay.setAttribute('aria-hidden', 'false');
okBtn.focus();
};
window.itConfirmSubmit = function (btn, title, text, confirmLabel) {
var form = btn.closest('form');
if (!form) return;
window.itConfirm({
title: title, text: text, confirmLabel: confirmLabel || 'Löschen',
onConfirm: function () { form.submit(); }
});
};
okBtn.addEventListener('click', function () { var f = onOk; close(); if (f) f(); });
noBtn.addEventListener('click', close);
overlay.addEventListener('click', function (e) { if (e.target === overlay) close(); });
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && overlay.classList.contains('open')) close();
});
})();
</script>