2015-02-04 10:46:36 +01:00
|
|
|
/*! Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
2014-07-15 13:39:22 +02:00
|
|
|
|
2014-03-06 13:01:52 +01:00
|
|
|
/**
|
|
|
|
* Icinga.Events
|
|
|
|
*
|
|
|
|
* Event handlers
|
|
|
|
*/
|
|
|
|
(function (Icinga, $) {
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
Icinga.Events = function (icinga) {
|
|
|
|
this.icinga = icinga;
|
2014-05-20 16:07:19 +02:00
|
|
|
|
|
|
|
this.searchValue = '';
|
2014-03-06 13:01:52 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
Icinga.Events.prototype = {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Icinga will call our initialize() function once it's ready
|
|
|
|
*/
|
|
|
|
initialize: function () {
|
|
|
|
this.applyGlobalDefaults();
|
2014-09-12 09:09:21 +02:00
|
|
|
$('#layout').trigger('rendered');
|
|
|
|
//$('.container').trigger('rendered');
|
2014-09-09 18:45:16 +02:00
|
|
|
$('.container').each(function(idx, el) {
|
|
|
|
icinga.ui.initializeControls($(el));
|
|
|
|
});
|
2014-03-06 13:01:52 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
// TODO: What's this?
|
2014-09-12 09:09:21 +02:00
|
|
|
applyHandlers: function (evt) {
|
|
|
|
var el = $(evt.target), self = evt.data.self;
|
|
|
|
var icinga = self.icinga;
|
2014-03-06 13:01:52 +01:00
|
|
|
|
|
|
|
$('.dashboard > div', el).each(function(idx, el) {
|
2014-03-17 17:10:03 +01:00
|
|
|
var url = $(el).data('icingaUrl');
|
2014-03-06 13:01:52 +01:00
|
|
|
if (typeof url === 'undefined') return;
|
|
|
|
icinga.loader.loadUrl(url, $(el)).autorefresh = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
// Set first links href in a action table tr as row href:
|
|
|
|
$('table.action tr', el).each(function(idx, el) {
|
|
|
|
var $a = $('a[href]', el).first();
|
|
|
|
if ($a.length) {
|
2014-03-17 17:10:03 +01:00
|
|
|
// TODO: Find out whether we leak memory on IE with this:
|
2014-03-06 13:01:52 +01:00
|
|
|
$(el).attr('href', $a.attr('href'));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2014-09-03 17:42:31 +02:00
|
|
|
$('td.state span.timesince').attr('title', null);
|
|
|
|
|
2014-06-05 17:03:59 +02:00
|
|
|
var moduleName = el.data('icingaModule');
|
|
|
|
if (moduleName) {
|
2014-03-20 10:58:28 +01:00
|
|
|
if (icinga.hasModule(moduleName)) {
|
|
|
|
var module = icinga.module(moduleName);
|
|
|
|
// NOT YET, the applyOnloadDings: module.applyEventHandlers(mod);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-06 13:01:52 +01:00
|
|
|
$('.icinga-module', el).each(function(idx, mod) {
|
|
|
|
var $mod = $(mod);
|
2014-03-20 10:58:28 +01:00
|
|
|
moduleName = $mod.data('icingaModule');
|
2014-03-06 13:01:52 +01:00
|
|
|
if (icinga.hasModule(moduleName)) {
|
|
|
|
var module = icinga.module(moduleName);
|
|
|
|
// NOT YET, the applyOnloadDings: module.applyEventHandlers(mod);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2014-05-20 23:55:32 +02:00
|
|
|
var searchField = $('#menu input.search', el);
|
|
|
|
// Remember initial search field value if any
|
|
|
|
if (searchField.length && searchField.val().length) {
|
2014-09-12 09:09:21 +02:00
|
|
|
self.searchValue = searchField.val();
|
2014-05-20 23:55:32 +02:00
|
|
|
}
|
2014-10-01 14:51:51 +02:00
|
|
|
|
|
|
|
if (icinga.ui.isOneColLayout()) {
|
|
|
|
icinga.ui.disableCloseButtons();
|
|
|
|
} else {
|
|
|
|
icinga.ui.enableCloseButtons();
|
|
|
|
}
|
2014-03-06 13:01:52 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Global default event handlers
|
|
|
|
*/
|
|
|
|
applyGlobalDefaults: function () {
|
2014-09-10 10:44:22 +02:00
|
|
|
$.each(self.icinga.behaviors, function (name, behavior) {
|
2014-09-12 09:09:21 +02:00
|
|
|
behavior.bind($(document));
|
2014-09-10 10:44:22 +02:00
|
|
|
});
|
|
|
|
|
2014-09-12 09:09:21 +02:00
|
|
|
// Apply element-specific behavior whenever the layout is rendered
|
|
|
|
$(document).on('rendered', { self: this }, this.applyHandlers);
|
|
|
|
|
2014-03-06 13:01:52 +01:00
|
|
|
// We catch resize events
|
|
|
|
$(window).on('resize', { self: this.icinga.ui }, this.icinga.ui.onWindowResize);
|
|
|
|
|
2014-04-01 10:40:38 +02:00
|
|
|
// Trigger 'rendered' event also on page loads
|
|
|
|
$(window).on('load', { self: this }, this.onLoad);
|
|
|
|
|
2014-03-06 13:01:52 +01:00
|
|
|
// Destroy Icinga, clean up and interrupt pending requests on unload
|
|
|
|
$( window ).on('unload', { self: this }, this.onUnload);
|
2015-04-16 21:01:08 +02:00
|
|
|
$( window ).on('beforeunload', { self: this }, this.onUnload);
|
2014-03-06 13:01:52 +01:00
|
|
|
|
|
|
|
// We catch scroll events in our containers
|
2014-06-05 17:03:59 +02:00
|
|
|
$('.container').on('scroll', { self: this }, this.icinga.events.onContainerScroll);
|
2014-03-06 13:01:52 +01:00
|
|
|
|
|
|
|
// We want to catch each link click
|
|
|
|
$(document).on('click', 'a', { self: this }, this.linkClicked);
|
2014-05-09 16:53:34 +02:00
|
|
|
$(document).on('click', 'tr[href]', { self: this }, this.linkClicked);
|
2014-03-06 13:01:52 +01:00
|
|
|
|
2014-04-09 19:11:56 +02:00
|
|
|
// Select a table row
|
2014-05-09 16:53:34 +02:00
|
|
|
$(document).on('click', 'table.multiselect tr[href]', { self: this }, this.rowSelected);
|
2014-03-06 13:01:52 +01:00
|
|
|
|
|
|
|
// We catch all form submit events
|
|
|
|
$(document).on('submit', 'form', { self: this }, this.submitForm);
|
|
|
|
|
|
|
|
// We support an 'autosubmit' class on dropdown form elements
|
2014-03-09 23:38:55 +01:00
|
|
|
$(document).on('change', 'form select.autosubmit', { self: this }, this.autoSubmitForm);
|
2014-06-20 14:32:22 +02:00
|
|
|
$(document).on('change', 'form input.autosubmit', { self: this }, this.autoSubmitForm);
|
2014-03-06 13:01:52 +01:00
|
|
|
|
2015-03-06 15:41:25 +01:00
|
|
|
// Automatically check a radio button once a specific input is focused
|
|
|
|
$(document).on('focus', 'form select[data-related-radiobtn]', { self: this }, this.autoCheckRadioButton);
|
|
|
|
$(document).on('focus', 'form input[data-related-radiobtn]', { self: this }, this.autoCheckRadioButton);
|
|
|
|
|
2014-05-20 16:07:19 +02:00
|
|
|
$(document).on('keyup', '#menu input.search', {self: this}, this.autoSubmitSearch);
|
2014-03-06 13:01:52 +01:00
|
|
|
|
2014-03-17 17:17:10 +01:00
|
|
|
$(document).on('click', '.tree .handle', { self: this }, this.treeNodeToggle);
|
|
|
|
|
2014-03-06 13:01:52 +01:00
|
|
|
// TBD: a global autocompletion handler
|
|
|
|
// $(document).on('keyup', 'form.auto input', this.formChangeDelayed);
|
|
|
|
// $(document).on('change', 'form.auto input', this.formChanged);
|
|
|
|
// $(document).on('change', 'form.auto select', this.submitForm);
|
|
|
|
},
|
|
|
|
|
2014-03-24 10:22:20 +01:00
|
|
|
treeNodeToggle: function () {
|
2014-03-20 10:58:28 +01:00
|
|
|
var $parent = $(this).closest('li');
|
|
|
|
if ($parent.hasClass('collapsed')) {
|
|
|
|
$('li', $parent).addClass('collapsed');
|
|
|
|
$parent.removeClass('collapsed');
|
|
|
|
} else {
|
|
|
|
$parent.addClass('collapsed');
|
|
|
|
}
|
2014-03-17 17:17:10 +01:00
|
|
|
},
|
|
|
|
|
2014-04-01 10:40:38 +02:00
|
|
|
onLoad: function (event) {
|
2014-09-12 09:09:21 +02:00
|
|
|
//$('.container').trigger('rendered');
|
2014-04-01 10:40:38 +02:00
|
|
|
},
|
|
|
|
|
2014-03-06 13:01:52 +01:00
|
|
|
onUnload: function (event) {
|
|
|
|
var icinga = event.data.self.icinga;
|
|
|
|
icinga.logger.info('Unloading Icinga');
|
|
|
|
icinga.destroy();
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A scroll event happened in one of our containers
|
|
|
|
*/
|
|
|
|
onContainerScroll: function (event) {
|
|
|
|
// Ugly. And PLEASE, not so often
|
|
|
|
icinga.ui.fixControls();
|
|
|
|
},
|
|
|
|
|
2015-03-06 15:41:25 +01:00
|
|
|
autoCheckRadioButton: function (event) {
|
|
|
|
var $input = $(event.currentTarget);
|
|
|
|
var $radio = $('#' + $input.attr('data-related-radiobtn'));
|
|
|
|
if ($radio.length) {
|
|
|
|
$radio.prop('checked', true);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
|
2014-05-20 16:07:19 +02:00
|
|
|
autoSubmitSearch: function(event) {
|
|
|
|
var self = event.data.self;
|
|
|
|
if ($('#menu input.search').val() === self.searchValue) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
self.searchValue = $('#menu input.search').val();
|
|
|
|
return self.autoSubmitForm(event);
|
|
|
|
},
|
|
|
|
|
2014-03-09 23:38:55 +01:00
|
|
|
autoSubmitForm: function (event) {
|
|
|
|
return event.data.self.submitForm(event, true);
|
|
|
|
},
|
|
|
|
|
2014-03-06 13:01:52 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2014-03-09 23:38:55 +01:00
|
|
|
submitForm: function (event, autosubmit) {
|
2014-11-20 11:07:10 +01:00
|
|
|
//return false;
|
2014-03-08 15:25:10 +01:00
|
|
|
var self = event.data.self;
|
|
|
|
var icinga = self.icinga;
|
2014-03-06 13:01:52 +01:00
|
|
|
// .closest is not required unless subelements to trigger this
|
|
|
|
var $form = $(event.currentTarget).closest('form');
|
2014-03-25 08:44:24 +01:00
|
|
|
var regex = new RegExp('&', 'g');
|
|
|
|
var url = $form.attr('action').replace(regex, '&'); // WHY??
|
2014-03-06 13:01:52 +01:00
|
|
|
var method = $form.attr('method');
|
2014-05-21 01:55:18 +02:00
|
|
|
var $button = $('input[type=submit]:focus', $form).add('button[type=submit]:focus', $form);
|
2014-03-08 15:25:10 +01:00
|
|
|
var $target;
|
2014-03-26 08:48:22 +01:00
|
|
|
var data;
|
2014-03-08 15:25:10 +01:00
|
|
|
|
2014-11-07 14:22:03 +01:00
|
|
|
if ($button.length === 0) {
|
2014-11-20 11:07:10 +01:00
|
|
|
var $el;
|
|
|
|
|
|
|
|
if (typeof event.originalEvent !== 'undefined'
|
|
|
|
&& typeof event.originalEvent.explicitOriginalTarget === 'object') { // Firefox
|
|
|
|
$el = $(event.originalEvent.explicitOriginalTarget);
|
2015-02-02 21:56:14 +01:00
|
|
|
icinga.logger.debug('events/submitForm: Button is event.originalEvent.explicitOriginalTarget');
|
2014-11-20 11:07:10 +01:00
|
|
|
} else {
|
|
|
|
$el = $(event.currentTarget);
|
2015-02-02 21:56:14 +01:00
|
|
|
icinga.logger.debug('events/submitForm: Button is event.currentTarget');
|
2014-11-20 11:07:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if ($el && ($el.is('input[type=submit]') || $el.is('button[type=submit]'))) {
|
2014-11-07 14:22:03 +01:00
|
|
|
$button = $el;
|
2014-11-20 11:07:10 +01:00
|
|
|
} else {
|
2015-02-02 21:56:14 +01:00
|
|
|
icinga.logger.debug(
|
2014-11-20 11:07:10 +01:00
|
|
|
'events/submitForm: Can not determine submit button, using the first one in form'
|
|
|
|
);
|
2014-11-07 14:22:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-25 13:13:42 +01:00
|
|
|
if (typeof method === 'undefined') {
|
|
|
|
method = 'POST';
|
|
|
|
} else {
|
|
|
|
method = method.toUpperCase();
|
|
|
|
}
|
|
|
|
|
2014-03-28 15:53:37 +01:00
|
|
|
if ($button.length === 0) {
|
2014-11-07 14:22:03 +01:00
|
|
|
$button = $('input[type=submit]', $form).add('button[type=submit]', $form).first();
|
2014-03-28 15:53:37 +01:00
|
|
|
}
|
|
|
|
|
2014-03-08 15:25:10 +01:00
|
|
|
event.stopPropagation();
|
|
|
|
event.preventDefault();
|
|
|
|
|
2015-03-12 11:30:21 +01:00
|
|
|
if ($button.length) {
|
2015-03-13 04:02:42 +01:00
|
|
|
// Activate spinner
|
2015-03-12 11:30:21 +01:00
|
|
|
if ($button.hasClass('spinner')) {
|
|
|
|
$button.addClass('active');
|
|
|
|
}
|
|
|
|
|
|
|
|
$target = self.getLinkTargetFor($button);
|
|
|
|
} else {
|
|
|
|
$target = self.getLinkTargetFor($form);
|
|
|
|
}
|
2014-03-25 13:13:42 +01:00
|
|
|
|
2015-03-13 04:02:42 +01:00
|
|
|
if (! url) {
|
|
|
|
// Use the URL of the target container if the form's action is not set
|
|
|
|
url = $target.closest('.container').data('icinga-url');
|
|
|
|
}
|
|
|
|
|
|
|
|
icinga.logger.debug('Submitting form: ' + method + ' ' + url, method);
|
|
|
|
|
2014-03-25 13:13:42 +01:00
|
|
|
if (method === 'GET') {
|
2014-08-12 12:49:03 +02:00
|
|
|
var dataObj = $form.serializeObject();
|
|
|
|
|
|
|
|
if (typeof autosubmit === 'undefined' || ! autosubmit) {
|
|
|
|
if ($button.length && $button.attr('name') !== 'undefined') {
|
|
|
|
dataObj[$button.attr('name')] = $button.attr('value');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
url = icinga.utils.addUrlParams(url, dataObj);
|
2014-03-25 13:13:42 +01:00
|
|
|
} else {
|
2014-03-26 08:48:22 +01:00
|
|
|
data = $form.serializeArray();
|
|
|
|
|
|
|
|
if (typeof autosubmit === 'undefined' || ! autosubmit) {
|
2014-08-12 12:49:03 +02:00
|
|
|
if ($button.length && $button.attr('name') !== 'undefined') {
|
2014-03-28 15:53:37 +01:00
|
|
|
data.push({
|
|
|
|
name: $button.attr('name'),
|
|
|
|
value: $button.attr('value')
|
|
|
|
});
|
|
|
|
}
|
2014-03-26 08:48:22 +01:00
|
|
|
}
|
2014-03-25 13:13:42 +01:00
|
|
|
}
|
2015-03-13 04:02:42 +01:00
|
|
|
|
2014-03-26 08:48:22 +01:00
|
|
|
icinga.loader.loadUrl(url, $target, data, method);
|
2014-03-08 15:25:10 +01:00
|
|
|
|
2014-03-06 13:01:52 +01:00
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
2014-04-02 18:23:01 +02:00
|
|
|
handleExternalTarget: function($node) {
|
|
|
|
var linkTarget = $node.attr('target');
|
|
|
|
|
|
|
|
// TODO: Let remote links pass through. Right now they only work
|
|
|
|
// combined with target="_blank" or target="_self"
|
|
|
|
// window.open is used as return true; didn't work reliable
|
|
|
|
if (linkTarget === '_blank' || linkTarget === '_self') {
|
2014-06-05 17:03:59 +02:00
|
|
|
window.open($node.attr('href'), linkTarget);
|
2014-04-02 18:23:01 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle table selection.
|
|
|
|
*/
|
|
|
|
rowSelected: function(event) {
|
|
|
|
var self = event.data.self;
|
|
|
|
var icinga = self.icinga;
|
2014-08-19 19:04:29 +02:00
|
|
|
var $tr = $(this);
|
2014-04-02 18:23:01 +02:00
|
|
|
var $table = $tr.closest('table.multiselect');
|
2014-04-23 19:41:07 +02:00
|
|
|
var data = self.icinga.ui.getSelectionKeys($table);
|
2014-04-02 18:23:01 +02:00
|
|
|
var url = $table.data('icinga-multiselect-url');
|
2014-04-09 19:11:56 +02:00
|
|
|
|
2015-05-04 17:59:16 +02:00
|
|
|
if ($(event.target).closest('form').length) {
|
|
|
|
// allow form actions in table rows to pass through
|
|
|
|
return;
|
|
|
|
}
|
2014-04-02 18:23:01 +02:00
|
|
|
event.stopPropagation();
|
|
|
|
event.preventDefault();
|
2014-04-09 19:11:56 +02:00
|
|
|
|
2014-06-20 13:43:18 +02:00
|
|
|
if (!data) {
|
|
|
|
icinga.logger.error('multiselect table has no data-icinga-multiselect-data');
|
2014-04-02 18:23:01 +02:00
|
|
|
return;
|
|
|
|
}
|
2014-06-20 13:43:18 +02:00
|
|
|
if (!url) {
|
|
|
|
icinga.logger.error('multiselect table has no data-icinga-multiselect-url');
|
2014-04-02 18:23:01 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-04-23 19:41:07 +02:00
|
|
|
// update selection
|
2014-06-20 13:43:18 +02:00
|
|
|
if (event.ctrlKey || event.metaKey) {
|
2014-04-07 13:36:25 +02:00
|
|
|
icinga.ui.toogleTableRowSelection($tr);
|
2014-04-02 18:23:01 +02:00
|
|
|
// multi selection
|
2014-06-20 13:43:18 +02:00
|
|
|
} else if (event.shiftKey) {
|
2014-04-02 18:23:01 +02:00
|
|
|
// range selection
|
2014-04-07 13:36:25 +02:00
|
|
|
icinga.ui.addTableRowRangeSelection($tr);
|
2014-04-02 18:23:01 +02:00
|
|
|
} else {
|
|
|
|
// single selection
|
2014-04-07 13:36:25 +02:00
|
|
|
icinga.ui.setTableRowSelection($tr);
|
2014-04-02 18:23:01 +02:00
|
|
|
}
|
2014-04-23 19:41:07 +02:00
|
|
|
// focus only the current table.
|
2014-04-09 19:11:56 +02:00
|
|
|
icinga.ui.focusTable($table[0]);
|
2014-04-02 18:23:01 +02:00
|
|
|
|
2014-04-09 19:13:46 +02:00
|
|
|
var $target = self.getLinkTargetFor($tr);
|
2014-06-20 13:43:18 +02:00
|
|
|
|
|
|
|
var $trs = $table.find('tr[href].active');
|
|
|
|
if ($trs.length > 1) {
|
|
|
|
var selectionData = icinga.ui.getSelectionSetData($trs, data);
|
|
|
|
var query = icinga.ui.selectionDataToQuery(selectionData);
|
|
|
|
icinga.loader.loadUrl(url + '?' + query, $target);
|
|
|
|
icinga.ui.storeSelectionData(selectionData);
|
2014-11-13 12:50:39 +01:00
|
|
|
icinga.ui.provideSelectionCount();
|
2014-06-20 13:43:18 +02:00
|
|
|
} else if ($trs.length === 1) {
|
|
|
|
// display a single row
|
|
|
|
$tr = $trs.first();
|
2014-04-09 19:13:46 +02:00
|
|
|
icinga.loader.loadUrl($tr.attr('href'), $target);
|
2014-06-20 13:43:18 +02:00
|
|
|
icinga.ui.storeSelectionData($tr.attr('href'));
|
2014-11-13 12:50:39 +01:00
|
|
|
icinga.ui.provideSelectionCount();
|
2014-06-20 13:43:18 +02:00
|
|
|
} else {
|
|
|
|
// display nothing
|
|
|
|
if ($target.attr('id') === 'col2') {
|
|
|
|
icinga.ui.layout1col();
|
|
|
|
}
|
|
|
|
icinga.ui.storeSelectionData(null);
|
2014-11-13 12:50:39 +01:00
|
|
|
icinga.ui.provideSelectionCount();
|
2014-04-02 18:23:01 +02:00
|
|
|
}
|
2014-06-20 13:43:18 +02:00
|
|
|
|
2014-04-02 18:23:01 +02:00
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
2015-03-12 15:51:22 +01:00
|
|
|
/**
|
|
|
|
* Handle anchor, i.e. focus the element which is referenced by the anchor
|
|
|
|
*
|
|
|
|
* @param {string} query jQuery selector
|
|
|
|
*/
|
2015-02-12 13:08:08 +01:00
|
|
|
handleAnchor: function(query) {
|
2015-02-12 16:14:07 +01:00
|
|
|
var $element = $(query);
|
|
|
|
if ($element.length > 0) {
|
2015-03-12 16:02:39 +01:00
|
|
|
if (typeof $element.attr('tabindex') === 'undefined') {
|
|
|
|
$element.attr('tabindex', -1);
|
2015-02-12 13:08:08 +01:00
|
|
|
}
|
2015-02-12 16:14:07 +01:00
|
|
|
$element.focus();
|
2015-02-12 13:08:08 +01:00
|
|
|
}
|
|
|
|
},
|
2014-04-02 18:23:01 +02:00
|
|
|
|
2014-03-06 13:01:52 +01:00
|
|
|
/**
|
|
|
|
* Someone clicked a link or tr[href]
|
|
|
|
*/
|
|
|
|
linkClicked: function (event) {
|
2014-03-08 15:25:10 +01:00
|
|
|
var self = event.data.self;
|
|
|
|
var icinga = self.icinga;
|
2014-03-06 13:01:52 +01:00
|
|
|
var $a = $(this);
|
2015-02-16 15:07:31 +01:00
|
|
|
var $eventTarget = $(event.target);
|
2014-03-06 13:01:52 +01:00
|
|
|
var href = $a.attr('href');
|
2014-03-09 00:58:49 +01:00
|
|
|
var linkTarget = $a.attr('target');
|
2014-03-08 15:25:10 +01:00
|
|
|
var $target;
|
2014-03-20 12:24:15 +01:00
|
|
|
var formerUrl;
|
2014-05-09 13:04:00 +02:00
|
|
|
var remote = /^(?:[a-z]+:)\/\//;
|
2014-09-05 15:05:22 +02:00
|
|
|
if (href.match(/^(mailto|javascript):/)) {
|
2014-06-24 06:35:52 +02:00
|
|
|
return true;
|
|
|
|
}
|
2014-03-08 14:53:17 +01:00
|
|
|
|
2014-08-19 18:33:28 +02:00
|
|
|
// Special checks for link clicks in multiselect rows
|
|
|
|
if (! $a.is('tr[href]') && $a.closest('tr[href]').length > 0 && $a.closest('table.multiselect').length > 0) {
|
|
|
|
|
|
|
|
// Forward clicks to ANY link with special key pressed to rowSelected
|
|
|
|
if (event.ctrlKey || event.metaKey || event.shiftKey)
|
|
|
|
{
|
|
|
|
return self.rowSelected.call($a.closest('tr[href]'), event);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Forward inner links matching the row URL to rowSelected
|
|
|
|
if ($a.attr('href') === $a.closest('tr[href]').attr('href'))
|
|
|
|
{
|
|
|
|
return self.rowSelected.call($a.closest('tr[href]'), event);
|
|
|
|
}
|
2014-06-20 13:43:18 +02:00
|
|
|
}
|
|
|
|
|
2014-05-09 13:41:18 +02:00
|
|
|
// Let remote links pass through
|
|
|
|
if (href.match(remote)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-03-09 00:58:49 +01:00
|
|
|
// window.open is used as return true; didn't work reliable
|
2014-05-09 13:41:18 +02:00
|
|
|
if (linkTarget === '_blank' || linkTarget === '_self') {
|
2014-03-09 00:58:49 +01:00
|
|
|
window.open(href, linkTarget);
|
|
|
|
return false;
|
2014-03-06 13:01:52 +01:00
|
|
|
}
|
2014-03-08 15:25:10 +01:00
|
|
|
|
2015-02-16 15:07:31 +01:00
|
|
|
if (! $eventTarget.is($a)) {
|
|
|
|
if ($eventTarget.is('input') || $eventTarget.is('button')) {
|
|
|
|
// Ignore form elements in action rows
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
var $button = $('input[type=submit]:focus').add('button[type=submit]:focus');
|
|
|
|
if ($button.length > 0 && $.contains($button[0], $eventTarget[0])) {
|
|
|
|
// Ignore any descendant of form elements
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2014-08-20 09:26:16 +02:00
|
|
|
}
|
|
|
|
|
2014-05-09 16:53:34 +02:00
|
|
|
// ignore multiselect table row clicks
|
|
|
|
if ($a.is('tr') && $a.closest('table.multiselect').length > 0) {
|
2014-04-09 19:11:56 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-09 00:58:49 +01:00
|
|
|
// Handle all other links as XHR requests
|
2014-03-06 13:01:52 +01:00
|
|
|
event.stopPropagation();
|
|
|
|
event.preventDefault();
|
|
|
|
|
2015-02-12 13:08:08 +01:00
|
|
|
// This is an anchor only
|
2015-02-13 11:45:20 +01:00
|
|
|
if (href.substr(0, 1) === '#' && href.length > 1
|
|
|
|
&& href.substr(1, 1) !== '!') {
|
2015-02-12 13:08:08 +01:00
|
|
|
self.handleAnchor(href);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-02-25 12:10:08 +01:00
|
|
|
// activate spinner indicator
|
|
|
|
if ($a.hasClass('spinner')) {
|
|
|
|
$a.addClass('active');
|
|
|
|
}
|
|
|
|
|
2014-03-20 12:24:15 +01:00
|
|
|
// If link has hash tag...
|
|
|
|
if (href.match(/#/)) {
|
2014-09-10 15:51:02 +02:00
|
|
|
if (href === '#') {
|
2014-10-01 14:51:51 +02:00
|
|
|
if ($a.hasClass('close-toggle')) {
|
|
|
|
if (! icinga.ui.isOneColLayout()) {
|
|
|
|
var $cont = $a.closest('.container').first();
|
|
|
|
if ($cont.attr('id') === 'col1') {
|
|
|
|
icinga.ui.moveToLeft();
|
|
|
|
icinga.ui.layout1col();
|
|
|
|
} else {
|
|
|
|
icinga.ui.layout1col();
|
|
|
|
}
|
2015-04-13 17:45:38 +02:00
|
|
|
$('table tr[href].active').removeClass('active');
|
|
|
|
icinga.ui.storeSelectionData(null);
|
|
|
|
icinga.ui.loadSelectionData();
|
2014-10-01 14:51:51 +02:00
|
|
|
icinga.history.pushCurrentState();
|
|
|
|
}
|
|
|
|
}
|
2014-09-10 15:51:02 +02:00
|
|
|
return false;
|
|
|
|
}
|
2014-03-20 12:24:15 +01:00
|
|
|
$target = self.getLinkTargetFor($a);
|
2014-03-08 14:53:17 +01:00
|
|
|
|
2014-03-20 12:24:15 +01:00
|
|
|
formerUrl = $target.data('icingaUrl');
|
|
|
|
if (typeof formerUrl !== 'undefined' && formerUrl.split(/#/)[0] === href.split(/#/)[0]) {
|
|
|
|
icinga.ui.scrollContainerToAnchor($target, href.split(/#/)[1]);
|
|
|
|
$target.data('icingaUrl', href);
|
|
|
|
if (formerUrl !== href) {
|
|
|
|
icinga.history.pushCurrentState();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$target = self.getLinkTargetFor($a);
|
|
|
|
}
|
2014-03-08 14:53:17 +01:00
|
|
|
|
|
|
|
// Load link URL
|
2014-03-06 13:01:52 +01:00
|
|
|
icinga.loader.loadUrl(href, $target);
|
2014-03-06 13:08:11 +01:00
|
|
|
|
2014-09-10 14:21:15 +02:00
|
|
|
if ($a.closest('#menu').length > 0) {
|
2014-09-08 15:21:14 +02:00
|
|
|
// Menu links should remove all but the first layout column
|
2014-03-08 15:08:03 +01:00
|
|
|
icinga.ui.layout1col();
|
2014-03-06 13:01:52 +01:00
|
|
|
}
|
2014-03-06 13:08:11 +01:00
|
|
|
|
2014-03-08 15:25:10 +01:00
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Detect the link/form target for a given element (link, form, whatever)
|
|
|
|
*/
|
|
|
|
getLinkTargetFor: function($el)
|
|
|
|
{
|
|
|
|
var targetId;
|
|
|
|
|
|
|
|
// If everything else fails, our target is the first column...
|
|
|
|
var $target = $('#col1');
|
|
|
|
|
|
|
|
// ...but usually we will use our own container...
|
|
|
|
var $container = $el.closest('.container');
|
|
|
|
if ($container.length) {
|
|
|
|
$target = $container;
|
|
|
|
}
|
|
|
|
|
2014-03-21 11:27:46 +01:00
|
|
|
// You can of course override the default behaviour:
|
2014-03-08 15:25:10 +01:00
|
|
|
if ($el.closest('[data-base-target]').length) {
|
|
|
|
targetId = $el.closest('[data-base-target]').data('baseTarget');
|
|
|
|
|
|
|
|
// Simulate _next to prepare migration to dynamic column layout
|
2014-03-20 16:41:36 +01:00
|
|
|
// YES, there are duplicate lines right now.
|
2014-03-08 15:25:10 +01:00
|
|
|
if (targetId === '_next') {
|
2014-06-24 07:46:37 +02:00
|
|
|
if (this.icinga.ui.hasOnlyOneColumn()) {
|
|
|
|
targetId = 'col1';
|
|
|
|
$target = $('#' + targetId);
|
|
|
|
} else {
|
|
|
|
if ($el.closest('#col2').length) {
|
|
|
|
this.icinga.ui.moveToLeft();
|
|
|
|
}
|
|
|
|
targetId = 'col2';
|
|
|
|
$target = $('#' + targetId);
|
2014-03-17 17:10:03 +01:00
|
|
|
}
|
2014-03-20 16:41:36 +01:00
|
|
|
} else if (targetId === '_self') {
|
|
|
|
$target = $el.closest('.container');
|
|
|
|
targetId = $target.attr('id');
|
|
|
|
} else if (targetId === '_main') {
|
2014-03-09 23:30:37 +01:00
|
|
|
targetId = 'col1';
|
2014-03-20 16:41:36 +01:00
|
|
|
$target = $('#' + targetId);
|
2014-06-05 17:03:59 +02:00
|
|
|
self.icinga.ui.layout1col();
|
2014-03-20 16:41:36 +01:00
|
|
|
} else {
|
|
|
|
$target = $('#' + targetId);
|
2014-03-09 23:30:37 +01:00
|
|
|
}
|
|
|
|
|
2014-03-08 15:25:10 +01:00
|
|
|
}
|
|
|
|
|
2014-03-08 14:53:17 +01:00
|
|
|
// Hardcoded layout switch unless columns are dynamic
|
|
|
|
if ($target.attr('id') === 'col2') {
|
2014-06-05 17:03:59 +02:00
|
|
|
this.icinga.ui.layout2col();
|
2014-03-06 13:01:52 +01:00
|
|
|
}
|
2014-03-08 15:25:10 +01:00
|
|
|
|
|
|
|
return $target;
|
2014-03-06 13:01:52 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
unbindGlobalHandlers: function () {
|
2014-09-10 10:44:22 +02:00
|
|
|
$.each(self.icinga.behaviors, function (name, behavior) {
|
2014-09-12 09:09:21 +02:00
|
|
|
behavior.unbind($(document));
|
2014-09-10 10:44:22 +02:00
|
|
|
});
|
2014-03-06 13:01:52 +01:00
|
|
|
$(window).off('resize', this.onWindowResize);
|
2014-04-01 10:40:38 +02:00
|
|
|
$(window).off('load', this.onLoad);
|
2014-03-06 13:01:52 +01:00
|
|
|
$(window).off('unload', this.onUnload);
|
2015-04-16 21:01:08 +02:00
|
|
|
$(window).off('beforeunload', this.onUnload);
|
2014-03-06 13:01:52 +01:00
|
|
|
$(document).off('scroll', '.container', this.onContainerScroll);
|
|
|
|
$(document).off('click', 'a', this.linkClicked);
|
2014-04-23 19:41:07 +02:00
|
|
|
$(document).off('click', 'table.action tr[href]', this.rowSelected);
|
|
|
|
$(document).off('click', 'table.action tr a', this.rowSelected);
|
2014-03-06 13:01:52 +01:00
|
|
|
$(document).off('submit', 'form', this.submitForm);
|
|
|
|
$(document).off('change', 'form select.autosubmit', this.submitForm);
|
2015-02-26 14:48:37 +01:00
|
|
|
$(document).off('change', 'form input.autosubmit', this.submitForm);
|
2015-03-06 15:41:25 +01:00
|
|
|
$(document).off('focus', 'form select[data-related-radiobtn]', this.autoCheckRadioButton);
|
|
|
|
$(document).off('focus', 'form input[data-related-radiobtn]', this.autoCheckRadioButton);
|
2014-03-06 13:01:52 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
destroy: function() {
|
|
|
|
// This is gonna be hard, clean up the mess
|
|
|
|
this.unbindGlobalHandlers();
|
|
|
|
this.icinga = null;
|
2014-03-05 13:38:38 +01:00
|
|
|
}
|
2014-03-06 13:01:52 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
}(Icinga, jQuery));
|