src/pyams_skin/resources/js/myams.js
changeset 49 58a1fc0b50a7
parent 39 4cf15d8ab938
child 51 b06eea7cafc2
--- a/src/pyams_skin/resources/js/myams.js	Tue Apr 14 16:39:04 2015 +0200
+++ b/src/pyams_skin/resources/js/myams.js	Tue Apr 14 16:39:45 2015 +0200
@@ -2,7 +2,7 @@
  * MyAMS
  * « My Application Management Skin »
  *
- * $Tag: null $
+ * $Tag$
  * A bootstrap based application/administration skin
  *
  * Custom administration and application skin tools
@@ -442,8 +442,8 @@
 			url: ams.getSource(url),
 			success: callback,
 			error: ams.error.show,
-			cache: true,
-			async: true
+			cache: !ams.devmode,
+			async: typeof(callback) == 'function'
 		};
 		var settings = $.extend({}, defaults, options);
 		return $.ajax(settings);
@@ -453,9 +453,12 @@
 		var head = $('HEAD');
 		var css = $('link[data-ams-id="' + id + '"]', head);
 		if (css.length == 0) {
+			var source = ams.getSource(url);
+			if (ams.devmode)
+				source += '?_=' + new Date().getTime();
 			$('<link />').attr({rel: 'stylesheet',
 								type: 'text/css',
-								href: ams.getSource(url),
+								href: source,
 								'data-ams-id': id})
 						 .appendTo(head);
 		}
@@ -948,12 +951,75 @@
 		 *
 		 * Parameters:
 		 *  - @method: name of JSON-RPC procedure to call
