201 lines
6.5 KiB
JavaScript
201 lines
6.5 KiB
JavaScript
/*! Icinga Web 2 | (c) 2019 Icinga GmbH | GPLv2+ */
|
|
|
|
;(function(Icinga, $) {
|
|
|
|
'use strict';
|
|
|
|
Icinga.Behaviors = Icinga.Behaviors || {};
|
|
|
|
/**
|
|
* Behavior for modal dialogs.
|
|
*
|
|
* @param icinga {Icinga} The current Icinga Object
|
|
*/
|
|
var Modal = function(icinga) {
|
|
Icinga.EventListener.call(this, icinga);
|
|
|
|
this.icinga = icinga;
|
|
this.$layout = $('#layout');
|
|
this.$ghost = $('#modal-ghost');
|
|
|
|
this.on('submit', '#modal form', this.onFormSubmit, this);
|
|
this.on('change', '#modal form select.autosubmit', this.onFormAutoSubmit, this);
|
|
this.on('change', '#modal form input.autosubmit', this.onFormAutoSubmit, this);
|
|
this.on('click', '[data-icinga-modal]', this.onModalToggleClick, this);
|
|
this.on('mousedown', '#layout > #modal', this.onModalLeave, this);
|
|
this.on('click', '.modal-header > button', this.onModalClose, this);
|
|
this.on('keydown', this.onKeyDown, this);
|
|
};
|
|
|
|
Modal.prototype = new Icinga.EventListener();
|
|
|
|
/**
|
|
* Event handler for toggling modals. Shows the link target in a modal dialog.
|
|
*
|
|
* @param event {Event} The `onClick` event triggered by the clicked modal-toggle element
|
|
* @returns {boolean}
|
|
*/
|
|
Modal.prototype.onModalToggleClick = function(event) {
|
|
var _this = event.data.self;
|
|
var $a = $(event.currentTarget);
|
|
var url = $a.attr('href');
|
|
var $modal = _this.$ghost.clone();
|
|
var $urlTarget = _this.icinga.loader.getLinkTargetFor($a, false);
|
|
|
|
// Add showCompact, we don't want controls in a modal
|
|
url = _this.icinga.utils.addUrlFlag(url, 'showCompact');
|
|
|
|
// Set the toggle's base target on the modal to use it as redirect target
|
|
$modal.data('redirectTarget', $urlTarget);
|
|
|
|
// Final preparations, the id is required so that it's not `display:none` anymore
|
|
$modal.attr('id', 'modal');
|
|
_this.$layout.append($modal);
|
|
|
|
var req = _this.icinga.loader.loadUrl(url, $modal.find('#modal-content'));
|
|
req.addToHistory = false;
|
|
req.done(function () {
|
|
_this.setTitle($modal, req.$target.data('icingaTitle').replace(/\s::\s.*/, ''));
|
|
_this.show($modal);
|
|
_this.focus($modal);
|
|
});
|
|
req.fail(function (req, _, errorThrown) {
|
|
if (req.status >= 500) {
|
|
// Yes, that's done twice (by us and by the base fail handler),
|
|
// but `renderContentToContainer` does too many useful things..
|
|
_this.icinga.loader.renderContentToContainer(req.responseText, $urlTarget, req.action);
|
|
} else if (req.status > 0) {
|
|
var msg = $(req.responseText).find('.error-message').text();
|
|
if (msg && msg !== errorThrown) {
|
|
errorThrown += ': ' + msg;
|
|
}
|
|
|
|
_this.icinga.loader.createNotice('error', errorThrown);
|
|
}
|
|
|
|
_this.hide($modal);
|
|
});
|
|
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Event handler for form submits within a modal.
|
|
*
|
|
* @param event {Event} The `submit` event triggered by a form within the modal
|
|
* @param $autoSubmittedBy {jQuery} The element triggering the auto submit, if any
|
|
* @returns {boolean}
|
|
*/
|
|
Modal.prototype.onFormSubmit = function(event, $autoSubmittedBy) {
|
|
var _this = event.data.self;
|
|
var $form = $(event.currentTarget).closest('form');
|
|
var $modal = $form.closest('#modal');
|
|
|
|
var req = _this.icinga.loader.submitForm($form, $autoSubmittedBy);
|
|
req.addToHistory = false;
|
|
req.$redirectTarget = $modal.data('redirectTarget');
|
|
req.done(function (data, textStatus, req) {
|
|
if (req.getResponseHeader('X-Icinga-Redirect')) {
|
|
_this.hide($modal);
|
|
}
|
|
});
|
|
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Event handler for form auto submits within a modal.
|
|
*
|
|
* @param event {Event} The `change` event triggered by a form input within the modal
|
|
* @returns {boolean}
|
|
*/
|
|
Modal.prototype.onFormAutoSubmit = function(event) {
|
|
return event.data.self.onFormSubmit(event, $(event.currentTarget));
|
|
};
|
|
|
|
/**
|
|
* Event handler for closing the modal. Closes it when the user clicks on the overlay.
|
|
*
|
|
* @param event {Event} The `click` event triggered by clicking on the overlay
|
|
*/
|
|
Modal.prototype.onModalLeave = function(event) {
|
|
var _this = event.data.self;
|
|
var $target = $(event.target);
|
|
|
|
if ($target.is('#modal')) {
|
|
_this.hide($target);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Event handler for closing the modal. Closes it when the user clicks on the close button.
|
|
*
|
|
* @param event {Event} The `click` event triggered by clicking on the close button
|
|
*/
|
|
Modal.prototype.onModalClose = function(event) {
|
|
var _this = event.data.self;
|
|
|
|
_this.hide($(event.currentTarget).closest('#modal'));
|
|
};
|
|
|
|
/**
|
|
* Event handler for closing the modal. Closes it when the user pushed ESC.
|
|
*
|
|
* @param event {Event} The `keydown` event triggered by pushing a key
|
|
*/
|
|
Modal.prototype.onKeyDown = function(event) {
|
|
var _this = event.data.self;
|
|
|
|
if (! event.isDefaultPrevented() && event.key === 'Escape') {
|
|
_this.hide(_this.$layout.children('#modal'));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Make final preparations and add the modal to the DOM
|
|
*
|
|
* @param $modal {jQuery} The modal element
|
|
*/
|
|
Modal.prototype.show = function($modal) {
|
|
$modal.addClass('active');
|
|
};
|
|
|
|
/**
|
|
* Set a title for the modal
|
|
*
|
|
* @param $modal {jQuery} The modal element
|
|
* @param title {string} The title
|
|
*/
|
|
Modal.prototype.setTitle = function($modal, title) {
|
|
$modal.find('.modal-header > h1').html(title);
|
|
};
|
|
|
|
/**
|
|
* Focus the modal
|
|
*
|
|
* @param $modal {jQuery} The modal element
|
|
*/
|
|
Modal.prototype.focus = function($modal) {
|
|
this.icinga.ui.focusElement($modal.find('.modal-window'));
|
|
};
|
|
|
|
/**
|
|
* Hide the modal and remove it from the DOM
|
|
*
|
|
* @param $modal {jQuery} The modal element
|
|
*/
|
|
Modal.prototype.hide = function($modal) {
|
|
$modal.removeClass('active');
|
|
// Using `setTimeout` here to let the transition finish
|
|
setTimeout(function () {
|
|
$modal.find('#modal-content').trigger('close-modal');
|
|
$modal.remove();
|
|
}, 200);
|
|
};
|
|
|
|
Icinga.Behaviors.Modal = Modal;
|
|
|
|
})(Icinga, jQuery);
|