modal.js: Prevent unintentional closing of a modal

Don't close modal if it contains changes and:
- `ESCAPE` is pressed
- User click on the overlay
This commit is contained in:
Sukhwinder Dhillon 2025-02-03 10:02:45 +01:00
parent 74369b7bf4
commit dd1f8e3e57
1 changed files with 28 additions and 2 deletions

View File

@ -17,6 +17,7 @@
this.icinga = icinga;
this.$layout = $('#layout');
this.$ghost = $('#modal-ghost');
this.hasChanges = false;
this.on('submit', '#modal form', this.onFormSubmit, this);
this.on('change', '#modal form select.autosubmit', this.onFormAutoSubmit, this);
@ -25,6 +26,7 @@
this.on('mousedown', '#layout > #modal', this.onModalLeave, this);
this.on('click', '.modal-header > button', this.onModalClose, this);
this.on('keydown', '#layout > #modal.active', this.onKeyDown, this);
this.on('change', '#modal form', this.OnChange, this);
};
Modal.prototype = new Icinga.EventListener();
@ -179,7 +181,7 @@
var _this = event.data.self;
var $target = $(event.target);
if ($target.is('#modal')) {
if (! _this.hasChanges && $target.is('#modal')) {
_this.hide($target);
}
};
@ -201,9 +203,21 @@
* @param event {Event} The `keydown` event triggered by pushing a key
*/
Modal.prototype.onKeyDown = function(event) {
if (event.key !== 'Escape') {
return;
}
var _this = event.data.self;
if (! event.isDefaultPrevented() && event.key === 'Escape') {
if (_this.hasChanges || document.activeElement.matches('form :scope')) {
if (! _this.hasChanges) {
document.activeElement.blur();
}
return;
}
if (! event.isDefaultPrevented()) {
let $modal = _this.$layout.children('#modal');
if ($modal.length) {
_this.hide($modal);
@ -211,6 +225,17 @@
}
};
/**
* Event handler to register whether the modal form has new changes after opening.
*
* This prevents the modal from being unintentionally closed
*
* @param event {Event} The `OnChange` event
*/
Modal.prototype.OnChange = function(event) {
event.data.self.hasChanges = true;
}
/**
* Make final preparations and add the modal to the DOM
*
@ -248,6 +273,7 @@
// Remove pointerEvent none style to make the button clickable again
this.modalOpener.style.pointerEvents = '';
this.modalOpener = null;
this.hasChanges = false;
$modal.removeClass('active');
// Using `setTimeout` here to let the transition finish