+		 *  - @options: additional JSON-RPC method call parameters
+		 *  - @callback: name of a callback which will be called on server response
+		 */
+		post: function(method, data, options, callback) {
+			ams.ajax.check($.jsonRPC,
+						   ams.baseURL + 'ext/jquery-jsonrpc' + (ams.devmode ? '.js' : '.min.js'),
+						   function() {
+								var result;
+								if (typeof(options) == 'function') {
+									callback = options;
+									options = {};
+								}
+								else if (!options)
+									options = {};
+								if (typeof(callback) == 'undefined')
+									callback = options.callback;
+								if (typeof(callback) == 'string')
+									callback = ams.getFunctionByName(callback);
+								delete options.callback;
+
+								var result;
+								var defaults = {
+									id: new Date().getTime(),
+									params: data,
+									success: callback || function(data) {
+										result = data;
+									},
+									error: ams.error.show
+								};
+								var settings = $.extend({}, defaults, options);
+								$.jsonRPC.withOptions({
+									endPoint: ams.jsonrpc.getAddr(options.url),
+									namespace: options.namespace,
+									cache: false
+								}, function() {
+									$.jsonRPC.request(method, settings);
+								});
+								return result;
+						   });
+		}
+	};
+
+
+	/**
+	 * XML-RPC helper functions
+	 */
+	MyAMS.xmlrpc = {
+
+		/**
+		 * Get address relative to current page
+		 */
+		getAddr: function(addr) {
+			var href = addr || $('HTML HEAD BASE').attr('href') || window.location.href;
+			var target = href.replace(/\+\+skin\+\+\w+\//, '');
+			return target.substr(0, target.lastIndexOf("/") + 1);
+		},
+
+		/**
+		 * Execute given XML-RPC post on given method
+		 *
+		 * Parameters:
+		 *  - @url: base method URL
+		 *  - @method: name of JSON-RPC procedure to call
 		 *  - @options: additional JSON-RPC procedure parameters
 		 *  - @callback: name of a callback which will be called on server response
 		 */
-		post: function(method, data, options, callback) {
-			ams.ajax.check($.jsonRpc,
-						   ams.baseURL + 'ext/jquery-jsonrpc' + (ams.devmode ? '.js' : '.min.js'),
+		post: function(url, method, data, options, callback) {
+			ams.ajax.check($.xmlrpc,
+						   ams.baseURL + 'ext/jquery-xmlrpc' + (ams.devmode ? '.js' : '.min.js'),
 						   function() {
 								var result;
 								if (typeof(options) == 'function') {
@@ -969,19 +1035,16 @@
 								delete options.callback;
 
 								var defaults = {
-									url: ams.jsonrpc.getAddr(options.url),
-									type: 'post',
-									cache: false,
-									method: method,
+									url: ams.xmlrpc.getAddr(url),
+									methodName: method,
 									params: data,
-									async: typeof(callback) == 'function',
-									success: callback || function(data /*, status*/) {
-										result = data.result;
+									success: callback || function(response /*, status, xhr*/) {
+										result = response;
 									},
 									error: ams.error.show
 								};
 								var settings = $.extend({}, defaults, options);
-								$.jsonRpc(settings);
+								$.xmlrpc(settings);
 								return result;
 						   });
 		}
@@ -1166,14 +1229,14 @@
 										cache: false,
 										data: form_data,
 										dataType: data.amsFormDatatype,
-										beforeSerialize: function(/*form, options*/) {
+										beforeSerialize: function (/*form, options*/) {
 											if (typeof(tinyMCE) != 'undefined')
 												tinyMCE.triggerSave();
 										},
-										beforeSubmit: function(data, form /*, options*/) {
+										beforeSubmit: function (data, form /*, options*/) {
 											form.data('submitted', true);
 										},
-										error: function(request, status, error, form) {
+										error: function (request, status, error, form) {
 											if (target)
 												ams.executeFunctionByName(data.amsFormSubmitError || 'MyAMS.form.finalizeSubmitOnError', form, target);
 											if (form.is(':visible')) {
@@ -1185,24 +1248,85 @@
 											form.data('submitted', false);
 											form.removeData('ams-submit-button');
 										},
-										success: function(result, status, request, form) {
-											var callback;
-											var button = form.data('ams-submit-button');
+										iframe: hasUpload
+									}
+									var download_target = data.amsFormDownloadTarget;
+									if (download_target) {
+										var iframe = $('iframe[name="' + download_target + '"]');
+										if (!iframe.exists())
+											iframe = $('<iframe></iframe>').hide()
+																		   .attr('name', download_target)
+																		   .appendTo(form);
+										defaults = $.extend({}, defaults, {
+											iframe: true,
+											iframeTarget: iframe,
+											success: function(result, status, request, form) {
+												var modal = $(form).parents('.modal-dialog');
+												if (modal.exists()) {
+													ams.dialog.close(form);
+												} else {
+													var callback;
+													var button = form.data('ams-submit-button');
+													if (button)
+														callback = button.data('ams-form-submit-callback');
+													if (!callback)
+														callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback;
+													callback.call(form, result, status, request, form);
+													if (form.is(':visible') && button)
+														button.button('reset');
+													form.data('submitted', false);
+													form.removeData('ams-submit-button');
+													form.removeAttr('data-ams-form-changed');
+												}
+											}
+										});
+									} else {
+										defaults = $.extend({}, defaults, {
+											error: function(request, status, error, form) {
+												if (target)
+													ams.executeFunctionByName(data.amsFormSubmitError || 'MyAMS.form.finalizeSubmitOnError', form, target);
+												if (form.is(':visible')) {
+													var button = form.data('ams-submit-button');
+													if (button)
+														button.button('reset');
+													ams.form.finalizeSubmitFooter.call(form);
+												}
+												form.data('submitted', false);
+												form.removeData('ams-submit-button');
+											},
+											success: function(result, status, request, form) {
+												var callback;
+												var button = form.data('ams-submit-button');
+												if (button)
+													callback = button.data('ams-form-submit-callback');
+												if (!callback)
+													callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback;
+												callback.call(form, result, status, request, form);
+												if (form.is(':visible') && button)
+													button.button('reset');
+												form.data('submitted', false);
+												form.removeData('ams-submit-button');
+												form.removeAttr('data-ams-form-changed');
+											},
+											iframe: hasUpload
+										});
+									}
+									var settings = $.extend({}, defaults, options, form_options, submit_options);
+									$(form).ajaxSubmit(settings);
+
+									if (download_target) {
+										var modal = $(form).parents('.modal-dialog');
+										if (modal.exists()) {
+											ams.dialog.close(form);
+										} else {
+											ams.form.finalizeSubmitFooter.call(form);
 											if (button)
-												callback = button.data('ams-form-submit-callback');
-											if (!callback)
-												callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback;
-											callback.call(form, result, status, request, form);
-											if (form.is(':visible') && button)
 												button.button('reset');
 											form.data('submitted', false);
 											form.removeData('ams-submit-button');
 											form.removeAttr('data-ams-form-changed');
-										},
-										iframe: hasUpload
+										}
 									}
-									var settings = $.extend({}, defaults, options, form_options, submit_options);
-									$(form).ajaxSubmit(settings);
 								}
 
 								var hasUpload = $('INPUT[type="file"]', form).length > 0;
@@ -1545,7 +1669,9 @@
 														settings = ams.executeFunctionByName(dialog_data.amsModalInitCallback, dialog, settings) || settings;
 														$('<div>').addClass('modal fade')
 																  .append(content)
-																  .modal(settings);
+																  .modal(settings)
+																  .on('shown', ams.dialog.shown)
+																  .on('hidden', ams.dialog.hidden);
 														ams.initContent(content);
 												}
 											}
@@ -1611,6 +1737,15 @@
 				if (manager && (manager.getOpenModals().indexOf(modal) >= 0))
 					modal.hide();
 			}
+		},
+
+		/**
+		 * Modals hidden callback
+		 * This callback can be used to clean contents added by plug-ins
+		 */
+		hidden: function(e) {
+			var modal = e.target;
+			$('.datepicker, .timepicker, .datetimepicker', modal).datetimepicker('destroy');
 		}
 	};
 
@@ -2139,13 +2274,10 @@
 												// JSON-RPC query
 												data_options.query = function(options) {
 													var settings = {
-														url: data.amsSelect2MethodTarget || ams.jsonrpc.getAddr(),
-														type: data.amsSelect2MethodType || 'POST',
-														cache: false,
-														method: data.amsSelect2QueryMethod,
+														id: new Date().getTime(),
 														params: data.amsSelect2QueryParams || {},
-														success: function(data, status) {
-															return ams.helpers.select2QueryMethodSuccessCallback.call(select, data, status, options);
+														success: function(result) {
+															return ams.helpers.select2QueryMethodSuccessCallback.call(select, result, 'success', options);
 														},
 														error: ams.error.show
 													};
@@ -2154,10 +2286,16 @@
 													settings.params[data.amsSelect2ContextParamName || 'context'] = options.context;
 													settings = $.extend({}, settings, data.amsSelect2QueryOptions);
 													settings = ams.executeFunctionByName(data.amsSelect2QueryInitCallback, select, settings) || settings;
-													ams.ajax.check($.jsonRpc,
+													ams.ajax.check($.jsonRPC,
 																   ams.baseURL + 'ext/jquery-jsonrpc' + (ams.devmode ? '.js' : '.min.js'),
 																   function() {
-																		$.jsonRpc(settings);
+																		$.jsonRPC.withOptions({
+																			endPoint: data.amsSelect2MethodTarget || ams.jsonrpc.getAddr(),
+																			namespace: data.amsSelect2MethodNamespace,
+																			cache: false
+																		}, function() {
+																			$.jsonRPC.request(data.amsSelect2QueryMethod, settings);
+																		});
 																   });
 												};
 												data_options.minimumInputLength = data.amsSelect2MinimumInputLength || 1;
@@ -2319,6 +2457,33 @@
 			},
 
 			/**
+			 * JQuery color picker
+			 */
+			colorpicker: function(element) {
+				var colorpickers = $('.colorpicker', element);
+				if (colorpickers.length > 0) {
+					ams.ajax.check($.fn.minicolors,
+								   ams.baseURL + 'ext/jquery-minicolors' + (ams.devmode ? '.js' : '.min.js'),
+								   function(first_load) {
+										if (first_load) {
+											ams.getCSS(ams.baseURL + '../css/ext/jquery-minicolors' + (ams.devmode ? '.css' : '.min.css'), 'jquery-minicolors');
+										}
+										colorpickers.each(function() {
+											var input = $(this);
+											var data = input.data();
+											var data_options = {
+												position: data.amsColorpickerPosition || input.closest('label.input').data('ams-colorpicker-position') || 'bottom left'
+											};
+											var settings = $.extend({}, data_options, data.amsColorpickerOptions);
+											settings = ams.executeFunctionByName(data.amsColorpickerInitCallback, input, settings) || settings;
+											var plugin = input.minicolors(settings);
+											ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings);
+										});
+								   });
+				}
+			},
+
+			/**
 			 * JQuery typeahead plug-in
 			 */
 			typeahead: function(element) {
@@ -3015,13 +3180,13 @@
 			return function() {
 				var link = $(this);
 				MyAMS.skin.bigBox({
-					title: MyAMS.i18n.WARNING,
-					content: '<i class="text-danger fa fa-2x fa-bell shake animated"></i>&nbsp; ' + MyAMS.i18n.DELETE_WARNING,
-					buttons: MyAMS.i18n.BTN_OK_CANCEL
+					title: ams.i18n.WARNING,
+					content: '<i class="text-danger fa fa-2x fa-bell shake animated"></i>&nbsp; ' + ams.i18n.DELETE_WARNING,
+					buttons: ams.i18n.BTN_OK_CANCEL
 				}, function(button) {
-					if (button == MyAMS.i18n.BTN_OK) {
+					if (button == ams.i18n.BTN_OK) {
 						var table = link.parents('table');
-						var location = table.data('ams-location');
+						var location = table.data('ams-location') || '';
 						var tr = link.parents('tr');
 						var delete_target = tr.data('ams-delete-target') || table.data('ams-delete-target') || 'delete-element.json';
 						var object_name = tr.data('ams-element-name');
@@ -3672,7 +3837,6 @@
 			if (source.parents('#shortcut').exists())
 				setTimeout(ams.skin._hideShortcutButtons, 300);
 		});
-		$(document).on('shown.bs.modal', ams.dialog.shown);
 
 		// Initialize form buttons
 		$(document).on('click', 'button[type="submit"], button.submit', function() {