--- a/src/pyams_skin/resources/js/myams.js Wed Oct 07 18:04:42 2015 +0200
+++ b/src/pyams_skin/resources/js/myams.js Wed Oct 07 18:06:06 2015 +0200
@@ -113,7 +113,7 @@
* Get object if it supports given CSS class,
* otherwise looks for parents
*/
- objectWithClass: function(klass) {
+ objectOrParentWithClass: function(klass) {
if (this.hasClass(klass))
return this;
else
@@ -595,6 +595,14 @@
msg = 1;
}
return msg;
+ },
+
+ copyToClipboard: function() {
+ return function() {
+ var source = $(this);
+ source.parents('.btn-group').removeClass('open');
+ window.prompt(MyAMS.i18n.CLIPBOARD_COPY, source.text());
+ }
}
};
@@ -1237,7 +1245,7 @@
if (!ams.form._checkSubmitValidators(form))
return false;
// Remove remaining status messages
- $('.alert, SPAN.state-error', form).remove();
+ $('.alert-danger, SPAN.state-error', form).remove();
$('.state-error', form).removeClassPrefix('state-');
// Check submit button
var button = $(form.data('ams-submit-button'));
@@ -1694,8 +1702,11 @@
* Register a callback which should be called when a dialog is shown
*/
registerShownCallback: function(callback, element) {
- var dialog = element.objectWithClass('modal-dialog');
- if (dialog.exists()) {
+ var dialog;
+ if (element) {
+ dialog = element.objectOrParentWithClass('modal-dialog');
+ }
+ if (dialog && dialog.exists()) {
var callbacks = dialog.data('shown-callbacks');
if (callbacks === undefined) {
callbacks = [];
@@ -1717,8 +1728,11 @@
* Register a callback which should be called when a dialog is closed
*/
registerHideCallback: function(callback, element) {
- var dialog = element.objectWithClass('modal-dialog');
- if (dialog.exists()) {
+ var dialog;
+ if (element) {
+ dialog = element.objectOrParentWithClass('modal-dialog');
+ }
+ if (dialog && dialog.exists()) {
var callbacks = dialog.data('hide-callbacks');
if (callbacks === undefined) {
callbacks = [];
@@ -1841,27 +1855,27 @@
var modal = e.target;
var viewport = $('.modal-viewport', modal);
- if (viewport.length == 0)
- return;
- var maxHeight = parseInt(viewport.css('max-height'));
- var barWidth = $.scrollbarWidth();
- if (viewport.height() == maxHeight) {
- $('<div></div>').addClass('scrollmarker')
- .addClass('top')
- .css('top', 0)
- .css('width', viewport.width() - barWidth)
- .hide()
- .appendTo(viewport);
- $('<div></div>').addClass('scrollmarker')
- .addClass('bottom')
- .css('top', maxHeight - 20)
- .css('width', viewport.width() - barWidth)
- .appendTo(viewport);
- viewport.scroll(resetViewport);
- viewport.off('resize')
+ if (viewport.exists()) {
+ var maxHeight = parseInt(viewport.css('max-height'));
+ var barWidth = $.scrollbarWidth();
+ if (viewport.height() == maxHeight) {
+ $('<div></div>').addClass('scrollmarker')
+ .addClass('top')
+ .css('top', 0)
+ .css('width', viewport.width() - barWidth)
+ .hide()
+ .appendTo(viewport);
+ $('<div></div>').addClass('scrollmarker')
+ .addClass('bottom')
+ .css('top', maxHeight - 20)
+ .css('width', viewport.width() - barWidth)
+ .appendTo(viewport);
+ viewport.scroll(resetViewport);
+ viewport.off('resize')
.on('resize', resetViewport);
- } else {
- $('.scrollmarker', viewport).remove();
+ } else {
+ $('.scrollmarker', viewport).remove();
+ }
}
// Call shown callbacks registered for this dialog
@@ -2967,28 +2981,13 @@
ams.ajax.check($.fn.dataTable,
ams.baseURL + 'ext/jquery-dataTables-1.9.4' + ams.devext + '.js',
function(first_load) {
- if (first_load) {
- $.fn.dataTableExt.oSort['numeric-comma-asc'] = function(a, b) {
- var x = a.replace(/,/, ".").replace(/ /g, '');
- var y = b.replace(/,/, ".").replace(/ /g, '');
- x = parseFloat(x);
- y = parseFloat(y);
- return ((x < y) ? -1 : ((x > y) ? 1 : 0));
- };
- $.fn.dataTableExt.oSort['numeric-comma-desc'] = function(a, b) {
- var x = a.replace(/,/, ".").replace(/ /g, '');
- var y = b.replace(/,/, ".").replace(/ /g, '');
- x = parseFloat(x);
- y = parseFloat(y);
- return ((x < y) ? 1 : ((x > y) ? -1 : 0));
- };
- }
$(tables).each(function() {
ams.ajax.check($.fn.dataTableExt.oPagination['bootstrap_full'],
ams.baseURL + 'myams-dataTables' + ams.devext + '.js');
var table = $(this);
var data = table.data();
var extensions = (data.amsDatatableExtensions || '').split(/\s+/);
+ // Check DOM elements
var sDom = data.amsDatatableSdom ||
"W" +
((extensions.indexOf('colreorder') >= 0 ||
@@ -3003,13 +3002,38 @@
"><'dt-row dt-bottom-row'<'row'<'col-sm-6'" +
(data.amsDatatableInformation === false ? '': 'i') +
"><'col-sm-6 text-right'p>>";
+ var index;
+ // Check initial sorting
+ var sorting = data.amsDatatableSorting;
+ if (typeof(sorting) === 'string') {
+ var sortings = sorting.split(';');
+ sorting = [];
+ for (index in sortings) {
+ var col_sorting = sortings[index].split(',');
+ col_sorting[0] = parseInt(col_sorting[0]);
+ sorting.push(col_sorting);
+ }
+ }
+ // Check columns types
+ var columns = [];
+ var sort_types = $('th', table).listattr('data-ams-datatable-stype');
+ for (index in sort_types) {
+ var sort_type = sort_types[index];
+ if (sort_type) {
+ var column = columns[index] || {};
+ column.sType = sort_type;
+ columns[index] = column;
+ }
+ }
+ // Set options
var data_options = {
bJQueryUI: false,
bFilter: data.amsDatatableGlobalFilter !== false,
bPaginate: data.amsDatatablePagination !== false,
bInfo: data.amsDatatableInfo !== false,
bSort: data.amsDatatableSort !== false,
- aaSorting: data.amsDatatableSorting,
+ aaSorting: sorting,
+ aoColumns: columns.length > 0 ? columns : undefined,
bDeferRender: true,
bAutoWidth: false,
iDisplayLength: data.amsDatatableDisplayLength || 25,
@@ -3022,7 +3046,6 @@
}
};
var settings = $.extend({}, data_options, data.amsDatatableOptions);
- var index;
if (extensions.length > 0) {
for (index in extensions) {
switch (extensions[index]) {
@@ -3087,85 +3110,88 @@
}
}
settings = ams.executeFunctionByName(data.amsDatatableInitCallback, table, settings) || settings;
- var plugin = table.dataTable(settings);
- ams.executeFunctionByName(data.amsDatatableAfterInitCallback, table, plugin, settings);
- if (extensions.length > 0) {
- for (index in extensions) {
- switch (extensions[index]) {
- case 'autofill':
- var af_settings = $.extend({}, data.amsDatatableAutofillOptions, settings.autofill);
- af_settings = ams.executeFunctionByName(data.amsDatatableAutofillInitCallback, table, af_settings) || af_settings;
- table.data('ams-autofill', data.amsDatatableAutofillConstructor === undefined
- ? new $.fn.dataTable.AutoFill(table, af_settings)
- : ams.executeFunctionByName(data.amsDatatableAutofillConstructor, table, plugin, af_settings));
- break;
- case 'columnfilter':
- var cf_default = {
- sPlaceHolder: 'head:after'
- };
- var cf_settings = $.extend({}, cf_default, data.amsDatatableColumnfilterOptions, settings.columnfilter);
- cf_settings = ams.executeFunctionByName(data.amsDatatableColumnfilterInitCallback, table, cf_settings) || cf_settings;
- table.data('ams-columnfilter', data.amsDatatableColumnfilterConstructor === undefined
- ? plugin.columnFilter(cf_settings)
- : ams.executeFunctionByName(data.amsDatatableColumnfilterConstructor, table, plugin, cf_settings));
- break;
- case 'editable':
- var ed_settings = $.extend({}, data.amsDatatableEditableOptions, settings.editable);
- ed_settings = ams.executeFunctionByName(data.amsDatatableEditableInitCallback, table, ed_settings) || ed_settings;
- table.data('ams-editable', data.amsDatatableEditableConstructor === undefined
- ? table.makeEditable(ed_settings)
- : ams.executeFunctionByName(data.amsDatatableEditableConstructor, table, plugin, ed_settings));
- break;
- case 'fixedcolumns':
- var fc_settings = $.extend({}, data.amsDatatableFixedcolumnsOptions, settings.fixedcolumns);
- fc_settings = ams.executeFunctionByName(data.amsDatatableFixedcolumnsInitCallback, table, fc_settings) || fc_settings;
- table.data('ams-fixedcolumns', data.amsDatatableFixedcolumnsConstructor === undefined
- ? new $.fn.dataTable.FixedColumns(table, fc_settings)
- : ams.executeFunctionByName(data.amsDatatableFixedcolumnsConstructor, table, plugin, fc_settings));
- break;
- case 'fixedheader':
- var fh_settings = $.extend({}, data.amsDatatableFixedheaderOptions, settings.fixedheader);
- fh_settings = ams.executeFunctionByName(data.amsDatatableFixedheadeInitCallback, table, fh_settings) || fh_settings;
- table.data('ams-fixedheader', data.amsDatatableFixedheaderConstructor === undefined
- ? new $.fn.dataTable.FixedHeader(table, fh_settings)
- : ams.executeFunctionByName(data.amsDatatableFixedheaderConstructor, table, plugin, fh_settings));
- break;
- case 'keytable':
- var kt_default = {
- table: table.get(0),
- datatable: plugin
- };
- var kt_settings = $.extend({}, kt_default, data.amsDatatableKeytableOptions, settings.keytable);
- kt_settings = ams.executeFunctionByName(data.amsDatatableKeytableInitCallback, table, kt_settings) || kt_settings;
- table.data('ams-keytable', data.amsDatatableKeytableConstructor === undefined
- ? new KeyTable(kt_settings)
- : ams.executeFunctionByName(data.amsDatatableKeytableConstructor, table, plugin, kt_settings));
- break;
- case 'rowgrouping':
- var rg_settings = $.extend({}, data.amsDatatableRowgroupingOptions, settings.rowgrouping);
- rg_settings = ams.executeFunctionByName(data.amsDatatableRowgroupingInitCallback, table, rg_settings) || rg_settings;
- table.data('ams-rowgrouping', data.amsDatatableRowgroupingConstructor === undefined
- ? table.rowGrouping(rg_settings)
- : ams.executeFunctionByName(data.amsDatatableRowgroupingConstructor, table, plugin, rg_settings));
- break;
- case 'rowreordering':
- var rr_settings = $.extend({}, data.amsDatatableRowreorderingOptions, settings.rowreordering);
- rr_settings = ams.executeFunctionByName(data.amsDatatableRowreorderingInitCallback, table, rr_settings) || rr_settings;
- table.data('ams-rowreordering', data.amsDatatableRowreorderingConstructor === undefined
- ? table.rowReordering(rr_settings)
- : ams.executeFunctionByName(data.amsDatatableRowreorderingConstructor, table, plugin, rr_settings));
- break;
- default:
- break;
+ try { // Some settings can easilly generate DataTables exceptions...
+ var plugin = table.dataTable(settings);
+ ams.executeFunctionByName(data.amsDatatableAfterInitCallback, table, plugin, settings);
+ if (extensions.length > 0) {
+ for (index in extensions) {
+ switch (extensions[index]) {
+ case 'autofill':
+ var af_settings = $.extend({}, data.amsDatatableAutofillOptions, settings.autofill);
+ af_settings = ams.executeFunctionByName(data.amsDatatableAutofillInitCallback, table, af_settings) || af_settings;
+ table.data('ams-autofill', data.amsDatatableAutofillConstructor === undefined
+ ? new $.fn.dataTable.AutoFill(table, af_settings)
+ : ams.executeFunctionByName(data.amsDatatableAutofillConstructor, table, plugin, af_settings));
+ break;
+ case 'columnfilter':
+ var cf_default = {
+ sPlaceHolder: 'head:after'
+ };
+ var cf_settings = $.extend({}, cf_default, data.amsDatatableColumnfilterOptions, settings.columnfilter);
+ cf_settings = ams.executeFunctionByName(data.amsDatatableColumnfilterInitCallback, table, cf_settings) || cf_settings;
+ table.data('ams-columnfilter', data.amsDatatableColumnfilterConstructor === undefined
+ ? plugin.columnFilter(cf_settings)
+ : ams.executeFunctionByName(data.amsDatatableColumnfilterConstructor, table, plugin, cf_settings));
+ break;
+ case 'editable':
+ var ed_settings = $.extend({}, data.amsDatatableEditableOptions, settings.editable);
+ ed_settings = ams.executeFunctionByName(data.amsDatatableEditableInitCallback, table, ed_settings) || ed_settings;
+ table.data('ams-editable', data.amsDatatableEditableConstructor === undefined
+ ? table.makeEditable(ed_settings)
+ : ams.executeFunctionByName(data.amsDatatableEditableConstructor, table, plugin, ed_settings));
+ break;
+ case 'fixedcolumns':
+ var fc_settings = $.extend({}, data.amsDatatableFixedcolumnsOptions, settings.fixedcolumns);
+ fc_settings = ams.executeFunctionByName(data.amsDatatableFixedcolumnsInitCallback, table, fc_settings) || fc_settings;
+ table.data('ams-fixedcolumns', data.amsDatatableFixedcolumnsConstructor === undefined
+ ? new $.fn.dataTable.FixedColumns(table, fc_settings)
+ : ams.executeFunctionByName(data.amsDatatableFixedcolumnsConstructor, table, plugin, fc_settings));
+ break;
+ case 'fixedheader':
+ var fh_settings = $.extend({}, data.amsDatatableFixedheaderOptions, settings.fixedheader);
+ fh_settings = ams.executeFunctionByName(data.amsDatatableFixedheadeInitCallback, table, fh_settings) || fh_settings;
+ table.data('ams-fixedheader', data.amsDatatableFixedheaderConstructor === undefined
+ ? new $.fn.dataTable.FixedHeader(table, fh_settings)
+ : ams.executeFunctionByName(data.amsDatatableFixedheaderConstructor, table, plugin, fh_settings));
+ break;
+ case 'keytable':
+ var kt_default = {
+ table: table.get(0),
+ datatable: plugin
+ };
+ var kt_settings = $.extend({}, kt_default, data.amsDatatableKeytableOptions, settings.keytable);
+ kt_settings = ams.executeFunctionByName(data.amsDatatableKeytableInitCallback, table, kt_settings) || kt_settings;
+ table.data('ams-keytable', data.amsDatatableKeytableConstructor === undefined
+ ? new KeyTable(kt_settings)
+ : ams.executeFunctionByName(data.amsDatatableKeytableConstructor, table, plugin, kt_settings));
+ break;
+ case 'rowgrouping':
+ var rg_settings = $.extend({}, data.amsDatatableRowgroupingOptions, settings.rowgrouping);
+ rg_settings = ams.executeFunctionByName(data.amsDatatableRowgroupingInitCallback, table, rg_settings) || rg_settings;
+ table.data('ams-rowgrouping', data.amsDatatableRowgroupingConstructor === undefined
+ ? table.rowGrouping(rg_settings)
+ : ams.executeFunctionByName(data.amsDatatableRowgroupingConstructor, table, plugin, rg_settings));
+ break;
+ case 'rowreordering':
+ var rr_settings = $.extend({}, data.amsDatatableRowreorderingOptions, settings.rowreordering);
+ rr_settings = ams.executeFunctionByName(data.amsDatatableRowreorderingInitCallback, table, rr_settings) || rr_settings;
+ table.data('ams-rowreordering', data.amsDatatableRowreorderingConstructor === undefined
+ ? table.rowReordering(rr_settings)
+ : ams.executeFunctionByName(data.amsDatatableRowreorderingConstructor, table, plugin, rr_settings));
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ var finalizers = (data.amsDatatableFinalizeCallback || '').split(/\s+/);
+ if (finalizers.length > 0) {
+ for (index in finalizers) {
+ ams.executeFunctionByName(finalizers[index], table, plugin, settings);
}
}
}
- var finalizers = (data.amsDatatableFinalizeCallback || '').split(/\s+/);
- if (finalizers.length > 0) {
- for (index in finalizers) {
- ams.executeFunctionByName(finalizers[index], table, plugin, settings);
- }
- }
+ catch (e) {}
});
});
}
@@ -3398,6 +3424,50 @@
},
/**
+ * Flot charts
+ */
+ chart: function(element) {
+ var charts = $('.chart', element);
+ if (charts.length > 0) {
+ ams.ajax.check($.fn.plot,
+ ams.baseURL + 'flot/jquery.flot' + ams.devext + '.js',
+ function() {
+ charts.each(function() {
+
+ function checkPlugin(plugin) {
+ for (var index in $.plot.plugins) {
+ var plugin_info = $.plot.plugins[index];
+ if (plugin_info.name == plugin) {
+ return plugin_info;
+ }
+ }
+ return null;
+ }
+
+ var chart = $(this);
+ var data = chart.data();
+ var data_options = {};
+ var plugins = (data.amsChartPlugins || '').split(/\s+/);
+ if (plugins.length > 0) {
+ for (var index in plugins) {
+ var plugin_name = plugins[index];
+ if (!checkPlugin(plugin_name)) {
+ ams.getScript(ams.baseURL + 'flot/jquery.flot.' + plugin_name + ams.devext + '.js');
+ }
+ }
+ }
+ var settings = $.extend({}, data_options, data.amsChartOptions);
+ settings = ams.executeFunctionByName(data.amsChartInitCallback, chart, settings) || settings;
+ var chart_data = data.amsChartData;
+ chart_data = ams.executeFunctionByName(data.amsChartInitData, chart, chart_data) || chart_data;
+ var plugin = chart.plot(chart_data, settings);
+ ams.executeFunctionByName(data.amsChartAfterInitCallback, chart, plugin, settings);
+ })
+ });
+ }
+ },
+
+ /**
* Sparkline graphs
*/
graphs: function(element) {
@@ -4265,7 +4335,6 @@
if (target) {
ams.form.confirmChangedForm(target, function () {
ams.skin.loadURL(href, target, link.data('ams-link-options'), link.data('ams-link-callback'));
- e.stopPropagation();
});
} else {
ams.form.confirmChangedForm(function () {
@@ -4401,15 +4470,21 @@
if (data.amsUrl) {
if (data.amsTabLoaded)
return;
- ams.skin.loadURL(data.amsUrl, link.attr('href'));
- if (data.amsTabLoadOnce)
- link.data('ams-tab-loaded', true);
+ try {
+ link.append('<i class="fa fa-spin fa-cog margin-left-5"></i>');
+ ams.skin.loadURL(data.amsUrl, link.attr('href'));
+ if (data.amsTabLoadOnce)
+ link.data('ams-tab-loaded', true);
+ }
+ finally {
+ $('i', link).remove();
+ }
}
});
// Init page content
ams.initContent(document);
- if (ams.ajax_nav && ($('nav').length > 0))
+ if (ams.ajax_nav && $('nav').exists())
ams.skin.checkURL();
// Add unload event listener to check for modified forms
@@ -4485,6 +4560,8 @@
BTN_NO: "No",
BTN_YES_NO: "[Yes][No]",
+ CLIPBOARD_COPY: "Copy to clipboard with Ctrl+C, and Enter",
+
FORM_CHANGED_WARNING: "Some changes were not saved. These updates will be lost if you leave this page.",
DELETE_WARNING: "This change can't be undone. Are you sure that you want to delete this element?",
NO_UPDATE: "No changes were applied.",