src/ztfy/myams/resources/js/myams.js
changeset 156 61176c64158d
parent 154 0fff49179f6d
child 160 6c271ae9cfd3
--- a/src/ztfy/myams/resources/js/myams.js	Fri Jan 29 15:36:00 2016 +0100
+++ b/src/ztfy/myams/resources/js/myams.js	Fri Jan 29 15:37:22 2016 +0100
@@ -91,7 +91,7 @@
 	 */
 	if ($.scrollbarWidth === undefined) {
 		$.scrollbarWidth = function() {
-			var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body');
+			var parent = $('<div style="width:50px; height:50px; overflow:auto"><div/></div>').appendTo('body');
 			var child = parent.children();
 			var width = child.innerWidth() - child.height(99).innerWidth();
 			parent.remove();
@@ -277,6 +277,10 @@
 
 			menu.find("LI A").on('click', function() {
 				var link = $(this);
+				if (link.hasClass('active')) {
+					return;
+				}
+				var href = link.attr('href').replace(/^#/,'');
 				var parent_ul = link.parent().find("UL");
 				if (settings.accordion) {
 					var parents = link.parent().parents("UL");
@@ -291,21 +295,22 @@
 						});
 						if (close) {
 							if (parent_ul !== visible[visibleIndex]) {
-								$(visible[visibleIndex]).slideUp(settings.speed, function() {
-									link.parent("LI")
-										.find("b:first")
-										.html(settings.closedSign);
-									link.parent("LI")
-										.removeClass("open");
-								});
+								var visibleItem = $(visible[visibleIndex]);
+								if (href || !visibleItem.hasClass('active')) {
+									visibleItem.slideUp(settings.speed, function () {
+										$(this).parent("LI")
+											.removeClass('open')
+											.find("B:first")
+											.delay(settings.speed)
+											.html(settings.closedSign);
+									});
+								}
 							}
 						}
 					});
 				}
 				var first_ul = link.parent().find("UL:first");
-				if (!link.attr('href').replace(/^#/,'') &&
-					first_ul.is(":visible") &&
-					!first_ul.hasClass("active")) {
+				if (!href && first_ul.is(":visible") && !first_ul.hasClass("active")) {
 					first_ul.slideUp(settings.speed, function() {
 						link.parent("LI")
 							.removeClass("open")
@@ -633,16 +638,16 @@
 		/**
 		 * Default JQuery AJAX error handler
 		 */
-		ajax: function(event, request /*, settings*/) {
-			if (request.statusText === 'OK') {
+		ajax: function(event, response, request, error) {
+			if (response.statusText === 'OK') {
 				return;
 			}
-			var response = ams.ajax.getResponse(request);
-			if (response.content_type === 'json') {
-				ams.ajax.handleJSON(response.data);
+			var ajax_response = ams.ajax.getResponse(response);
+			if (ajax_response.content_type === 'json') {
+				ams.ajax.handleJSON(ajax_response.data);
 			} else {
 				var title = event.statusText || event.type;
-				var message = request.responseText;
+				var message = response.responseText;
 				ams.skin.messageBox('error', {
 					title: ams.i18n.ERROR_OCCURED,
 					content: '<h4>' + title + '</h4><p>' + message + '</p>',
@@ -652,7 +657,7 @@
 			}
 			if (globals.console) {
 				globals.console.error(event);
-				globals.console.debug(request);
+				globals.console.debug(response);
 			}
 		},
 
@@ -794,8 +799,7 @@
 				dataType: 'json',
 				success: callback || function(data /*, status*/) {
 					result = data.result;
-				},
-				error: ams.error.show
+				}
 			};
 			var settings = $.extend({}, defaults, options);
 			$.ajax(settings);
@@ -1257,10 +1261,15 @@
 				focused = $('input, select', container).first();
 			}
 			if (focused.exists()) {
+				if (focused.hasClass('select2-input')) {
+					focused = focused.parents('.select2');
+				}
 				if (focused.hasClass('select2')) {
 					setTimeout(function() {
-						focused.select2('focus')
-						focused.select2('open');
+						focused.select2('focus');
+						if (focused.data('ams-focus-open') === true) {
+							focused.select2('open');
+						}
 					}, 100);
 				} else {
 					focused.focus();
@@ -1332,7 +1341,7 @@
 				return false;
 			}
 			// Remove remaining status messages
-			$('.alert-danger, SPAN.state-error', form).remove();
+			$('.alert-danger, SPAN.state-error', form).not('.persistent').remove();
 			$('.state-error', form).removeClassPrefix('state-');
 			// Check submit button
 			var button = $(form.data('ams-submit-button'));
@@ -1820,7 +1829,7 @@
 						}
 					}
 				}
-				ams.skin.alert(form, errors.error_level || 'error', header, message, errors.error_message);
+				ams.skin.alert($('fieldset:first', form), errors.error_level || 'error', header, message, errors.error_message);
 			}
 		}
 	};
@@ -1958,6 +1967,7 @@
 														var dialog = $('.modal-dialog', content.wrap('<div></div>').parent());
 														var dialog_data = dialog.data();
 														var data_options = {
+															backdrop: 'static',
 															overflow: dialog_data.amsModalOverflow || '.modal-viewport',
 															maxHeight: dialog_data.amsModalMaxHeight === undefined ?
 																	function() {
@@ -2267,50 +2277,103 @@
 				}
 			});
 
-			// Load and register new plug-ins
+			// Scan new element for plug-ins
+			var plugins = {};
+			var plugin;
+			var name;
+
 			$('[data-ams-plugins]', element).each(function() {
+
+				function registerPlugin(name, new_plugin) {
+					if (plugins.hasOwnProperty(name)) {
+						var plugin = plugins[name];
+						plugin.css = plugin.css || new_plugin.css;
+						if (new_plugin.callback) {
+							plugin.callbacks.push(new_plugin.callback);
+						}
+						if (new_plugin.register) {
+							plugin.register = true;
+						}
+						if (new_plugin.async === false) {
+							plugin.async = false;
+						}
+					} else {
+						plugins[name] = {
+							src: new_plugin.src,
+							css: new_plugin.css,
+							callbacks: new_plugin.callback ? [new_plugin.callback] : [],
+							register: new_plugin.register,
+							async: new_plugin.async
+						}
+					}
+				}
+
 				var source = $(this);
-				var plugins = {};
-				var name;
-				if (typeof(source.data('ams-plugins')) === 'string') {
+				var ams_plugins = source.data('ams-plugins');
+				if (typeof(ams_plugins) === 'string') {
 					var names = source.data('ams-plugins').split(/\s+/);
-					for (var index=0; index < names.length; index++) {
+					for (var index = 0; index < names.length; index++) {
 						name = names[index];
-						plugins[name] = {
+						var new_plugin = {
 							src: source.data('ams-plugin-' + name + '-src'),
 							css: source.data('ams-plugin-' + name + '-css'),
 							callback: source.data('ams-plugin-' + name + '-callback'),
 							register: source.data('ams-plugin-' + name + '-register'),
 							async: source.data('ams-plugin-' + name + '-async')
 						};
+						registerPlugin(name, new_plugin);
 					}
 				} else {
-					plugins = source.data('ams-plugins');
-				}
-				for (name in plugins) {
-					if (ams.plugins.enabled[name] === undefined) {
-						var plugin = plugins[name];
-						ams.getScript(plugin.src, function() {
-							var callback = plugin.callback;
-							if (callback) {
-								var called = ams.getFunctionByName(callback);
-								if (plugin.register !== false)
-									ams.plugins.enabled[name] = called;
-							} else {
-								if (plugin.register !== false)
-									ams.plugins.enabled[name] = null;
-							}
-							var css = plugin['css'];
-							if (css) {
-								ams.getCSS(css, name + '_css');
-							}
-						}, {
-							async: plugin.async === undefined ? true : plugin.async
-						});
+					for (name in ams_plugins) {
+						if (!ams_plugins.hasOwnProperty(name)) {
+							continue;
+						}
+						registerPlugin(name, ams_plugins[name]);
 					}
 				}
 			});
 
+			// Load new plug-ins and execute async ones
+			for (name in plugins) {
+				if (ams.plugins.enabled[name] === undefined) {
+					plugin = plugins[name];
+					ams.getScript(plugin.src, function() {
+						var index;
+						var callbacks = plugin.callbacks;
+						if (callbacks) {
+							for (index=0; index < callbacks.length; index++) {
+								var called = ams.getFunctionByName(callbacks[index]);
+								if (plugin.register !== false) {
+									var enabled = ams.plugins.enabled;
+									if (enabled.hasOwnProperty(name)) {
+										enabled[name].push(called);
+									} else {
+										enabled[name] = [called];
+									}
+								}
+							}
+						} else {
+							if (plugin.register !== false) {
+								ams.plugins.enabled[name] = null;
+							}
+						}
+						var css = plugin.css;
+						if (css) {
+							ams.getCSS(css, name + '_css');
+						}
+						// If running in async mode, registered plug-ins are run
+						// before callback is called so we call plug-in manually
+						if (callbacks && (plugin.async !== false)) {
+							for (index=0; index < callbacks.length; index++) {
+								callbacks[index](element);
+							}
+						}
+					}, {
+						async: plugin.async === undefined ? true : plugin.async
+					});
+				}
+			}
+
 			// Run all enabled plug-ins
 			for (var index in ams.plugins.enabled) {
 				if (!ams.plugins.enabled.hasOwnProperty(index)) {
@@ -2319,9 +2382,18 @@
 				if (disabled.indexOf(index) >= 0) {
 					continue;
 				}
-				var plugin = ams.plugins.enabled[index];
-				if (typeof(plugin) === 'function') {
-					plugin(element);
+				var callbacks = ams.plugins.enabled[index];
+				switch (typeof(callbacks)) {
+					case 'function':
+						callbacks(element);
+						break;
+					default:
+						for (var cb_index = 0; cb_index < callbacks.length; cb_index++) {
+							var callback = callbacks[cb_index];
+							if (typeof(callback) === 'function') {
+								callback(element);
+							}
+						}
 				}
 			}
 		},
@@ -2932,13 +3004,14 @@
 				var masks = $('[data-mask]', element);
 				if (masks.length > 0) {
 					ams.ajax.check($.fn.mask,
-								   ams.baseURL + 'ext/jquery-maskedinput-1.3.1.min.js',
+								   ams.baseURL + 'ext/jquery-maskedinput-1.4.1' + ams.devext + '.js',
 								   function() {
 										masks.each(function() {
 											var mask = $(this);
 											var data = mask.data();
 											var data_options = {
-												placeholder: data.amsMaskeditPlaceholder || 'X'
+												placeholder: data.amsMaskeditPlaceholder === undefined ? 'X' : data.amsMaskeditPlaceholder,
+												complete: ams.getFunctionByName(data.amsMaskeditComplete)
 											};
 											var settings = $.extend({}, data_options, data.amsMaskeditOptions);
 											settings = ams.executeFunctionByName(data.amsMaskeditInitCallback, mask, settings) || settings;
@@ -3397,21 +3470,27 @@
 								   function(first_load) {
 										tables.each(function() {
 											var table = $(this);
-											$(table).on('mouseover', 'tr', function() {
-												$(this.cells[0]).addClass('drag-handle');
-											}).on('mouseout', 'tr', function() {
-												$(this.cells[0]).removeClass('drag-handle');
-											});
 											var data = table.data();
+											if (data.amsTabledndDragHandle) {
+												$('tr', table).addClass('no-drag-handle');
+											} else {
+												$(table).on('mouseover', 'tr', function () {
+													$(this.cells[0]).addClass('drag-handle');
+												}).on('mouseout', 'tr', function () {
+													$(this.cells[0]).removeClass('drag-handle');
+												});
+											}
 											var data_options = {
 												onDragClass: data.amsTabledndDragClass || 'dragging-row',
-												onDragStart: data.amsTabledndDragStart,
+												onDragStart: ams.getFunctionByName(data.amsTabledndDragStart),
 												dragHandle: data.amsTabledndDragHandle,
 												scrollAmount: data.amsTabledndScrollAmount,
 												onAllowDrop: data.amsTabledndAllowDrop,
-												onDrop: data.amsTabledndDrop || function(dnd_table, row) {
+												onDrop: ams.getFunctionByName(data.amsTabledndDrop) || function(dnd_table, row) {
 													var target = data.amsTabledndDropTarget;
 													if (target) {
+														// Disable row click handler
+														$(row).data('ams-disabled-handlers', 'click');
 														var rows = [];
 														$(dnd_table.rows).each(function() {
 															var row_id = $(this).data('ams-element-name');
@@ -3425,6 +3504,10 @@
 														} else {
 															ams.ajax.post(target, {names: JSON.stringify(rows)});
 														}
+														// Restore row click handler
+														setTimeout(function() {
+															$(row).removeData('ams-disabled-handlers');
+														}, 50);
 													}
 													return false;
 												}
@@ -3907,11 +3990,11 @@
 		 * @margin: if true, a margin will be displayed around alert
 		 */
 		alert: function(parent, status, header, message, subtitle, margin) {
-			$('.alert', parent).remove();
 			if (status === 'error') {
 				status = 'danger';
 			}
-			var content = '<div class="' + (margin ? 'margin-10' : '') + ' alert alert-block alert-' + status + ' fade in">' +
+			$('.alert-' + status, parent).remove();
+			var content = '<div class="' + (margin ? 'margin-10' : '') + ' alert alert-block alert-' + status + ' padding-5 fade in">' +
 				'<a class="close" data-dismiss="alert"><i class="fa fa-check"></i></a>' +
 				'<h4 class="alert-heading">' +
 				'<i class="fa fa-fw fa-warning"></i> ' + header +
@@ -4018,9 +4101,12 @@
 		 */
 		_drawBreadCrumb: function() {
 			var crumb = $('#ribbon OL.breadcrumb');
-			crumb.empty()
-				 .append($('<li></li>').append($('<a></a>').text(ams.i18n.HOME)
-														   .attr('href', $('nav a[href!="#"]:first').attr('href'))));
+			$('li', crumb).not('.parent').remove();
+			if (!$('li', crumb).exists()) {
+				crumb.append($('<li></li>').append($('<a></a>').text(ams.i18n.HOME)
+															   .addClass('padding-right-5')
+															   .attr('href', $('nav a[href!="#"]:first').attr('href'))));
+			}
 			$('nav LI.active >A').each(function() {
 				var menu = $(this);
 				var body = $.trim(menu.clone()
@@ -4041,7 +4127,7 @@
 		checkURL: function() {
 
 			function updateActiveMenus(menu) {
-				$('nav .active').removeClass('active');
+				$('.active', nav).removeClass('active');
 				menu.addClass('open')
 					.addClass('active');
 				menu.parents('li').addClass('open active')
@@ -4053,6 +4139,7 @@
 			}
 
 			var menu;
+			var nav = $('nav');
 			var hash = location.hash;
 			var url = hash.replace(/^#/, '');
 			if (url) {
@@ -4060,7 +4147,7 @@
 				if (!container.exists()) {
 					container = $('body');
 				}
-				menu = $('nav A[href="' + hash + '"]');
+				menu = $('A[href="' + hash + '"]', nav);
 				if (menu.exists()) {
 					updateActiveMenus(menu);
 				}
@@ -4071,9 +4158,9 @@
 			} else {
 				var active_url = $('[data-ams-active-menu]').data('ams-active-menu');
 				if (active_url) {
-					menu = $('nav A[href="' + active_url + '"]');
+					menu = $('A[href="' + active_url + '"]', nav);
 				} else {
-					menu = $('nav >UL >LI >A[href!="#"]').first();
+					menu = $('>UL >LI >A[href!="#"]', nav).first();
 				}
 				if (menu.exists()) {
 					updateActiveMenus(menu);
@@ -4292,7 +4379,7 @@
 							   ams.baseURL + '/ext/jquery-smartclick' + ams.devext + '.js',
 							   function() {
 								   $('NAV UL A').noClickDelay();
-								   $('#hide-menu A').noClickDelay();
+								   $('A', '#hide-menu').noClickDelay();
 							   });
 			}
 		}
@@ -4384,8 +4471,9 @@
 		});
 
 		// Initialize left nav
-		$('NAV UL').myams_menu({
-			accordion : true,
+		var nav = $('nav');
+		$('UL', nav).myams_menu({
+			accordion : nav.data('ams-menu-accordion') !== false,
 			speed : ams.menu_speed
 		});
 
@@ -4429,7 +4517,7 @@
 							   ams.skin._setPageHeight();
 							   ams.skin._checkMobileWidth();
 						   });
-						   $('nav').resize(function() {
+						   nav.resize(function() {
 							   ams.skin._setPageHeight();
 						   });
 					   });
@@ -4441,6 +4529,10 @@
 			});
 			$(document).on('click', 'a[href!="#"]:not([data-toggle]), [data-ams-url]:not([data-toggle])', function(e) {
 				var link = $(e.currentTarget);
+				var handlers = link.data('ams-disabled-handlers');
+				if ((handlers === true) || (handlers === 'click')) {
+					return;
+				}
 				var href = link.attr('href') || link.data('ams-url');
 				if (!href || href.startsWith('javascript') || link.attr('target') || (link.data('ams-context-menu') === true)) {
 					return;
@@ -4502,6 +4594,10 @@
 		$(document).off('click.modal')
 				   .on('click', '[data-toggle="modal"]', function(e) {
 			var source = $(this);
+			var handlers = source.data('ams-disabled-handlers');
+			if ((handlers === true) || (handlers === 'click')) {
+				return;
+			}
 			if (source.data('ams-context-menu') === true) {
 				return;
 			}
@@ -4524,6 +4620,10 @@
 		// Initialize custom click handlers
 		$(document).on('click', '[data-ams-click-handler]', function(e) {
 			var source = $(this);
+			var handlers = source.data('ams-disabled-handlers');
+			if ((handlers === true) || (handlers === 'click')) {
+				return;
+			}
 			var data = source.data();
 			if (data.amsClickHandler) {
 				if ((data.amsStopPropagation === true) || (data.amsClickStopPropagation === true)) {
@@ -4542,6 +4642,10 @@
 		// Initialize custom change handlers
 		$(document).on('change', '[data-ams-change-handler]', function(e) {
 			var source = $(this);
+			var handlers = source.data('ams-disabled-handlers');
+			if ((handlers === true) || (handlers === 'change')) {
+				return;
+			}
 			var data = source.data();
 			if (data.amsChangeHandler) {
 				if (data.amsChangeKeepDefault !== true) {
@@ -4626,7 +4730,7 @@
 
 		// Init page content
 		ams.initContent(document);
-		if (ams.ajax_nav && $('nav').exists()) {
+		if (ams.ajax_nav && nav.exists()) {
 			ams.skin.checkURL();
 		}
 		ams.form.setFocus(document);