src/ztfy/myams/resources/js/myams.js
changeset 142 0201f1422bd7
parent 136 3ea42c4b9938
child 145 1a37bfc4aa5b
equal deleted inserted replaced
141:a4200ce41c25 142:0201f1422bd7
     8  * Custom administration and application skin tools
     8  * Custom administration and application skin tools
     9  * Released under Zope Public License ZPL 1.1
     9  * Released under Zope Public License ZPL 1.1
    10  * ©2014-2015 Thierry Florac <tflorac@ulthar.net>
    10  * ©2014-2015 Thierry Florac <tflorac@ulthar.net>
    11  */
    11  */
    12 
    12 
    13 (function($) {
    13 (function($, globals) {
       
    14 
       
    15 	"use strict";
    14 
    16 
    15 	/**
    17 	/**
    16 	 * String prototype extensions
    18 	 * String prototype extensions
    17 	 */
    19 	 */
    18 	String.prototype.startsWith = function(str) {
    20 	String.prototype.startsWith = function(str) {
    19 		var slen = this.length;
    21 		var slen = this.length,
    20 		var dlen = str.length;
    22 			dlen = str.length;
    21 		if (slen < dlen) {
    23 		if (slen < dlen) {
    22 			return false;
    24 			return false;
    23 		}
    25 		}
    24 		return (this.substr(0,dlen) == str);
    26 		return (this.substr(0,dlen) === str);
    25 	};
    27 	};
    26 
    28 
    27 	String.prototype.endsWith = function(str) {
    29 	String.prototype.endsWith = function(str) {
    28 		var slen = this.length;
    30 		var slen = this.length,
    29 		var dlen = str.length;
    31 			dlen = str.length;
    30 		if (slen < dlen) {
    32 		if (slen < dlen) {
    31 			return false;
    33 			return false;
    32 		}
    34 		}
    33 		return (this.substr(slen-dlen) == str);
    35 		return (this.substr(slen-dlen) === str);
    34 	};
    36 	};
    35 
    37 
    36 
    38 
    37 	/**
    39 	/**
    38 	 * Array prototype extensions
    40 	 * Array prototype extensions
    39 	 */
    41 	 */
    40 	if (!Array.prototype.indexOf) {
    42 	if (!Array.prototype.indexOf) {
    41 		Array.prototype.indexOf = function(elt /*, from*/) {
    43 		Array.prototype.indexOf = function(elt, from) {
    42 			var len = this.length;
    44 			var len = this.length;
    43 
    45 
    44 			var from = Number(arguments[1]) || 0;
    46 			from = Number(from) || 0;
    45 			from = (from < 0) ? Math.ceil(from) : Math.floor(from);
    47 			from = (from < 0) ? Math.ceil(from) : Math.floor(from);
    46 			if (from < 0)
    48 			if (from < 0) {
    47 				from += len;
    49 				from += len;
       
    50 			}
    48 
    51 
    49 			for (; from < len; from++) {
    52 			for (; from < len; from++) {
    50 				if (from in this &&
    53 				if (from in this && this[from] === elt) {
    51 					this[from] === elt)
       
    52 					return from;
    54 					return from;
       
    55 				}
    53 			}
    56 			}
    54 			return -1;
    57 			return -1;
    55 		};
    58 		};
    56 	}
    59 	}
    57 
    60 
    59 	/**
    62 	/**
    60 	 * JQuery 'econtains' expression
    63 	 * JQuery 'econtains' expression
    61 	 * Case insensitive contains expression
    64 	 * Case insensitive contains expression
    62 	 */
    65 	 */
    63 	$.expr[":"].econtains = function(obj, index, meta /*, stack*/) {
    66 	$.expr[":"].econtains = function(obj, index, meta /*, stack*/) {
    64 		return (obj.textContent || obj.innerText || $(obj).text() || "").toLowerCase() == meta[3].toLowerCase();
    67 		return (obj.textContent || obj.innerText || $(obj).text() || "").toLowerCase() === meta[3].toLowerCase();
    65 	};
    68 	};
    66 
    69 
    67 
    70 
    68 	/**
    71 	/**
    69 	 * JQuery 'withtext' expression
    72 	 * JQuery 'withtext' expression
    70 	 * Case sensitive exact search expression
    73 	 * Case sensitive exact search expression
    71 	 */
    74 	 */
    72 	$.expr[":"].withtext = function(obj, index, meta /*, stack*/) {
    75 	$.expr[":"].withtext = function(obj, index, meta /*, stack*/) {
    73 		return (obj.textContent || obj.innerText || $(obj).text() || "") == meta[3];
    76 		return (obj.textContent || obj.innerText || $(obj).text() || "") === meta[3];
    74 	};
    77 	};
    75 
    78 
    76 
    79 
    77 	/**
    80 	/**
    78 	 * JQuery filter on parents class
    81 	 * JQuery filter on parents class
   112 		/*
   115 		/*
   113 		 * Get object if it supports given CSS class,
   116 		 * Get object if it supports given CSS class,
   114 		 * otherwise looks for parents
   117 		 * otherwise looks for parents
   115 		 */
   118 		 */
   116 		objectOrParentWithClass: function(klass) {
   119 		objectOrParentWithClass: function(klass) {
   117 			if (this.hasClass(klass))
   120 			if (this.hasClass(klass)) {
   118 				return this;
   121 				return this;
   119 			else
   122 			} else {
   120 				return this.parents('.' + klass);
   123 				return this.parents('.' + klass);
       
   124 			}
   121 		},
   125 		},
   122 
   126 
   123 		/*
   127 		/*
   124 		 * Build an array of attributes of the given selection
   128 		 * Build an array of attributes of the given selection
   125 		 */
   129 		 */
   137 		 */
   141 		 */
   138 		style: function(styleName, value, priority) {
   142 		style: function(styleName, value, priority) {
   139 			// DOM node
   143 			// DOM node
   140 			var node = this.get(0);
   144 			var node = this.get(0);
   141 			// Ensure we have a DOM node
   145 			// Ensure we have a DOM node
   142 			if (typeof node == 'undefined') {
   146 			if (typeof(node) === 'undefined') {
   143 				return;
   147 				return;
   144 			}
   148 			}
   145 			// CSSStyleDeclaration
   149 			// CSSStyleDeclaration
   146 			var style = this.get(0).style;
   150 			var style = this.get(0).style;
   147 			// Getter/Setter
   151 			// Getter/Setter
   148 			if (typeof styleName != 'undefined') {
   152 			if (typeof(styleName) !== 'undefined') {
   149 				if (typeof value != 'undefined') {
   153 				if (typeof(value) !== 'undefined') {
   150 					// Set style property
   154 					// Set style property
   151 					priority = typeof priority != 'undefined' ? priority : '';
   155 					priority = typeof(priority) !== 'undefined' ? priority : '';
   152 					style.setProperty(styleName, value, priority);
   156 					style.setProperty(styleName, value, priority);
   153 					return this;
   157 					return this;
   154 				} else {
   158 				} else {
   155 					// Get style property
   159 					// Get style property
   156 					return style.getPropertyValue(styleName);
   160 					return style.getPropertyValue(styleName);
   165 		 * Remove CSS classes starting with a given prefix
   169 		 * Remove CSS classes starting with a given prefix
   166 		 */
   170 		 */
   167 		removeClassPrefix: function (prefix) {
   171 		removeClassPrefix: function (prefix) {
   168 			this.each(function (i, it) {
   172 			this.each(function (i, it) {
   169 				var classes = it.className.split(" ").map(function(item) {
   173 				var classes = it.className.split(" ").map(function(item) {
   170 					return item.startsWith(prefix) ? "" : item
   174 					return item.startsWith(prefix) ? "" : item;
   171 				});
   175 				});
   172 				it.className = $.trim(classes.join(" "))
   176 				it.className = $.trim(classes.join(" "));
   173 			});
   177 			});
   174 			return this;
   178 			return this;
   175 		},
   179 		},
   176 
   180 
   177 		/*
   181 		/*
   182 			function getMenuPosition(mouse, direction, scrollDir) {
   186 			function getMenuPosition(mouse, direction, scrollDir) {
   183 				var win = $(window)[direction](),
   187 				var win = $(window)[direction](),
   184 					menu = $(settings.menuSelector)[direction](),
   188 					menu = $(settings.menuSelector)[direction](),
   185 					position = mouse;
   189 					position = mouse;
   186 				// opening menu would pass the side of the page
   190 				// opening menu would pass the side of the page
   187 				if (mouse + menu > win && menu < mouse)
   191 				if (mouse + menu > win && menu < mouse) {
   188 					position -= menu;
   192 					position -= menu;
       
   193 				}
   189 				return position;
   194 				return position;
   190 			}
   195 			}
   191 
   196 
   192 			return this.each(function () {
   197 			return this.each(function () {
   193 
   198 
   195 				$('a', $(settings.menuSelector)).each(function() {
   200 				$('a', $(settings.menuSelector)).each(function() {
   196 					$(this).data('ams-context-menu', true);
   201 					$(this).data('ams-context-menu', true);
   197 				});
   202 				});
   198 				$(this).on("contextmenu", function (e) {
   203 				$(this).on("contextmenu", function (e) {
   199 					// return native menu if pressing control
   204 					// return native menu if pressing control
   200 					if (e.ctrlKey)
   205 					if (e.ctrlKey) {
   201 						return;
   206 						return;
       
   207 					}
   202 					//open menu
   208 					//open menu
   203 					$(settings.menuSelector).data("invokedOn", $(e.target))
   209 					$(settings.menuSelector).data("invokedOn", $(e.target))
   204 											.show()
   210 											.show()
   205 											.css({
   211 											.css({
   206 												position: 'fixed',
   212 												position: 'fixed',
   250 					menu_item.find("A:first")
   256 					menu_item.find("A:first")
   251 							 .append("<b class='collapse-sign'>" + settings.closedSign + "</b>");
   257 							 .append("<b class='collapse-sign'>" + settings.closedSign + "</b>");
   252 
   258 
   253 					// avoid jumping to the top of the page when the href is an #
   259 					// avoid jumping to the top of the page when the href is an #
   254 					var first_link = menu_item.find("A:first");
   260 					var first_link = menu_item.find("A:first");
   255 					if (first_link.attr('href') == "#") {
   261 					if (first_link.attr('href') === "#") {
   256 						first_link.click(function() {
   262 						first_link.click(function() {
   257 							return false;
   263 							return false;
   258 						});
   264 						});
   259 					}
   265 					}
   260 				}
   266 				}
   264 			menu.find("LI.active").each(function() {
   270 			menu.find("LI.active").each(function() {
   265 				var active_parent = $(this).parents('UL');
   271 				var active_parent = $(this).parents('UL');
   266 				var active_item = active_parent.parent('LI');
   272 				var active_item = active_parent.parent('LI');
   267 				active_parent.slideDown(settings.speed);
   273 				active_parent.slideDown(settings.speed);
   268 				active_item.find("b:first").html(settings.openedSign);
   274 				active_item.find("b:first").html(settings.openedSign);
   269 				active_item.addClass("open")
   275 				active_item.addClass("open");
   270 			});
   276 			});
   271 
   277 
   272 			menu.find("LI A").on('click', function() {
   278 			menu.find("LI A").on('click', function() {
   273 				var link = $(this);
   279 				var link = $(this);
   274 				var parent_ul = link.parent().find("UL");
   280 				var parent_ul = link.parent().find("UL");
   276 					var parents = link.parent().parents("UL");
   282 					var parents = link.parent().parents("UL");
   277 					var visible = menu.find("UL:visible");
   283 					var visible = menu.find("UL:visible");
   278 					visible.each(function(visibleIndex) {
   284 					visible.each(function(visibleIndex) {
   279 						var close = true;
   285 						var close = true;
   280 						parents.each(function(parentIndex) {
   286 						parents.each(function(parentIndex) {
   281 							if (parents[parentIndex] == visible[visibleIndex]) {
   287 							if (parents[parentIndex] === visible[visibleIndex]) {
   282 								close = false;
   288 								close = false;
   283 								return false;
   289 								return false;
   284 							}
   290 							}
   285 						});
   291 						});
   286 						if (close) {
   292 						if (close) {
   287 							if (parent_ul != visible[visibleIndex]) {
   293 							if (parent_ul !== visible[visibleIndex]) {
   288 								$(visible[visibleIndex]).slideUp(settings.speed, function() {
   294 								$(visible[visibleIndex]).slideUp(settings.speed, function() {
   289 									link.parent("LI")
   295 									link.parent("LI")
   290 										.find("b:first")
   296 										.find("b:first")
   291 										.html(settings.closedSign);
   297 										.html(settings.closedSign);
   292 									link.parent("LI")
   298 									link.parent("LI")
   305 							.removeClass("open")
   311 							.removeClass("open")
   306 							.find("B:first")
   312 							.find("B:first")
   307 							.delay(settings.speed)
   313 							.delay(settings.speed)
   308 							.html(settings.closedSign);
   314 							.html(settings.closedSign);
   309 					});
   315 					});
   310 				} else /*if (link.attr('href') != location.hash)*/ {
   316 				} else /*if (link.attr('href') !== location.hash)*/ {
   311 					first_ul.slideDown(settings.speed, function() {
   317 					first_ul.slideDown(settings.speed, function() {
   312 						link.parent("LI")
   318 						link.parent("LI")
   313 							.addClass("open")
   319 							.addClass("open")
   314 							.find("B:first")
   320 							.find("B:first")
   315 							.delay(settings.speed)
   321 							.delay(settings.speed)
   386 
   392 
   387 
   393 
   388 	/**
   394 	/**
   389 	 * MyAMS extensions to JQuery
   395 	 * MyAMS extensions to JQuery
   390 	 */
   396 	 */
   391 	if (window.MyAMS === undefined) {
   397 	if (globals.MyAMS === undefined) {
   392 		window.MyAMS = {
   398 		globals.MyAMS = {
   393 			devmode: true,
   399 			devmode: true,
   394 			devext: '',
   400 			devext: '',
   395 			lang: 'en',
   401 			lang: 'en',
   396 			throttle_delay: 350,
   402 			throttle_delay: 350,
   397 			menu_speed: 235,
   403 			menu_speed: 235,
   402 			enable_fastclick: false,
   408 			enable_fastclick: false,
   403 			warn_on_form_change: false,
   409 			warn_on_form_change: false,
   404 			ismobile: (/iphone|ipad|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase()))
   410 			ismobile: (/iphone|ipad|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase()))
   405 		};
   411 		};
   406 	}
   412 	}
       
   413 	var MyAMS = globals.MyAMS;
   407 	var ams = MyAMS;
   414 	var ams = MyAMS;
   408 
   415 
   409 	/**
   416 	/**
   410 	 * Get MyAMS base URL
   417 	 * Get MyAMS base URL
   411 	 * Copyright Andrew Davy: https://forrst.com/posts/Get_the_URL_of_the_current_javascript_file-Dst
   418 	 * Copyright Andrew Davy: https://forrst.com/posts/Get_the_URL_of_the_current_javascript_file-Dst
   422 	/**
   429 	/**
   423 	 * Extract parameter value from given query string
   430 	 * Extract parameter value from given query string
   424 	 */
   431 	 */
   425 	MyAMS.getQueryVar = function(src, varName) {
   432 	MyAMS.getQueryVar = function(src, varName) {
   426 		// Check src
   433 		// Check src
   427 		if (src.indexOf('?') < 0)
   434 		if (src.indexOf('?') < 0) {
   428 			return false;
   435 			return false;
   429 		if (!src.endsWith('&'))
   436 		}
       
   437 		if (!src.endsWith('&')) {
   430 			src += '&';
   438 			src += '&';
       
   439 		}
   431 		// Dynamic replacement RegExp
   440 		// Dynamic replacement RegExp
   432 		var regex = new RegExp('.*?[&\\?]' + varName + '=(.*?)&.*');
   441 		var regex = new RegExp('.*?[&\\?]' + varName + '=(.*?)&.*');
   433 		// Apply RegExp to the query string
   442 		// Apply RegExp to the query string
   434 		var val = src.replace(regex, "$1");
   443 		var val = src.replace(regex, "$1");
   435 		// If the string is the same, we didn't find a match - return false
   444 		// If the string is the same, we didn't find a match - return false
   436 		return val == src ? false : val;
   445 		return val === src ? false : val;
   437 	};
   446 	};
   438 
   447 
   439 
   448 
   440 	/**
   449 	/**
   441 	 * Color conversion function
   450 	 * Color conversion function
   442 	 */
   451 	 */
   443 	MyAMS.rgb2hex = function(color) {
   452 	MyAMS.rgb2hex = function(color) {
   444 		return "#" + $.map(color.match(/\b(\d+)\b/g), function(digit) {
   453 		return "#" + $.map(color.match(/\b(\d+)\b/g), function(digit) {
   445 			return ('0' + parseInt(digit).toString(16)).slice(-2)
   454 			return ('0' + parseInt(digit).toString(16)).slice(-2);
   446 		}).join('');
   455 		}).join('');
   447 	};
   456 	};
   448 
   457 
   449 
   458 
   450 	/**
   459 	/**
   463 	/**
   472 	/**
   464 	 * Get and execute a function given by name
   473 	 * Get and execute a function given by name
   465 	 * Small piece of code by Jason Bunting
   474 	 * Small piece of code by Jason Bunting
   466 	 */
   475 	 */
   467 	MyAMS.getFunctionByName = function(functionName, context) {
   476 	MyAMS.getFunctionByName = function(functionName, context) {
   468 		if (functionName === undefined)
   477 		if (functionName === undefined) {
   469 			return undefined;
   478 			return undefined;
   470 		else if (typeof(functionName) == 'function')
   479 		} else if (typeof(functionName) === 'function') {
   471 			return functionName;
   480 			return functionName;
       
   481 		}
   472 		var namespaces = functionName.split(".");
   482 		var namespaces = functionName.split(".");
   473 		var func = namespaces.pop();
   483 		var func = namespaces.pop();
   474 		context = (context === undefined || context === null) ? window : context;
   484 		context = (context === undefined || context === null) ? window : context;
   475 		for (var i=0; i < namespaces.length; i++) {
   485 		for (var i=0; i < namespaces.length; i++) {
   476 			try {
   486 			try {
   486 		}
   496 		}
   487 	};
   497 	};
   488 
   498 
   489 	MyAMS.executeFunctionByName = function(functionName, context /*, args */) {
   499 	MyAMS.executeFunctionByName = function(functionName, context /*, args */) {
   490 		var func = ams.getFunctionByName(functionName, window);
   500 		var func = ams.getFunctionByName(functionName, window);
   491 		if (typeof(func) == 'function') {
   501 		if (typeof(func) === 'function') {
   492 			var args = Array.prototype.slice.call(arguments, 2);
   502 			var args = Array.prototype.slice.call(arguments, 2);
   493 			return func.apply(context, args);
   503 			return func.apply(context, args);
   494 		}
   504 		}
   495 	};
   505 	};
   496 
   506 
   511 			dataType: 'script',
   521 			dataType: 'script',
   512 			url: ams.getSource(url),
   522 			url: ams.getSource(url),
   513 			success: callback,
   523 			success: callback,
   514 			error: ams.error.show,
   524 			error: ams.error.show,
   515 			cache: !ams.devmode,
   525 			cache: !ams.devmode,
   516 			async: typeof(callback) == 'function'
   526 			async: typeof(callback) === 'function'
   517 		};
   527 		};
   518 		var settings = $.extend({}, defaults, options);
   528 		var settings = $.extend({}, defaults, options);
   519 		return $.ajax(settings);
   529 		return $.ajax(settings);
   520 	};
   530 	};
   521 
   531 
   522 	MyAMS.getCSS = function(url, id) {
   532 	MyAMS.getCSS = function(url, id) {
   523 		var head = $('HEAD');
   533 		var head = $('HEAD');
   524 		var css = $('link[data-ams-id="' + id + '"]', head);
   534 		var css = $('link[data-ams-id="' + id + '"]', head);
   525 		if (css.length == 0) {
   535 		if (css.length === 0) {
   526 			var source = ams.getSource(url);
   536 			var source = ams.getSource(url);
   527 			if (ams.devmode)
   537 			if (ams.devmode) {
   528 				source += '?_=' + new Date().getTime();
   538 				source += '?_=' + new Date().getTime();
       
   539 			}
   529 			$('<link />').attr({rel: 'stylesheet',
   540 			$('<link />').attr({rel: 'stylesheet',
   530 								type: 'text/css',
   541 								type: 'text/css',
   531 								href: source,
   542 								href: source,
   532 								'data-ams-id': id})
   543 								'data-ams-id': id})
   533 						 .appendTo(head);
   544 						 .appendTo(head);
   562 	 */
   573 	 */
   563 	MyAMS.browser = {
   574 	MyAMS.browser = {
   564 
   575 
   565 		getInternetExplorerVersion: function() {
   576 		getInternetExplorerVersion: function() {
   566 			var rv = -1;
   577 			var rv = -1;
   567 			if (navigator.appName == "Microsoft Internet Explorer") {
   578 			if (navigator.appName === "Microsoft Internet Explorer") {
   568 				var ua = navigator.userAgent;
   579 				var ua = navigator.userAgent;
   569 				var re = new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");
   580 				var re = new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");
   570 				if (re.exec(ua) != null)
   581 				if (re.exec(ua) !== null) {
   571 					rv = parseFloat(RegExp.$1);
   582 					rv = parseFloat(RegExp.$1);
       
   583 				}
   572 			}
   584 			}
   573 			return rv;
   585 			return rv;
   574 		},
   586 		},
   575 
   587 
   576 		checkVersion: function() {
   588 		checkVersion: function() {
   577 			var msg = "You're not using Windows Internet Explorer.";
   589 			var msg = "You're not using Windows Internet Explorer.";
   578 			var ver = this.getInternetExplorerVersion();
   590 			var ver = this.getInternetExplorerVersion();
   579 			if (ver > -1) {
   591 			if (ver > -1) {
   580 				if (ver >= 8)
   592 				if (ver >= 8) {
   581 					msg = "You're using a recent copy of Windows Internet Explorer.";
   593 					msg = "You're using a recent copy of Windows Internet Explorer.";
   582 				else
   594 				} else {
   583 					msg = "You should upgrade your copy of Windows Internet Explorer.";
   595 					msg = "You should upgrade your copy of Windows Internet Explorer.";
   584 			}
   596 				}
   585 			alert(msg);
   597 			}
       
   598 			if (globals.alert) {
       
   599 				globals.alert(msg);
       
   600 			}
   586 		},
   601 		},
   587 
   602 
   588 		isIE8orlower: function() {
   603 		isIE8orlower: function() {
   589 			var msg = "0";
   604 			var msg = "0";
   590 			var ver = this.getInternetExplorerVersion();
   605 			var ver = this.getInternetExplorerVersion();
   591 			if (ver > -1) {
   606 			if (ver > -1) {
   592 				if (ver >= 9)
   607 				if (ver >= 9) {
   593 					msg = 0;
   608 					msg = 0;
   594 				else
   609 				} else {
   595 					msg = 1;
   610 					msg = 1;
       
   611 				}
   596 			}
   612 			}
   597 			return msg;
   613 			return msg;
   598 		},
   614 		},
   599 
   615 
   600 		copyToClipboard: function() {
   616 		copyToClipboard: function() {
   601 			return function() {
   617 			return function() {
   602 				var source = $(this);
   618 				var source = $(this);
   603 				source.parents('.btn-group').removeClass('open');
   619 				source.parents('.btn-group').removeClass('open');
   604 				window.prompt(MyAMS.i18n.CLIPBOARD_COPY, source.text());
   620 				if (globals.prompt) {
   605 			}
   621 					globals.prompt(MyAMS.i18n.CLIPBOARD_COPY, source.text());
       
   622 				}
       
   623 			};
   606 		}
   624 		}
   607 	};
   625 	};
   608 
   626 
   609 
   627 
   610 	/**
   628 	/**
   614 
   632 
   615 		/**
   633 		/**
   616 		 * Default JQuery AJAX error handler
   634 		 * Default JQuery AJAX error handler
   617 		 */
   635 		 */
   618 		ajax: function(event, request /*, settings*/) {
   636 		ajax: function(event, request /*, settings*/) {
   619 			if (request.statusText == 'OK')
   637 			if (request.statusText === 'OK') {
   620 				return;
   638 				return;
       
   639 			}
   621 			var response = ams.ajax.getResponse(request);
   640 			var response = ams.ajax.getResponse(request);
   622 			if (response.content_type == 'json') {
   641 			if (response.content_type === 'json') {
   623 				ams.ajax.handleJSON(response.data);
   642 				ams.ajax.handleJSON(response.data);
   624 			} else {
   643 			} else {
   625 				var title = event.statusText || event.type;
   644 				var title = event.statusText || event.type;
   626 				var message = request.responseText;
   645 				var message = request.responseText;
   627 				ams.skin.messageBox('error', {
   646 				ams.skin.messageBox('error', {
   629 					content: '<h4>' + title + '</h4><p>' + message + '</p>',
   648 					content: '<h4>' + title + '</h4><p>' + message + '</p>',
   630 					icon: 'fa fa-warning animated shake',
   649 					icon: 'fa fa-warning animated shake',
   631 					timeout: 10000
   650 					timeout: 10000
   632 				});
   651 				});
   633 			}
   652 			}
   634 			if (window.console) {
   653 			if (globals.console) {
   635 				console.error(event);
   654 				globals.console.error(event);
   636 				console.debug(request);
   655 				globals.console.debug(request);
   637 			}
   656 			}
   638 		},
   657 		},
   639 
   658 
   640 		/**
   659 		/**
   641 		 * Show AJAX error
   660 		 * Show AJAX error
   642 		 */
   661 		 */
   643 		show: function(request, status, error) {
   662 		show: function(request, status, error) {
   644 			if (!error)
   663 			if (!error) {
   645 				return;
   664 				return;
       
   665 			}
   646 			var response = ams.ajax.getResponse(request);
   666 			var response = ams.ajax.getResponse(request);
   647 			if (response.content_type == 'json') {
   667 			if (response.content_type === 'json') {
   648 				ams.ajax.handleJSON(response.data);
   668 				ams.ajax.handleJSON(response.data);
   649 			} else {
   669 			} else {
   650 				ams.skin.messageBox('error', {
   670 				ams.skin.messageBox('error', {
   651 					title: ams.i18n.ERRORS_OCCURED,
   671 					title: ams.i18n.ERRORS_OCCURED,
   652 					content: '<h4>' + status + '</h4><p>' + error + '</p>',
   672 					content: '<h4>' + status + '</h4><p>' + error + '</p>',
   653 					icon: "fa fa-warning animated shake",
   673 					icon: "fa fa-warning animated shake",
   654 					timeout: 10000
   674 					timeout: 10000
   655 				});
   675 				});
   656 			}
   676 			}
   657 			if (window.console) {
   677 			if (globals.console) {
   658 				console.error(error);
   678 				globals.console.error(error);
   659 				console.debug(request);
   679 				globals.console.debug(request);
   660 			}
   680 			}
   661 		}
   681 		}
   662 	};
   682 	};
   663 
   683 
   664 
   684 
   676 		 *   argument of this callback is a boolean value indicating if the script was just downloaded (true)
   696 		 *   argument of this callback is a boolean value indicating if the script was just downloaded (true)
   677 		 *   or if the requested object was already loaded (false)
   697 		 *   or if the requested object was already loaded (false)
   678 		 * @options: callback options
   698 		 * @options: callback options
   679 		 */
   699 		 */
   680 		check: function(checker, source, callback, options) {
   700 		check: function(checker, source, callback, options) {
   681 			if (typeof(callback) == 'object') {
   701 			if (typeof(callback) === 'object') {
   682 				options = callback;
   702 				options = callback;
   683 				callback = undefined;
   703 				callback = undefined;
   684 			}
   704 			}
   685 			var defaults = {
   705 			var defaults = {
   686 				async: typeof(callback) == 'function'
   706 				async: typeof(callback) === 'function'
   687 			};
   707 			};
   688 			var settings = $.extend({}, defaults, options);
   708 			var settings = $.extend({}, defaults, options);
   689 			if (checker === undefined) {
   709 			if (checker === undefined) {
   690 				ams.getScript(source, function() {
   710 				ams.getScript(source, function() {
   691 					if (typeof(callback) == 'function')
   711 					if (typeof(callback) === 'function') {
   692 						callback(true, options);
   712 						callback(true, options);
       
   713 					}
   693 				}, settings);
   714 				}, settings);
   694 			} else {
   715 			} else {
   695 				if (typeof(callback) == 'function')
   716 				if (typeof(callback) === 'function') {
   696 					callback(false, options);
   717 					callback(false, options);
       
   718 				}
   697 			}
   719 			}
   698 		},
   720 		},
   699 
   721 
   700 		/**
   722 		/**
   701 		 * Get address relative to current page
   723 		 * Get address relative to current page
   725 		 * @param event: the source event
   747 		 * @param event: the source event
   726 		 * @param request: the request
   748 		 * @param request: the request
   727 		 * @param options: AJAX options
   749 		 * @param options: AJAX options
   728 		 */
   750 		 */
   729 		progress: function(event) {
   751 		progress: function(event) {
   730 			if (!event.lengthComputable)
   752 			if (!event.lengthComputable) {
   731 				return;
   753 				return;
   732 			if (event.loaded >= event.total)
   754 			}
       
   755 			if (event.loaded >= event.total) {
   733 				return;
   756 				return;
   734 			console.log(parseInt((event.loaded / event.total * 100), 10) + "%");
   757 			}
       
   758 			if (globals.console) {
       
   759 				globals.console.log(parseInt((event.loaded / event.total * 100), 10) + "%");
       
   760 			}
   735 		},
   761 		},
   736 
   762 
   737 		/**
   763 		/**
   738 		 * Post data to given URL
   764 		 * Post data to given URL
   739 		 */
   765 		 */
   740 		post: function(url, data, options, callback) {
   766 		post: function(url, data, options, callback) {
   741 			if (url.startsWith(window.location.protocol))
   767 			var addr;
   742 				var addr = url;
   768 			if (url.startsWith(window.location.protocol)) {
   743 			else
   769 				addr = url;
       
   770 			} else {
   744 				addr = this.getAddr() + url;
   771 				addr = this.getAddr() + url;
   745 			if (typeof(options) == 'function') {
   772 			}
       
   773 			if (typeof(options) === 'function') {
   746 				callback = options;
   774 				callback = options;
   747 				options = {}
   775 				options = {};
   748 			} else if (!options) {
   776 			} else if (!options) {
   749 				options = {};
   777 				options = {};
   750 			}
   778 			}
   751 			if (typeof(callback) == 'undefined')
   779 			if (typeof(callback) === 'undefined') {
   752 				callback = options.callback;
   780 				callback = options.callback;
   753 			if (typeof(callback) == 'string')
   781 			}
       
   782 			if (typeof(callback) === 'string') {
   754 				callback = ams.getFunctionByName(callback);
   783 				callback = ams.getFunctionByName(callback);
       
   784 			}
   755 			delete options.callback;
   785 			delete options.callback;
   756 
   786 
   757 			var result = undefined;
   787 			var result;
   758 			var defaults = {
   788 			var defaults = {
   759 				url: addr,
   789 				url: addr,
   760 				type: 'post',
   790 				type: 'post',
   761 				cache: false,
   791 				cache: false,
   762 				async: typeof(callback) == 'function',
   792 				async: typeof(callback) === 'function',
   763 				data: $.param(data),
   793 				data: $.param(data),
   764 				dataType: 'json',
   794 				dataType: 'json',
   765 				success: callback || function(data /*, status*/) {
   795 				success: callback || function(data /*, status*/) {
   766 					result = data.result;
   796 					result = data.result;
   767 				},
   797 				},
   790 				} else if (content_type.startsWith('text/xml')) {
   820 				} else if (content_type.startsWith('text/xml')) {
   791 					data_type = 'xml';
   821 					data_type = 'xml';
   792 					result = request.responseText;
   822 					result = request.responseText;
   793 				} else {
   823 				} else {
   794 					result = request.responseJSON;
   824 					result = request.responseJSON;
   795 					if (result)
   825 					if (result) {
   796 						data_type = 'json';
   826 						data_type = 'json';
   797 					else {
   827 					} else {
   798 						try {
   828 						try {
   799 							result = JSON.parse(request.responseText);
   829 							result = JSON.parse(request.responseText);
   800 							data_type = 'json';
   830 							data_type = 'json';
   801 						} catch (e) {
   831 						} catch (e) {
   802 							result = request.responseText;
   832 							result = request.responseText;
   842 		handleJSON: function(result, form, target) {
   872 		handleJSON: function(result, form, target) {
   843 			var status = result.status;
   873 			var status = result.status;
   844 			var url;
   874 			var url;
   845 			switch (status) {
   875 			switch (status) {
   846 				case 'alert':
   876 				case 'alert':
   847 					alert(result.alert.title + '\n\n' + result.alert.content);
   877 					if (globals.alert) {
       
   878 						globals.alert(result.alert.title + '\n\n' + result.alert.content);
       
   879 					}
   848 					break;
   880 					break;
   849 				case 'error':
   881 				case 'error':
   850 					ams.form.showErrors(form, result);
   882 					ams.form.showErrors(form, result);
   851 					break;
   883 					break;
   852 				case 'info':
   884 				case 'info':
   853 				case 'success':
   885 				case 'success':
   854 					if (result.close_form != false)
   886 					if (result.close_form !== false) {
   855 						ams.dialog.close(form);
   887 						ams.dialog.close(form);
       
   888 					}
   856 					break;
   889 					break;
   857 				case 'message':
   890 				case 'message':
   858 				case 'messagebox':
   891 				case 'messagebox':
   859 					break;
   892 					break;
   860 				case 'notify':
   893 				case 'notify':
   861 				case 'callback':
   894 				case 'callback':
   862 				case 'callbacks':
   895 				case 'callbacks':
   863 					if (result.close_form != false)
   896 					if (result.close_form !== false) {
   864 						ams.dialog.close(form);
   897 						ams.dialog.close(form);
       
   898 					}
   865 					break;
   899 					break;
   866 				case 'modal':
   900 				case 'modal':
   867 					ams.dialog.open(result.location);
   901 					ams.dialog.open(result.location);
   868 					break;
   902 					break;
   869 				case 'reload':
   903 				case 'reload':
   870 					if (result.close_form != false)
   904 					if (result.close_form !== false) {
   871 						ams.dialog.close(form);
   905 						ams.dialog.close(form);
       
   906 					}
   872 					url = result.location || window.location.hash;
   907 					url = result.location || window.location.hash;
   873 					if (url.startsWith('#'))
   908 					if (url.startsWith('#')) {
   874 						url = url.substr(1);
   909 						url = url.substr(1);
       
   910 					}
   875 					ams.skin.loadURL(url, result.target || target || '#content');
   911 					ams.skin.loadURL(url, result.target || target || '#content');
   876 					break;
   912 					break;
   877 				case 'redirect':
   913 				case 'redirect':
   878 					if (result.close_form == true)
   914 					if (result.close_form === true) {
   879 						ams.dialog.close(form);
   915 						ams.dialog.close(form);
       
   916 					}
   880 					url = result.location || window.location.href;
   917 					url = result.location || window.location.href;
   881 					if (result.window) {
   918 					if (result.window) {
   882 						window.open(url, result.window, result.options);
   919 						window.open(url, result.window, result.options);
   883 					} else {
   920 					} else {
   884 						if (window.location.href == url) {
   921 						if (window.location.href === url) {
   885 							window.location.reload(true);
   922 							window.location.reload(true);
   886 						} else {
   923 						} else {
   887 							window.location.href = url;
   924 							window.location.href = url;
   888 						}
   925 						}
   889 					}
   926 					}
   890 					break;
   927 					break;
   891 				default:
   928 				default:
   892 					console.log("Unhandled status: " + status);
   929 					if (globals.console) {
   893 					break;
   930 						globals.console.log("Unhandled status: " + status);
   894 			}
   931 					}
       
   932 			}
       
   933 
       
   934 			var index;
       
   935 			var content;
       
   936 			var container;
   895 			if (result.content) {
   937 			if (result.content) {
   896 				var content = result.content;
   938 				content = result.content;
   897 				var container = $(content.target || target || form || '#content');
   939 				container = $(content.target || target || form || '#content');
   898 				if (content.raw == true) {
   940 				if (content.raw === true) {
   899 					container.text(content.text);
   941 					container.text(content.text);
   900 				} else {
   942 				} else {
   901 					container.html(content.html);
   943 					container.html(content.html);
   902 					ams.initContent(container);
   944 					ams.initContent(container);
   903 				}
   945 				}
   904 				if (!content.keep_hidden)
   946 				if (!content.keep_hidden) {
   905 					container.removeClass('hidden');
   947 					container.removeClass('hidden');
       
   948 				}
   906 			}
   949 			}
   907 			if (result.contents) {
   950 			if (result.contents) {
   908 				var contents = result.contents;
   951 				var contents = result.contents;
   909 				for (var index in contents) {
   952 				for (index=0; index < contents.length; index++) {
   910 					content = contents[index];
   953 					content = contents[index];
   911 					container = $(content.target);
   954 					container = $(content.target);
   912 					if (content.raw == true) {
   955 					if (content.raw === true) {
   913 						container.text(content.text);
   956 						container.text(content.text);
   914 					} else {
   957 					} else {
   915 						container.html(content.html);
   958 						container.html(content.html);
   916 						ams.initContent(container);
   959 						ams.initContent(container);
   917 					}
   960 					}
   918 					if (!content.keep_hidden)
   961 					if (!content.keep_hidden) {
   919 						container.removeClass('hidden');
   962 						container.removeClass('hidden');
   920 				}
   963 					}
   921 			}
   964 				}
       
   965 			}
       
   966 
       
   967 			var message;
   922 			if (result.message) {
   968 			if (result.message) {
   923 				var message = result.message;
   969 				message = result.message;
   924 				if (typeof(message) == 'string') {
   970 				if (typeof(message) === 'string') {
   925 					if ((status == 'info') || (status == 'success'))
   971 					if ((status === 'info') || (status === 'success')) {
   926 						ams.skin.smallBox(status,
   972 						ams.skin.smallBox(status,
   927 										  {title: message,
   973 										  {
   928 										   icon: 'fa fa-fw fa-info-circle font-xs align-top margin-top-10',
   974 											  title: message,
   929 										   timeout: 3000});
   975 											  icon: 'fa fa-fw fa-info-circle font-xs align-top margin-top-10',
   930 					else
   976 											  timeout: 3000
       
   977 										  });
       
   978 					} else {
   931 						ams.skin.alert($(form || '#content'), status, message);
   979 						ams.skin.alert($(form || '#content'), status, message);
   932 				} else
   980 					}
       
   981 				} else {
   933 					ams.skin.alert($(message.target || target || form || '#content'),
   982 					ams.skin.alert($(message.target || target || form || '#content'),
   934 								   message.status || 'success',
   983 								   message.status || 'success',
   935 								   message.header,
   984 								   message.header,
   936 								   message.body,
   985 								   message.body,
   937 								   message.subtitle);
   986 								   message.subtitle);
       
   987 				}
   938 			}
   988 			}
   939 			if (result.smallbox) {
   989 			if (result.smallbox) {
   940 				ams.skin.smallBox(result.smallbox_status || status,
   990 				ams.skin.smallBox(result.smallbox_status || status,
   941 								  {title: result.smallbox,
   991 								  {title: result.smallbox,
   942 								   icon: 'fa fa-fw fa-info-circle font-xs align-top margin-top-10',
   992 								   icon: 'fa fa-fw fa-info-circle font-xs align-top margin-top-10',
   943 								   timeout: 3000});
   993 								   timeout: 3000});
   944 			}
   994 			}
   945 			if (result.messagebox) {
   995 			if (result.messagebox) {
   946 				message = result.messagebox;
   996 				message = result.messagebox;
   947 				if (typeof(message) == 'string')
   997 				if (typeof(message) === 'string') {
   948 					ams.skin.messageBox('info',
   998 					ams.skin.messageBox('info',
   949 										{title: ams.i18n.ERROR_OCCURED,
   999 										{
   950 										 content: message,
  1000 											title: ams.i18n.ERROR_OCCURED,
   951 										 timeout: 10000});
  1001 											content: message,
   952 				else {
  1002 											timeout: 10000
       
  1003 										});
       
  1004 				} else {
   953 					var message_status = message.status || 'info';
  1005 					var message_status = message.status || 'info';
   954 					if (message_status == 'error' && form && target)
  1006 					if (message_status === 'error' && form && target) {
   955 						ams.executeFunctionByName(form.data('ams-form-submit-error') || 'MyAMS.form.finalizeSubmitOnError', form, target);
  1007 						ams.executeFunctionByName(form.data('ams-form-submit-error') || 'MyAMS.form.finalizeSubmitOnError', form, target);
       
  1008 					}
   956 					ams.skin.messageBox(message_status,
  1009 					ams.skin.messageBox(message_status,
   957 										{title: message.title || ams.i18n.ERROR_OCCURED,
  1010 										{title: message.title || ams.i18n.ERROR_OCCURED,
   958 										 content: message.content,
  1011 										 content: message.content,
   959 										 icon: message.icon,
  1012 										 icon: message.icon,
   960 										 number: message.number,
  1013 										 number: message.number,
   961 										 timeout: message.timeout == null ? undefined : (message.timeout || 10000)});
  1014 										 timeout: message.timeout === null ? undefined : (message.timeout || 10000)});
   962 				}
  1015 				}
   963 			}
  1016 			}
   964 			if (result.event)
  1017 			if (result.event) {
   965 				form.trigger(result.event, result.event_options);
  1018 				form.trigger(result.event, result.event_options);
   966 			if (result.callback)
  1019 			}
       
  1020 			if (result.callback) {
   967 				ams.executeFunctionByName(result.callback, form, result.options);
  1021 				ams.executeFunctionByName(result.callback, form, result.options);
       
  1022 			}
   968 			if (result.callbacks) {
  1023 			if (result.callbacks) {
   969 				for (index in result.callbacks) {
  1024 				var callback;
   970 					if (!$.isNumeric(index))
  1025 				for (index=0; index < result.callbacks.length; index++) {
   971 						continue;
  1026 					callback = result.callbacks[index];
   972 					var callback = result.callbacks[index];
       
   973 					ams.executeFunctionByName(callback, form, callback.options);
  1027 					ams.executeFunctionByName(callback, form, callback.options);
   974 				}
  1028 				}
   975 			}
  1029 			}
   976 		}
  1030 		}
   977 	};
  1031 	};
  1003 		 */
  1057 		 */
  1004 		query: function(query, method, options, callback) {
  1058 		query: function(query, method, options, callback) {
  1005 			ams.ajax.check($.jsonRpc,
  1059 			ams.ajax.check($.jsonRpc,
  1006 						   ams.baseURL + 'ext/jquery-jsonrpc' + ams.devext + '.js',
  1060 						   ams.baseURL + 'ext/jquery-jsonrpc' + ams.devext + '.js',
  1007 						   function() {
  1061 						   function() {
  1008 								var result;
  1062 								if (typeof(options) === 'function') {
  1009 								if (typeof(options) == 'function') {
       
  1010 									callback = options;
  1063 									callback = options;
  1011 									options = {};
  1064 									options = {};
  1012 								}
  1065 								}
  1013 								else if (!options)
  1066 								else if (!options) {
  1014 									options = {};
  1067 									options = {};
  1015 								if (typeof(callback) == 'undefined')
  1068 								}
       
  1069 								if (callback === 'undefined') {
  1016 									callback = options.callback;
  1070 									callback = options.callback;
  1017 								if (typeof(callback) == 'string')
  1071 								}
       
  1072 								if (typeof(callback) === 'string') {
  1018 									callback = ams.getFunctionByName(callback);
  1073 									callback = ams.getFunctionByName(callback);
       
  1074 								}
  1019 								delete options.callback;
  1075 								delete options.callback;
  1020 
  1076 
  1021 								var params = {};
  1077 								var params = {};
  1022 								if (typeof(query) == 'string')
  1078 								if (typeof(query) === 'string') {
  1023 									params['query'] = query;
  1079 									params.query = query;
  1024 								else if (typeof(query) == 'object')
  1080 								} else if (typeof(query) === 'object') {
  1025 									$.extend(params, query);
  1081 									$.extend(params, query);
       
  1082 								}
  1026 								$.extend(params, options);
  1083 								$.extend(params, options);
  1027 
  1084 
       
  1085 								var result;
  1028 								var settings = {
  1086 								var settings = {
  1029 									url: ams.jsonrpc.getAddr(options.url),
  1087 									url: ams.jsonrpc.getAddr(options.url),
  1030 									type: 'post',
  1088 									type: 'post',
  1031 									cache: false,
  1089 									cache: false,
  1032 									method: method,
  1090 									method: method,
  1033 									params: params,
  1091 									params: params,
  1034 									async: typeof(callback) == 'function',
  1092 									async: typeof(callback) === 'function',
  1035 									success: callback || function(data /*, status*/) {
  1093 									success: callback || function(data /*, status*/) {
  1036 										result = data.result;
  1094 										result = data.result;
  1037 									},
  1095 									},
  1038 									error: ams.error.show
  1096 									error: ams.error.show
  1039 								};
  1097 								};
  1052 		 */
  1110 		 */
  1053 		post: function(method, data, options, callback) {
  1111 		post: function(method, data, options, callback) {
  1054 			ams.ajax.check($.jsonRpc,
  1112 			ams.ajax.check($.jsonRpc,
  1055 						   ams.baseURL + 'ext/jquery-jsonrpc' + ams.devext + '.js',
  1113 						   ams.baseURL + 'ext/jquery-jsonrpc' + ams.devext + '.js',
  1056 						   function() {
  1114 						   function() {
  1057 								var result;
  1115 								if (typeof(options) === 'function') {
  1058 								if (typeof(options) == 'function') {
       
  1059 									callback = options;
  1116 									callback = options;
  1060 									options = {};
  1117 									options = {};
  1061 								}
  1118 								}
  1062 								else if (!options)
  1119 								else if (!options) {
  1063 									options = {};
  1120 									options = {};
  1064 								if (typeof(callback) == 'undefined')
  1121 								}
       
  1122 								if (typeof(callback) === 'undefined') {
  1065 									callback = options.callback;
  1123 									callback = options.callback;
  1066 								if (typeof(callback) == 'string')
  1124 								}
       
  1125 								if (typeof(callback) === 'string') {
  1067 									callback = ams.getFunctionByName(callback);
  1126 									callback = ams.getFunctionByName(callback);
       
  1127 								}
  1068 								delete options.callback;
  1128 								delete options.callback;
  1069 
  1129 
  1070 								var result;
  1130 								var result;
  1071 								var defaults = {
  1131 								var defaults = {
  1072 									url: ams.jsonrpc.getAddr(options.url),
  1132 									url: ams.jsonrpc.getAddr(options.url),
  1073 									type: 'post',
  1133 									type: 'post',
  1074 									cache: false,
  1134 									cache: false,
  1075 									method: method,
  1135 									method: method,
  1076 									params: data,
  1136 									params: data,
  1077 									async: typeof(callback) == 'function',
  1137 									async: typeof(callback) === 'function',
  1078 									success: callback || function(data /*, status*/) {
  1138 									success: callback || function(data /*, status*/) {
  1079 										result = data.result;
  1139 										result = data.result;
  1080 									},
  1140 									},
  1081 									error: ams.error.show
  1141 									error: ams.error.show
  1082 								};
  1142 								};
  1113 		 */
  1173 		 */
  1114 		post: function(url, method, data, options, callback) {
  1174 		post: function(url, method, data, options, callback) {
  1115 			ams.ajax.check($.xmlrpc,
  1175 			ams.ajax.check($.xmlrpc,
  1116 						   ams.baseURL + 'ext/jquery-xmlrpc' + ams.devext + '.js',
  1176 						   ams.baseURL + 'ext/jquery-xmlrpc' + ams.devext + '.js',
  1117 						   function() {
  1177 						   function() {
  1118 								var result;
  1178 								if (typeof(options) === 'function') {
  1119 								if (typeof(options) == 'function') {
       
  1120 									callback = options;
  1179 									callback = options;
  1121 									options = {};
  1180 									options = {};
  1122 								}
  1181 								}
  1123 								else if (!options)
  1182 								else if (!options) {
  1124 									options = {};
  1183 									options = {};
  1125 								if (typeof(callback) == 'undefined')
  1184 								}
       
  1185 								if (typeof(callback) === 'undefined') {
  1126 									callback = options.callback;
  1186 									callback = options.callback;
  1127 								if (typeof(callback) == 'string')
  1187 								}
       
  1188 								if (typeof(callback) === 'string') {
  1128 									callback = ams.getFunctionByName(callback);
  1189 									callback = ams.getFunctionByName(callback);
       
  1190 								}
  1129 								delete options.callback;
  1191 								delete options.callback;
  1130 
  1192 
       
  1193 								var result;
  1131 								var defaults = {
  1194 								var defaults = {
  1132 									url: ams.xmlrpc.getAddr(url),
  1195 									url: ams.xmlrpc.getAddr(url),
  1133 									methodName: method,
  1196 									methodName: method,
  1134 									params: data,
  1197 									params: data,
  1135 									success: callback || function(response /*, status, xhr*/) {
  1198 									success: callback || function(response /*, status, xhr*/) {
  1155 		 *
  1218 		 *
  1156 		 * @param element: the parent element
  1219 		 * @param element: the parent element
  1157 		 */
  1220 		 */
  1158 		init: function(element) {
  1221 		init: function(element) {
  1159 			// Activate form changes if required
  1222 			// Activate form changes if required
  1160 			if (ams.warn_on_form_change)
  1223 			var forms;
  1161 				var forms = $('FORM[data-ams-warn-on-change!="false"]', element);
  1224 			if (ams.warn_on_form_change) {
  1162 			else
  1225 				forms = $('FORM[data-ams-warn-on-change!="false"]', element);
       
  1226 			} else {
  1163 				forms = $('FORM[data-ams-warn-on-change="true"]', element);
  1227 				forms = $('FORM[data-ams-warn-on-change="true"]', element);
       
  1228 			}
  1164 			forms.each(function() {
  1229 			forms.each(function() {
  1165 				var form = $(this);
  1230 				var form = $(this);
  1166 				$('INPUT[type="text"], ' +
  1231 				$('INPUT[type="text"], ' +
  1167 				  'INPUT[type="checkbox"], ' +
  1232 				  'INPUT[type="checkbox"], ' +
  1168 				  'INPUT[type="radio"], ' +
  1233 				  'INPUT[type="radio"], ' +
  1195 
  1260 
  1196 		/**
  1261 		/**
  1197 		 * Check for modified forms before loading new inner content
  1262 		 * Check for modified forms before loading new inner content
  1198 		 */
  1263 		 */
  1199 		confirmChangedForm: function(element, callback) {
  1264 		confirmChangedForm: function(element, callback) {
  1200 			if (typeof(element) == 'function') {
  1265 			if (typeof(element) === 'function') {
  1201 				callback = element;
  1266 				callback = element;
  1202 				element = undefined;
  1267 				element = undefined;
  1203 			}
  1268 			}
  1204 			var forms = $('FORM[data-ams-form-changed="true"]', element);
  1269 			var forms = $('FORM[data-ams-form-changed="true"]', element);
  1205 			if (forms.exists()) {
  1270 			if (forms.exists()) {
  1206 				ams.skin.bigBox({
  1271 				ams.skin.bigBox({
  1207 					title: ams.i18n.WARNING,
  1272 					title: ams.i18n.WARNING,
  1208 					content: '<i class="text-danger fa fa-2x fa-bell shake animated"></i>&nbsp; ' + ams.i18n.FORM_CHANGED_WARNING,
  1273 					content: '<i class="text-danger fa fa-2x fa-bell shake animated"></i>&nbsp; ' + ams.i18n.FORM_CHANGED_WARNING,
  1209 					buttons: ams.i18n.BTN_OK_CANCEL
  1274 					buttons: ams.i18n.BTN_OK_CANCEL
  1210 				}, function(button) {
  1275 				}, function(button) {
  1211 					if (button == ams.i18n.BTN_OK)
  1276 					if (button === ams.i18n.BTN_OK) {
  1212 						callback.call(element);
  1277 						callback.call(element);
       
  1278 					}
  1213 				});
  1279 				});
  1214 			} else {
  1280 			} else {
  1215 				callback.call(element);
  1281 				callback.call(element);
  1216 			}
  1282 			}
  1217 		},
  1283 		},
  1220 		 * Submit given form
  1286 		 * Submit given form
  1221 		 */
  1287 		 */
  1222 		submit: function(form, handler, submit_options) {
  1288 		submit: function(form, handler, submit_options) {
  1223 			// Check params
  1289 			// Check params
  1224 			form = $(form);
  1290 			form = $(form);
  1225 			if (!form.exists())
  1291 			if (!form.exists()) {
  1226 				return false;
  1292 				return false;
  1227 			if (typeof(handler) == 'object') {
  1293 			}
       
  1294 			if (typeof(handler) === 'object') {
  1228 				submit_options = handler;
  1295 				submit_options = handler;
  1229 				handler = undefined;
  1296 				handler = undefined;
  1230 			}
  1297 			}
  1231 			// Prevent multiple submits of the same form
  1298 			// Prevent multiple submits of the same form
  1232 			if (form.data('submitted')) {
  1299 			if (form.data('submitted')) {
  1239 					});
  1306 					});
  1240 				}
  1307 				}
  1241 				return false;
  1308 				return false;
  1242 			}
  1309 			}
  1243 			// Check submit validators
  1310 			// Check submit validators
  1244 			if (!ams.form._checkSubmitValidators(form))
  1311 			if (!ams.form._checkSubmitValidators(form)) {
  1245 				return false;
  1312 				return false;
       
  1313 			}
  1246 			// Remove remaining status messages
  1314 			// Remove remaining status messages
  1247 			$('.alert, SPAN.state-error', form).remove();
  1315 			$('.alert-danger, SPAN.state-error', form).remove();
  1248 			$('.state-error', form).removeClassPrefix('state-');
  1316 			$('.state-error', form).removeClassPrefix('state-');
  1249 			// Check submit button
  1317 			// Check submit button
  1250 			var button = $(form.data('ams-submit-button'));
  1318 			var button = $(form.data('ams-submit-button'));
  1251 			if (button && !button.data('ams-form-hide-loading'))
  1319 			if (button && !button.data('ams-form-hide-loading')) {
  1252 				button.button('loading');
  1320 				button.button('loading');
       
  1321 			}
  1253 			ams.ajax.check($.fn.ajaxSubmit,
  1322 			ams.ajax.check($.fn.ajaxSubmit,
  1254 						   ams.baseURL + 'ext/jquery-form-3.49' + ams.devext + '.js',
  1323 						   ams.baseURL + 'ext/jquery-form-3.49' + ams.devext + '.js',
  1255 						   function() {
  1324 						   function() {
  1256 
  1325 
  1257 								function _submitAjaxForm(form, options) {
  1326 								function _submitAjaxForm(form, options) {
  1258 
  1327 
  1259 									var button;
  1328 									var button;
  1260 									var data = form.data();
  1329 									var data = form.data();
  1261 									var form_options = data.amsFormOptions;
  1330 									var form_options = data.amsFormOptions;
  1262 
  1331 									var form_data;
  1263 									if (submit_options)
  1332 									var form_data_callback;
  1264 										var form_data_callback = submit_options.formDataInitCallback;
  1333 
  1265 									if (form_data_callback)
  1334 									if (submit_options) {
       
  1335 										form_data_callback = submit_options.formDataInitCallback;
       
  1336 									}
       
  1337 									if (form_data_callback) {
  1266 										delete submit_options.formDataInitCallback;
  1338 										delete submit_options.formDataInitCallback;
  1267 									else
  1339 									} else {
  1268 										form_data_callback = data.amsFormDataInitCallback;
  1340 										form_data_callback = data.amsFormDataInitCallback;
       
  1341 									}
  1269 									if (form_data_callback) {
  1342 									if (form_data_callback) {
  1270 										var veto = {};
  1343 										var veto = {};
  1271 										if (typeof(form_data_callback) == 'function')
  1344 										if (typeof(form_data_callback) === 'function') {
  1272 											var form_data = form_data_callback.call(form, veto);
  1345 											form_data = form_data_callback.call(form, veto);
  1273 										else
  1346 										} else {
  1274 											form_data = ams.executeFunctionByName(form_data_callback, form, veto);
  1347 											form_data = ams.executeFunctionByName(form_data_callback, form, veto);
       
  1348 										}
  1275 										if (veto.veto) {
  1349 										if (veto.veto) {
  1276 											button = form.data('ams-submit-button');
  1350 											button = form.data('ams-submit-button');
  1277 											if (button)
  1351 											if (button) {
  1278 												button.button('reset');
  1352 												button.button('reset');
       
  1353 											}
  1279 											ams.form.finalizeSubmitFooter.call(form);
  1354 											ams.form.finalizeSubmitFooter.call(form);
  1280 											return false;
  1355 											return false;
  1281 										}
  1356 										}
  1282 									} else {
  1357 									} else {
  1283 										form_data = data.amsFormData || {};
  1358 										form_data = data.amsFormData || {};
  1289 									if (button) {
  1364 									if (button) {
  1290 										buttonHandler = button.data('ams-form-handler');
  1365 										buttonHandler = button.data('ams-form-handler');
  1291 										buttonTarget = button.data('ams-form-submit-target');
  1366 										buttonTarget = button.data('ams-form-submit-target');
  1292 									}
  1367 									}
  1293 
  1368 
       
  1369 									var url;
  1294 									var form_handler = handler || buttonHandler || data.amsFormHandler || '';
  1370 									var form_handler = handler || buttonHandler || data.amsFormHandler || '';
  1295 									if (form_handler.startsWith(window.location.protocol)) {
  1371 									if (form_handler.startsWith(window.location.protocol)) {
  1296 										var url = form_handler;
  1372 										url = form_handler;
  1297 									} else {
  1373 									} else {
  1298 										var action = form.attr('action').replace(/#/, '');
  1374 										var action = form.attr('action').replace(/#/, '');
  1299 										if (action.startsWith(window.location.protocol))
  1375 										if (action.startsWith(window.location.protocol)) {
  1300 											url = action;
  1376 											url = action;
  1301 										else
  1377 										} else {
  1302 											url = ams.ajax.getAddr() + action;
  1378 											url = ams.ajax.getAddr() + action;
       
  1379 										}
  1303 										url += form_handler;
  1380 										url += form_handler;
  1304 									}
  1381 									}
  1305 
  1382 
  1306 									var target = null;
  1383 									var target = null;
  1307 									if (data.amsFormInitSubmitTarget) {
  1384 									if (submit_options && submit_options.initSubmitTarget) {
  1308 										target = $(buttonTarget || data.amsFormSubmitTarget || '#content');
  1385 										ams.executeFunctionByName(submit_options.initSubmitTarget);
  1309 										ams.executeFunctionByName(data.amsFormInitSubmit || 'MyAMS.form.initSubmit', form, target);
  1386 									} else {
  1310 									} else if (!data.amsFormHideSubmitFooter)
  1387 										if (data.amsFormInitSubmitTarget) {
  1311 										ams.executeFunctionByName(data.amsFormInitSubmit || 'MyAMS.form.initSubmitFooter', form);
  1388 											target = $(buttonTarget || data.amsFormSubmitTarget || '#content');
  1312 
  1389 											ams.executeFunctionByName(data.amsFormInitSubmit || 'MyAMS.form.initSubmit', form, target);
  1313 									var hasUpload = typeof(options.uuid) != 'undefined';
  1390 										} else if (!data.amsFormHideSubmitFooter) {
       
  1391 											ams.executeFunctionByName(data.amsFormInitSubmit || 'MyAMS.form.initSubmitFooter', form);
       
  1392 										}
       
  1393 									}
       
  1394 
       
  1395 									var hasUpload = typeof(options.uuid) !== 'undefined';
  1314 									if (hasUpload) {
  1396 									if (hasUpload) {
  1315 										if (url.indexOf('X-Progress-ID') < 0)
  1397 										if (url.indexOf('X-Progress-ID') < 0) {
  1316 											url += "?X-Progress-ID=" + options.uuid;
  1398 											url += "?X-Progress-ID=" + options.uuid;
       
  1399 										}
  1317 										delete options.uuid;
  1400 										delete options.uuid;
  1318 									}
  1401 									}
  1319 
  1402 
       
  1403 									if (submit_options) {
       
  1404 										form_data = $.extend({}, form_data, submit_options.form_data);
       
  1405 									}
  1320 									var defaults = {
  1406 									var defaults = {
  1321 										url: url,
  1407 										url: url,
  1322 										type: 'post',
  1408 										type: 'post',
  1323 										cache: false,
  1409 										cache: false,
  1324 										data: form_data,
  1410 										data: form_data,
  1325 										dataType: data.amsFormDatatype,
  1411 										dataType: data.amsFormDatatype,
  1326 										beforeSerialize: function(/*form, options*/) {
  1412 										beforeSerialize: function(/*form, options*/) {
  1327 											if (typeof(tinyMCE) != 'undefined')
  1413 											if (typeof(globals.tinyMCE) !== 'undefined') {
  1328 												tinyMCE.triggerSave();
  1414 												globals.tinyMCE.triggerSave();
       
  1415 											}
  1329 										},
  1416 										},
  1330 										beforeSubmit: function(data, form /*, options*/) {
  1417 										beforeSubmit: function(data, form /*, options*/) {
  1331 											form.data('submitted', true);
  1418 											form.data('submitted', true);
  1332 										},
  1419 										},
  1333 										error: function(request, status, error, form) {
  1420 										error: function(request, status, error, form) {
  1334 											if (target)
  1421 											if (target) {
  1335 												ams.executeFunctionByName(data.amsFormSubmitError || 'MyAMS.form.finalizeSubmitOnError', form, target);
  1422 												ams.executeFunctionByName(data.amsFormSubmitError || 'MyAMS.form.finalizeSubmitOnError', form, target);
       
  1423 											}
  1336 											if (form.is(':visible')) {
  1424 											if (form.is(':visible')) {
  1337 												var button = form.data('ams-submit-button');
  1425 												var button = form.data('ams-submit-button');
  1338 												if (button)
  1426 												if (button) {
  1339 													button.button('reset');
  1427 													button.button('reset');
       
  1428 												}
  1340 												ams.form.finalizeSubmitFooter.call(form);
  1429 												ams.form.finalizeSubmitFooter.call(form);
  1341 											}
  1430 											}
  1342 											form.data('submitted', false);
  1431 											form.data('submitted', false);
  1343 											form.removeData('ams-submit-button');
  1432 											form.removeData('ams-submit-button');
  1344 										},
  1433 										},
  1345 										iframe: hasUpload
  1434 										iframe: hasUpload
  1346 									}
  1435 									};
  1347 									var download_target = data.amsFormDownloadTarget;
  1436 									var download_target = (submit_options && submit_options.downloadTarget) || data.amsFormDownloadTarget;
  1348 									if (download_target) {
  1437 									if (download_target) {
  1349 										var iframe = $('iframe[name="' + download_target + '"]');
  1438 										var iframe = $('iframe[name="' + download_target + '"]');
  1350 										if (!iframe.exists())
  1439 										if (!iframe.exists()) {
  1351 											iframe = $('<iframe></iframe>').hide()
  1440 											iframe = $('<iframe></iframe>').hide()
  1352 																		   .attr('name', download_target)
  1441 																		   .attr('name', download_target)
  1353 																		   .appendTo(form);
  1442 																		   .appendTo(form);
       
  1443 										}
  1354 										defaults = $.extend({}, defaults, {
  1444 										defaults = $.extend({}, defaults, {
  1355 											iframe: true,
  1445 											iframe: true,
  1356 											iframeTarget: iframe,
  1446 											iframeTarget: iframe,
  1357 											success: function(result, status, request, form) {
  1447 											success: function(result, status, request, form) {
  1358 												var modal = $(form).parents('.modal-dialog');
  1448 												var modal = $(form).parents('.modal-dialog');
  1359 												if (modal.exists()) {
  1449 												if (modal.exists()) {
  1360 													ams.dialog.close(form);
  1450 													ams.dialog.close(form);
  1361 												} else {
  1451 												} else {
  1362 													var callback;
  1452 													var callback;
  1363 													var button = form.data('ams-submit-button');
  1453 													var button = form.data('ams-submit-button');
  1364 													if (button)
  1454 													if (button) {
  1365 														callback = button.data('ams-form-submit-callback');
  1455 														callback = button.data('ams-form-submit-callback');
  1366 													if (!callback)
  1456 													}
       
  1457 													if (!callback) {
  1367 														callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback;
  1458 														callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback;
       
  1459 													}
  1368 													callback.call(form, result, status, request, form);
  1460 													callback.call(form, result, status, request, form);
  1369 													if (form.is(':visible') && button)
  1461 													if (form.is(':visible') && button) {
  1370 														button.button('reset');
  1462 														button.button('reset');
       
  1463 													}
  1371 													form.data('submitted', false);
  1464 													form.data('submitted', false);
  1372 													form.removeData('ams-submit-button');
  1465 													form.removeData('ams-submit-button');
  1373 													form.removeAttr('data-ams-form-changed');
  1466 													form.removeAttr('data-ams-form-changed');
  1374 												}
  1467 												}
  1375 											}
  1468 											}
  1376 										});
  1469 										});
  1377 									} else {
  1470 									} else {
  1378 										defaults = $.extend({}, defaults, {
  1471 										defaults = $.extend({}, defaults, {
  1379 											error: function(request, status, error, form) {
  1472 											error: function(request, status, error, form) {
  1380 												if (target)
  1473 												if (target) {
  1381 													ams.executeFunctionByName(data.amsFormSubmitError || 'MyAMS.form.finalizeSubmitOnError', form, target);
  1474 													ams.executeFunctionByName(data.amsFormSubmitError || 'MyAMS.form.finalizeSubmitOnError', form, target);
       
  1475 												}
  1382 												if (form.is(':visible')) {
  1476 												if (form.is(':visible')) {
  1383 													var button = form.data('ams-submit-button');
  1477 													var button = form.data('ams-submit-button');
  1384 													if (button)
  1478 													if (button) {
  1385 														button.button('reset');
  1479 														button.button('reset');
       
  1480 													}
  1386 													ams.form.finalizeSubmitFooter.call(form);
  1481 													ams.form.finalizeSubmitFooter.call(form);
  1387 												}
  1482 												}
  1388 												form.data('submitted', false);
  1483 												form.data('submitted', false);
  1389 												form.removeData('ams-submit-button');
  1484 												form.removeData('ams-submit-button');
  1390 											},
  1485 											},
  1391 											success: function(result, status, request, form) {
  1486 											success: function(result, status, request, form) {
  1392 												var callback;
  1487 												var callback;
  1393 												var button = form.data('ams-submit-button');
  1488 												var button = form.data('ams-submit-button');
  1394 												if (button)
  1489 												if (button) {
  1395 													callback = button.data('ams-form-submit-callback');
  1490 													callback = button.data('ams-form-submit-callback');
  1396 												if (!callback)
  1491 												}
       
  1492 												if (!callback) {
  1397 													callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback;
  1493 													callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback;
       
  1494 												}
  1398 												callback.call(form, result, status, request, form);
  1495 												callback.call(form, result, status, request, form);
  1399 												if (form.is(':visible') && button)
  1496 												if (form.is(':visible') && button) {
  1400 													button.button('reset');
  1497 													button.button('reset');
       
  1498 												}
  1401 												form.data('submitted', false);
  1499 												form.data('submitted', false);
  1402 												form.removeData('ams-submit-button');
  1500 												form.removeData('ams-submit-button');
  1403 												form.removeAttr('data-ams-form-changed');
  1501 												form.removeAttr('data-ams-form-changed');
  1404 											},
  1502 											},
  1405 											iframe: hasUpload
  1503 											iframe: hasUpload
  1412 										var modal = $(form).parents('.modal-dialog');
  1510 										var modal = $(form).parents('.modal-dialog');
  1413 										if (modal.exists()) {
  1511 										if (modal.exists()) {
  1414 											ams.dialog.close(form);
  1512 											ams.dialog.close(form);
  1415 										} else {
  1513 										} else {
  1416 											ams.form.finalizeSubmitFooter.call(form);
  1514 											ams.form.finalizeSubmitFooter.call(form);
  1417 											if (button)
  1515 											if (button) {
  1418 												button.button('reset');
  1516 												button.button('reset');
       
  1517 											}
  1419 											form.data('submitted', false);
  1518 											form.data('submitted', false);
  1420 											form.removeData('ams-submit-button');
  1519 											form.removeData('ams-submit-button');
  1421 											form.removeAttr('data-ams-form-changed');
  1520 											form.removeAttr('data-ams-form-changed');
  1422 										}
  1521 										}
  1423 									}
  1522 									}
  1433 												   ams.baseURL + 'ext/jquery-progressbar' + ams.devext + '.js');
  1532 												   ams.baseURL + 'ext/jquery-progressbar' + ams.devext + '.js');
  1434 									var settings = $.extend({}, {
  1533 									var settings = $.extend({}, {
  1435 										uuid: $.progressBar.submit(form)
  1534 										uuid: $.progressBar.submit(form)
  1436 									});
  1535 									});
  1437 									_submitAjaxForm(form, settings);
  1536 									_submitAjaxForm(form, settings);
  1438 								} else
  1537 								} else {
  1439 									_submitAjaxForm(form, {});
  1538 									_submitAjaxForm(form, {});
       
  1539 								}
  1440 						   });
  1540 						   });
  1441 			return false;
  1541 			return false;
  1442 		},
  1542 		},
  1443 
  1543 
  1444 		/**
  1544 		/**
  1449 		 * @param message: the optional message
  1549 		 * @param message: the optional message
  1450 		 */
  1550 		 */
  1451 		initSubmit: function(target, message) {
  1551 		initSubmit: function(target, message) {
  1452 			var form = $(this);
  1552 			var form = $(this);
  1453 			var spin = '<i class="fa fa-3x fa-gear fa-spin"></i>';
  1553 			var spin = '<i class="fa fa-3x fa-gear fa-spin"></i>';
  1454 			if (!message)
  1554 			if (!message) {
  1455 				message = form.data('ams-form-submit-message');
  1555 				message = form.data('ams-form-submit-message');
  1456 			if (message)
  1556 			}
       
  1557 			if (message) {
  1457 				spin += '<strong>' + message + '</strong>';
  1558 				spin += '<strong>' + message + '</strong>';
       
  1559 			}
  1458 			$(target).html('<div class="row margin-20"><div class="text-center">' + spin + '</div></div>');
  1560 			$(target).html('<div class="row margin-20"><div class="text-center">' + spin + '</div></div>');
  1459 			$(target).parents('.hidden').removeClass('hidden');
  1561 			$(target).parents('.hidden').removeClass('hidden');
  1460 		},
  1562 		},
  1461 
  1563 
  1462 		/**
  1564 		/**
  1477 		 * @param message: the optional submit message
  1579 		 * @param message: the optional submit message
  1478 		 */
  1580 		 */
  1479 		initSubmitFooter: function(message) {
  1581 		initSubmitFooter: function(message) {
  1480 			var form = $(this);
  1582 			var form = $(this);
  1481 			var spin = '<i class="fa fa-3x fa-gear fa-spin"></i>';
  1583 			var spin = '<i class="fa fa-3x fa-gear fa-spin"></i>';
  1482 			if (!message)
  1584 			if (!message) {
  1483 				message = $(this).data('ams-form-submit-message');
  1585 				message = $(this).data('ams-form-submit-message');
  1484 			if (message)
  1586 			}
       
  1587 			if (message) {
  1485 				spin += '<strong class="submit-message align-top padding-left-10 margin-top-10">' + message + '</strong>';
  1588 				spin += '<strong class="submit-message align-top padding-left-10 margin-top-10">' + message + '</strong>';
       
  1589 			}
  1486 			var footer = $('footer', form);
  1590 			var footer = $('footer', form);
  1487 			$('button', footer).hide();
  1591 			$('button', footer).hide();
  1488 			footer.append('<div class="row"><div class="text-center">' + spin + '</div></div>');
  1592 			footer.append('<div class="row"><div class="text-center">' + spin + '</div></div>');
  1489 		},
  1593 		},
  1490 
  1594 
  1520 		 *     - redirect: redirect browser to given URL
  1624 		 *     - redirect: redirect browser to given URL
  1521 		 *   Each JSON response can also specify an HTML content, a message and a callback (
  1625 		 *   Each JSON response can also specify an HTML content, a message and a callback (
  1522 		 */
  1626 		 */
  1523 		_submitCallback: function(result, status, request, form) {
  1627 		_submitCallback: function(result, status, request, form) {
  1524 
  1628 
       
  1629 			var button;
  1525 			if (form.is(':visible')) {
  1630 			if (form.is(':visible')) {
  1526 				ams.form.finalizeSubmitFooter.call(form);
  1631 				ams.form.finalizeSubmitFooter.call(form);
  1527 				var button = form.data('ams-submit-button');
  1632 				button = form.data('ams-submit-button');
  1528 				if (button)
  1633 				if (button) {
  1529 					button.button('reset');
  1634 					button.button('reset');
  1530 			}
  1635 				}
       
  1636 			}
       
  1637 
  1531 			var data = form.data();
  1638 			var data = form.data();
  1532 			if (data.amsFormDatatype)
  1639 			var data_type;
  1533 				var data_type = data.amsFormDatatype;
  1640 			if (data.amsFormDatatype) {
  1534 			else {
  1641 				data_type = data.amsFormDatatype;
       
  1642 			} else {
  1535 				var request_data = ams.ajax.getResponse(request);
  1643 				var request_data = ams.ajax.getResponse(request);
  1536 				data_type = request_data.content_type;
  1644 				data_type = request_data.content_type;
  1537 				result = request_data.data;
  1645 				result = request_data.data;
  1538 			}
  1646 			}
  1539 
  1647 
  1540 			if (button)
  1648 			var target;
  1541 				var target = $(button.amsFormSubmitTarget || data.amsFormSubmitTarget || '#content');
  1649 			if (button) {
  1542 			else
  1650 				target = $(button.amsFormSubmitTarget || data.amsFormSubmitTarget || '#content');
       
  1651 			} else {
  1543 				target = $(data.amsFormSubmitTarget || '#content');
  1652 				target = $(data.amsFormSubmitTarget || '#content');
       
  1653 			}
  1544 
  1654 
  1545 			switch (data_type) {
  1655 			switch (data_type) {
  1546 				case 'json':
  1656 				case 'json':
  1547 					ams.ajax.handleJSON(result, form, target);
  1657 					ams.ajax.handleJSON(result, form, target);
  1548 					break;
  1658 					break;
  1549 				case 'script':
  1659 				case 'script':
  1550 					break;
  1660 					break;
  1551 				case 'xml':
  1661 				case 'xml':
  1552 					break;
  1662 					break;
  1553 				case 'html':
  1663 				case 'html':
       
  1664 					/* falls through */
  1554 				case 'text':
  1665 				case 'text':
       
  1666 					/* falls through */
  1555 				default:
  1667 				default:
  1556 					if (button && (button.data('ams-keep-modal') !== true))
  1668 					if (button && (button.data('ams-keep-modal') !== true)) {
  1557 						ams.dialog.close(form);
  1669 						ams.dialog.close(form);
  1558 					if (!target.exists())
  1670 					}
       
  1671 					if (!target.exists()) {
  1559 						target = $('body');
  1672 						target = $('body');
       
  1673 					}
  1560 					target.parents('.hidden').removeClass('hidden');
  1674 					target.parents('.hidden').removeClass('hidden');
  1561 					$('.alert', target.parents('.alerts-container')).remove();
  1675 					$('.alert', target.parents('.alerts-container')).remove();
  1562 					target.css({opacity: '0.0'})
  1676 					target.css({opacity: '0.0'})
  1563 						  .html(result)
  1677 						  .html(result)
  1564 						  .delay(50)
  1678 						  .delay(50)
  1574 
  1688 
  1575 		/**
  1689 		/**
  1576 		 * Get list of custom validators called before submit
  1690 		 * Get list of custom validators called before submit
  1577 		 */
  1691 		 */
  1578 		_getSubmitValidators: function(form) {
  1692 		_getSubmitValidators: function(form) {
  1579 			var validators = new Array();
  1693 			var validators = [];
  1580 			var form_validator = form.data('ams-form-validator');
  1694 			var form_validator = form.data('ams-form-validator');
  1581 			if (form_validator)
  1695 			if (form_validator) {
  1582 				validators.push([form, form_validator]);
  1696 				validators.push([form, form_validator]);
       
  1697 			}
  1583 			$('[data-ams-form-validator]', form).each(function() {
  1698 			$('[data-ams-form-validator]', form).each(function() {
  1584 				var source = $(this);
  1699 				var source = $(this);
  1585 				validators.push([source, source.data('ams-form-validator')]);
  1700 				validators.push([source, source.data('ams-form-validator')]);
  1586 			});
  1701 			});
  1587 			return validators;
  1702 			return validators;
  1596 		 *  - an array containing a list of string error messages
  1711 		 *  - an array containing a list of string error messages
  1597 		 * Any other value (undefined, null, True...) will lead to a successful submit.
  1712 		 * Any other value (undefined, null, True...) will lead to a successful submit.
  1598 		 */
  1713 		 */
  1599 		_checkSubmitValidators: function(form) {
  1714 		_checkSubmitValidators: function(form) {
  1600 			var validators = ams.form._getSubmitValidators(form);
  1715 			var validators = ams.form._getSubmitValidators(form);
  1601 			if (!validators.length)
  1716 			if (!validators.length) {
  1602 				return true;
  1717 				return true;
  1603 			var output = new Array();
  1718 			}
       
  1719 			var output = [];
  1604 			var result = true;
  1720 			var result = true;
  1605 			for (var index in validators) {
  1721 			for (var index=0; index < validators.length; index++) {
  1606 				if (!$.isNumeric(index))  // IE check !
       
  1607 					continue;
       
  1608 				var validator = validators[index];
  1722 				var validator = validators[index];
  1609 				var source = validator[0];
  1723 				var source = validator[0];
  1610 				var handler = validator[1];
  1724 				var handler = validator[1];
  1611 				var validator_result = ams.executeFunctionByName(handler, form, source);
  1725 				var validator_result = ams.executeFunctionByName(handler, form, source);
  1612 				if (validator_result === false)
  1726 				if (validator_result === false) {
  1613 					result = false;
  1727 					result = false;
  1614 				else if (typeof(validator_result) == 'string')
  1728 				} else if (typeof(validator_result) === 'string') {
  1615 					output.push(validator_result);
  1729 					output.push(validator_result);
  1616 				else if (result.length && (result.length > 0))
  1730 				} else if (result.length && (result.length > 0)) {
  1617 					output = output.concat(result);
  1731 					output = output.concat(result);
       
  1732 				}
  1618 			}
  1733 			}
  1619 			if (output.length > 0) {
  1734 			if (output.length > 0) {
  1620 				var header = output.length == 1 ? ams.i18n.ERROR_OCCURED : ams.i18n.ERRORS_OCCURED;
  1735 				var header = output.length === 1 ? ams.i18n.ERROR_OCCURED : ams.i18n.ERRORS_OCCURED;
  1621 				ams.skin.alert(form, 'danger', header, output);
  1736 				ams.skin.alert(form, 'danger', header, output);
  1622 				return false;
  1737 				return false;
  1623 			} else
  1738 			} else {
  1624 				return result;
  1739 				return result;
       
  1740 			}
  1625 		},
  1741 		},
  1626 
  1742 
  1627 		/**
  1743 		/**
  1628 		 * Display JSON errors
  1744 		 * Display JSON errors
  1629 		 * JSON errors should be defined in an object as is:
  1745 		 * JSON errors should be defined in an object as is:
  1636 		 *            {label: "Second widget name",
  1752 		 *            {label: "Second widget name",
  1637 		 *             name: "field-name-2",
  1753 		 *             name: "field-name-2",
  1638 		 *             message: "Second error message"},...]}
  1754 		 *             message: "Second error message"},...]}
  1639 		 */
  1755 		 */
  1640 		showErrors: function(form, errors) {
  1756 		showErrors: function(form, errors) {
  1641 			if (typeof(errors) == 'string') {
  1757 			var header;
  1642 				ams.skin.alert(form, 'error', ams.i18n.ERROR_OCCURED, errors)
  1758 			if (typeof(errors) === 'string') {
       
  1759 				ams.skin.alert(form, 'error', ams.i18n.ERROR_OCCURED, errors);
  1643 			} else if (errors instanceof Array) {
  1760 			} else if (errors instanceof Array) {
  1644 				var header = errors.length == 1 ? ams.i18n.ERROR_OCCURED : ams.i18n.ERRORS_OCCURED;
  1761 				header = errors.length === 1 ? ams.i18n.ERROR_OCCURED : ams.i18n.ERRORS_OCCURED;
  1645 				ams.skin.alert(form, 'error', header, errors);
  1762 				ams.skin.alert(form, 'error', header, errors);
  1646 			} else {
  1763 			} else {
  1647 				$('.state-error', form).removeClass('state-error');
  1764 				$('.state-error', form).removeClass('state-error');
  1648 				header = errors.error_header ||
  1765 				header = errors.error_header ||
  1649 						 (errors.widgets && (errors.widgets.length > 1) ? ams.i18n.ERRORS_OCCURED : ams.i18n.ERROR_OCCURED);
  1766 						 (errors.widgets && (errors.widgets.length > 1) ? ams.i18n.ERRORS_OCCURED : ams.i18n.ERROR_OCCURED);
  1650 				var message = new Array();
  1767 				var message = [];
  1651 				var index;
  1768 				var index;
  1652 				for (index in errors.messages) {
  1769 				for (index=0; index < errors.messages.length; index++) {
  1653 					if (!$.isNumeric(index))
  1770 					var msg = errors.messages[index];
  1654 						continue;
  1771 					if (msg.header) {
  1655 					if (errors.messages[index].header) {
  1772 						message.push('<strong>' + msg.header + '</strong><br />' + msg.message);
  1656 						message.push('<strong>' + errors.messages[index].header + '</strong><br />' + errors.messages[index].message);
       
  1657 					} else {
  1773 					} else {
  1658 						message.push(errors.messages[index].message || errors.messages[index]);
  1774 						message.push(msg.message || msg);
  1659 					}
  1775 					}
  1660 				}
  1776 				}
  1661 				for (index in errors.widgets) {
  1777 				if (errors.widgets) {
  1662 					if (!$.isNumeric(index))
  1778 					for (index = 0; index < errors.widgets.length; index++) {
  1663 						continue;
  1779 						// set widget status message
  1664 					// set widget status message
  1780 						var widget_data = errors.widgets[index];
  1665 					var widget_data = errors.widgets[index];
  1781 						var widget = $('[name="' + widget_data.name + '"]', form);
  1666 					var widget = $('[name="' + widget_data.name + '"]', form);
  1782 						widget.parents('label:first')
  1667 					widget.parents('label:first')
  1783 								.removeClassPrefix('state-')
  1668 						  .removeClassPrefix('state-')
  1784 								.addClass('state-error')
  1669 						  .addClass('state-error')
  1785 								.after('<span for="name" class="state-error">' + widget_data.message + '</span>');
  1670 						  .after('<span for="name" class="state-error">' + widget_data.message + '</span>');
  1786 						// complete form alert message
  1671 					// complete form alert message
  1787 						if (widget_data.label) {
  1672 					if (widget_data.label) {
  1788 							message.push(widget_data.label + ' : ' + widget_data.message);
  1673 						message.push(widget_data.label + ' : ' + widget_data.message);
  1789 						}
  1674 					}
  1790 						// mark parent tab (if any) with error status
  1675 					// mark parent tab (if any) with error status
  1791 						var tab_index = widget.parents('.tab-pane').index() + 1;
  1676 					var tab_index = widget.parents('.tab-pane').index() + 1;
  1792 						if (tab_index > 0) {
  1677 					if (tab_index > 0) {
  1793 							var nav_tabs = $('.nav-tabs', $(widget).parents('.tabforms'));
  1678 						var nav_tabs = $('.nav-tabs', $(widget).parents('.tabforms'));
  1794 							$('li:nth-child(' + tab_index + ')', nav_tabs).removeClassPrefix('state-')
  1679 						$('li:nth-child(' + tab_index + ')', nav_tabs).removeClassPrefix('state-')
  1795 									.addClass('state-error');
  1680 																	  .addClass('state-error');
  1796 							$('li.state-error:first a', form).click();
  1681 						$('li.state-error:first a', form).click();
  1797 						}
  1682 					}
  1798 					}
  1683 				}
  1799 				}
  1684 				ams.skin.alert(form, errors.error_level || 'error', header, message, errors.error_message);
  1800 				ams.skin.alert(form, errors.error_level || 'error', header, message, errors.error_message);
  1685 			}
  1801 			}
  1686 		}
  1802 		}
  1703 		registerShownCallback: function(callback, element) {
  1819 		registerShownCallback: function(callback, element) {
  1704 			var dialog;
  1820 			var dialog;
  1705 			if (element) {
  1821 			if (element) {
  1706 				dialog = element.objectOrParentWithClass('modal-dialog');
  1822 				dialog = element.objectOrParentWithClass('modal-dialog');
  1707 			}
  1823 			}
       
  1824 
       
  1825 			var callbacks;
  1708 			if (dialog && dialog.exists()) {
  1826 			if (dialog && dialog.exists()) {
  1709 				var callbacks = dialog.data('shown-callbacks');
  1827 				callbacks = dialog.data('shown-callbacks');
  1710 				if (callbacks === undefined) {
  1828 				if (callbacks === undefined) {
  1711 					callbacks = [];
  1829 					callbacks = [];
  1712 					dialog.data('shown-callbacks', callbacks);
  1830 					dialog.data('shown-callbacks', callbacks);
  1713 				}
  1831 				}
  1714 			} else {
  1832 			} else {
  1715 				callbacks = ams.dialog._shown_callbacks;
  1833 				callbacks = ams.dialog._shown_callbacks;
  1716 			}
  1834 			}
  1717 			if (callbacks.indexOf(callback) < 0)
  1835 			if (callbacks.indexOf(callback) < 0) {
  1718 				callbacks.push(callback);
  1836 				callbacks.push(callback);
       
  1837 			}
  1719 		},
  1838 		},
  1720 
  1839 
  1721 		/**
  1840 		/**
  1722 		 * List of registered 'hide' callbacks
  1841 		 * List of registered 'hide' callbacks
  1723 		 */
  1842 		 */
  1729 		registerHideCallback: function(callback, element) {
  1848 		registerHideCallback: function(callback, element) {
  1730 			var dialog;
  1849 			var dialog;
  1731 			if (element) {
  1850 			if (element) {
  1732 				dialog = element.objectOrParentWithClass('modal-dialog');
  1851 				dialog = element.objectOrParentWithClass('modal-dialog');
  1733 			}
  1852 			}
       
  1853 
       
  1854 			var callbacks;
  1734 			if (dialog && dialog.exists()) {
  1855 			if (dialog && dialog.exists()) {
  1735 				var callbacks = dialog.data('hide-callbacks');
  1856 				callbacks = dialog.data('hide-callbacks');
  1736 				if (callbacks === undefined) {
  1857 				if (callbacks === undefined) {
  1737 					callbacks = [];
  1858 					callbacks = [];
  1738 					dialog.data('hide-callbacks', callbacks);
  1859 					dialog.data('hide-callbacks', callbacks);
  1739 				}
  1860 				}
  1740 			} else {
  1861 			} else {
  1741 				callbacks = ams.dialog._hide_callbacks;
  1862 				callbacks = ams.dialog._hide_callbacks;
  1742 			}
  1863 			}
  1743 			if (callbacks.indexOf(callback) < 0)
  1864 			if (callbacks.indexOf(callback) < 0) {
  1744 				callbacks.push(callback);
  1865 				callbacks.push(callback);
       
  1866 			}
  1745 		},
  1867 		},
  1746 
  1868 
  1747 		/**
  1869 		/**
  1748 		 * Modal dialog opener
  1870 		 * Modal dialog opener
  1749 		 */
  1871 		 */
  1761 												'<div class="progress progress-striped active">' +
  1883 												'<div class="progress progress-striped active">' +
  1762 													'<div class="progress-bar" style="width: 100%;"></div>' +
  1884 													'<div class="progress-bar" style="width: 100%;"></div>' +
  1763 												'</div>' +
  1885 												'</div>' +
  1764 											'</div>';
  1886 											'</div>';
  1765 									}
  1887 									}
  1766 									if (typeof(source) == 'string') {
  1888 
  1767 										var source_data = {};
  1889 									var source_data;
  1768 										var url = source;
  1890 									var url;
       
  1891 									if (typeof(source) === 'string') {
       
  1892 										source_data = {};
       
  1893 										url = source;
  1769 									} else {
  1894 									} else {
  1770 										source_data = source.data();
  1895 										source_data = source.data();
  1771 										url = source.attr('href') || source_data.amsUrl;
  1896 										url = source.attr('href') || source_data.amsUrl;
  1772 										var url_getter = ams.getFunctionByName(url);
  1897 										var url_getter = ams.getFunctionByName(url);
  1773 										if (typeof(url_getter) == 'function') {
  1898 										if (typeof(url_getter) === 'function') {
  1774 											url = url_getter.call(source);
  1899 											url = url_getter.call(source);
  1775 										}
  1900 										}
  1776 									}
  1901 									}
  1777 									if (!url)
  1902 									if (!url) {
  1778 										return;
  1903 										return;
       
  1904 									}
  1779 									$('body').modalmanager('loading');
  1905 									$('body').modalmanager('loading');
  1780 									if (url.indexOf('#') == 0) {
  1906 									if (url.indexOf('#') === 0) {
  1781 										// Inner hidden modal dialog
  1907 										// Inner hidden modal dialog
  1782 										$(url).modal('show');
  1908 										$(url).modal('show');
  1783 									} else {
  1909 									} else {
  1784 										// Remote URL modal dialog
  1910 										// Remote URL modal dialog
  1785 										$.ajax({
  1911 										$.ajax({
  1799 													case 'script':
  1925 													case 'script':
  1800 														break;
  1926 														break;
  1801 													case 'xml':
  1927 													case 'xml':
  1802 														break;
  1928 														break;
  1803 													case 'html':
  1929 													case 'html':
       
  1930 														/* falls through */
  1804 													case 'text':
  1931 													case 'text':
       
  1932 														/* falls through */
  1805 													default:
  1933 													default:
  1806 														var content = $(result);
  1934 														var content = $(result);
  1807 														var dialog = $('.modal-dialog', content.wrap('<div></div>').parent());
  1935 														var dialog = $('.modal-dialog', content.wrap('<div></div>').parent());
  1808 														var dialog_data = dialog.data();
  1936 														var dialog_data = dialog.data();
  1809 														var data_options = {
  1937 														var data_options = {
  1810 															overflow: dialog_data.amsModalOverflow || '.modal-viewport',
  1938 															overflow: dialog_data.amsModalOverflow || '.modal-viewport',
  1811 															maxHeight: dialog_data.amsModalMaxHeight === undefined
  1939 															maxHeight: dialog_data.amsModalMaxHeight === undefined ?
  1812 																	? function() {
  1940 																	function() {
  1813 																		return $(window).height() -
  1941 																		return $(window).height() -
  1814 																					$('.modal-header', content).outerHeight(true) -
  1942 																					$('.modal-header', content).outerHeight(true) -
  1815 																					$('footer', content).outerHeight(true) - 85;
  1943 																					$('footer', content).outerHeight(true) - 85;
  1816 																	}
  1944 																	}
  1817 																	: ams.getFunctionByName(dialog_data.amsModalMaxHeight)
  1945 																	: ams.getFunctionByName(dialog_data.amsModalMaxHeight)
  1839 		shown: function(e) {
  1967 		shown: function(e) {
  1840 
  1968 
  1841 			function resetViewport(ev) {
  1969 			function resetViewport(ev) {
  1842 				var top = $('.scrollmarker.top', viewport);
  1970 				var top = $('.scrollmarker.top', viewport);
  1843 				var top_position = viewport.scrollTop();
  1971 				var top_position = viewport.scrollTop();
  1844 				if (top_position > 0)
  1972 				if (top_position > 0) {
  1845 					top.show();
  1973 					top.show();
  1846 				else
  1974 				} else {
  1847 					top.hide();
  1975 					top.hide();
       
  1976 				}
  1848 				var bottom = $('.scrollmarker.bottom', viewport);
  1977 				var bottom = $('.scrollmarker.bottom', viewport);
  1849 				if (maxHeight + top_position >= viewport.get(0).scrollHeight)
  1978 				if (maxHeight + top_position >= viewport.get(0).scrollHeight) {
  1850 					bottom.hide();
  1979 					bottom.hide();
  1851 				else
  1980 				} else {
  1852 					bottom.show();
  1981 					bottom.show();
       
  1982 				}
  1853 			}
  1983 			}
  1854 
  1984 
  1855 			var modal = e.target;
  1985 			var modal = e.target;
  1856 			var viewport = $('.modal-viewport', modal);
  1986 			var viewport = $('.modal-viewport', modal);
  1857 			if (viewport.exists()) {
  1987 			if (viewport.exists()) {
  1858 				var maxHeight = parseInt(viewport.css('max-height'));
  1988 				var maxHeight = parseInt(viewport.css('max-height'));
  1859 				var barWidth = $.scrollbarWidth();
  1989 				var barWidth = $.scrollbarWidth();
  1860 				if (viewport.height() == maxHeight) {
  1990 				if (viewport.height() === maxHeight) {
  1861 					$('<div></div>').addClass('scrollmarker')
  1991 					$('<div></div>').addClass('scrollmarker')
  1862 						.addClass('top')
  1992 						.addClass('top')
  1863 						.css('top', 0)
  1993 						.css('top', 0)
  1864 						.css('width', viewport.width() - barWidth)
  1994 						.css('width', viewport.width() - barWidth)
  1865 						.hide()
  1995 						.hide()
  1876 					$('.scrollmarker', viewport).remove();
  2006 					$('.scrollmarker', viewport).remove();
  1877 				}
  2007 				}
  1878 			}
  2008 			}
  1879 
  2009 
  1880 			// Call shown callbacks registered for this dialog
  2010 			// Call shown callbacks registered for this dialog
       
  2011 			var index;
  1881 			var callbacks = $('.modal-dialog', modal).data('shown-callbacks');
  2012 			var callbacks = $('.modal-dialog', modal).data('shown-callbacks');
  1882 			if (callbacks) {
  2013 			if (callbacks) {
  1883 				for (var index in callbacks) {
  2014 				for (index=0; index < callbacks.length; index++) {
  1884 					callbacks[index].call(modal);
  2015 					callbacks[index].call(modal);
  1885 				}
  2016 				}
  1886 			}
  2017 			}
  1887 			// Call globally registered shown callbacks
  2018 			// Call globally registered shown callbacks
  1888 			callbacks = ams.dialog._shown_callbacks;
  2019 			callbacks = ams.dialog._shown_callbacks;
  1889 			for (index in callbacks) {
  2020 			if (callbacks) {
  1890 				callbacks[index].call(modal);
  2021 				for (index=0; index < callbacks.length; index++) {
       
  2022 					callbacks[index].call(modal);
       
  2023 				}
       
  2024 			}
       
  2025 
       
  2026 			// Set focus to first input
       
  2027 			var focused = $('[data-ams-focus-target]', modal).first();
       
  2028 			if (!focused.exists()) {
       
  2029 				focused = $('input, select', modal).first();
       
  2030 			}
       
  2031 			if (focused.exists()) {
       
  2032 				focused.focus();
  1891 			}
  2033 			}
  1892 		},
  2034 		},
  1893 
  2035 
  1894 		/**
  2036 		/**
  1895 		 * Close modal dialog associated with given context
  2037 		 * Close modal dialog associated with given context
  1896 		 */
  2038 		 */
  1897 		close: function(context) {
  2039 		close: function(context) {
  1898 			var modal = context.parents('.modal').data('modal');
  2040 			var modal = context.parents('.modal').data('modal');
  1899 			if (modal) {
  2041 			if (modal) {
  1900 				var manager = $('body').data('modalmanager');
  2042 				var manager = $('body').data('modalmanager');
  1901 				if (manager && (manager.getOpenModals().indexOf(modal) >= 0))
  2043 				if (manager && (manager.getOpenModals().indexOf(modal) >= 0)) {
  1902 					modal.hide();
  2044 					modal.hide();
       
  2045 				}
  1903 			}
  2046 			}
  1904 		},
  2047 		},
  1905 
  2048 
  1906 		/**
  2049 		/**
  1907 		 * Modals hidden callback
  2050 		 * Modals hidden callback
  1910 		hidden: function(e) {
  2053 		hidden: function(e) {
  1911 			var modal = e.target;
  2054 			var modal = e.target;
  1912 			// Call registered cleaning callbacks
  2055 			// Call registered cleaning callbacks
  1913 			ams.skin.cleanContainer(modal);
  2056 			ams.skin.cleanContainer(modal);
  1914 			// Call hide callbacks registered for this dialog
  2057 			// Call hide callbacks registered for this dialog
       
  2058 			var index;
  1915 			var callbacks = $('.modal-dialog', modal).data('hide-callbacks');
  2059 			var callbacks = $('.modal-dialog', modal).data('hide-callbacks');
  1916 			if (callbacks) {
  2060 			if (callbacks) {
  1917 				for (var index in callbacks) {
  2061 				for (index=0; index < callbacks.length; index++) {
  1918 					callbacks[index].call(modal);
  2062 					callbacks[index].call(modal);
  1919 				}
  2063 				}
  1920 			}
  2064 			}
  1921 			// Call globally registered hide callbacks
  2065 			// Call globally registered hide callbacks
  1922 			callbacks = ams.dialog._hide_callbacks;
  2066 			callbacks = ams.dialog._hide_callbacks;
  1923 			for (index in callbacks) {
  2067 			if (callbacks) {
  1924 				callbacks[index].call(modal);
  2068 				for (index=0; index < callbacks.length; index++) {
       
  2069 					callbacks[index].call(modal);
       
  2070 				}
  1925 			}
  2071 			}
  1926 		}
  2072 		}
  1927 	};
  2073 	};
  1928 
  2074 
  1929 
  2075 
  1946 
  2092 
  1947 		/** Select2 selection formatter */
  2093 		/** Select2 selection formatter */
  1948 		select2FormatSelection: function(object, container) {
  2094 		select2FormatSelection: function(object, container) {
  1949 			if (object instanceof Array) {
  2095 			if (object instanceof Array) {
  1950 				$(object).each(function() {
  2096 				$(object).each(function() {
  1951 					if (typeof(this) == 'object')
  2097 					if (typeof(this) === 'object') {
  1952 						container.append(this.text);
  2098 						container.append(this.text);
  1953 					else
  2099 					} else {
  1954 						container.append(this);
  2100 						container.append(this);
       
  2101 					}
  1955 				});
  2102 				});
  1956 			} else {
  2103 			} else {
  1957 				if (typeof(object) == 'object')
  2104 				if (typeof(object) === 'object') {
  1958 					container.append(object.text);
  2105 					container.append(object.text);
  1959 				else
  2106 				} else {
  1960 					container.append(object);
  2107 					container.append(object);
       
  2108 				}
  1961 			}
  2109 			}
  1962 		},
  2110 		},
  1963 
  2111 
  1964 		/** Select2 query results callback */
  2112 		/** Select2 query results callback */
  1965 		select2QueryUrlResultsCallback: function(data, page, context) {
  2113 		select2QueryUrlResultsCallback: function(data, page, context) {
  1972 						timeout: 10000
  2120 						timeout: 10000
  1973 					});
  2121 					});
  1974 					break;
  2122 					break;
  1975 				case 'modal':
  2123 				case 'modal':
  1976 					$(this).data('select2').dropdown.hide();
  2124 					$(this).data('select2').dropdown.hide();
  1977 					ams.dialog.open(result.location);
  2125 					ams.dialog.open(data.location);
  1978 					break;
  2126 					break;
  1979 				default:
  2127 				default:
  1980 					return {
  2128 					return {
  1981 						results: data.results || data,
  2129 						results: data.results || data,
  1982 						more: data.has_more || false,
  2130 						more: data.has_more || false,
  1986 		},
  2134 		},
  1987 
  2135 
  1988 		/** Select2 JSON-RPC success callback */
  2136 		/** Select2 JSON-RPC success callback */
  1989 		select2QueryMethodSuccessCallback: function(data, status, options) {
  2137 		select2QueryMethodSuccessCallback: function(data, status, options) {
  1990 			var result = data.result;
  2138 			var result = data.result;
  1991 			if (typeof(result) == 'string') {
  2139 			if (typeof(result) === 'string') {
  1992 				try {
  2140 				try {
  1993 					result = JSON.parse(result);
  2141 					result = JSON.parse(result);
  1994 				} catch (e) {}
  2142 				} catch (e) {}
  1995 			}
  2143 			}
  1996 			switch (result.status) {
  2144 			switch (result.status) {
  2016 		},
  2164 		},
  2017 
  2165 
  2018 		/** Context menu handler */
  2166 		/** Context menu handler */
  2019 		contextMenuHandler: function(target, menu) {
  2167 		contextMenuHandler: function(target, menu) {
  2020 			var menu_data = menu.data();
  2168 			var menu_data = menu.data();
  2021 			if (menu_data.toggle == 'modal') {
  2169 			if (menu_data.toggle === 'modal') {
  2022 				ams.dialog.open(menu);
  2170 				ams.dialog.open(menu);
  2023 			} else {
  2171 			} else {
  2024 				var href = menu.attr('href') || menu_data.amsUrl;
  2172 				var href = menu.attr('href') || menu_data.amsUrl;
  2025 				if (!href || href.startsWith('javascript:') || menu.attr('target'))
  2173 				if (!href || href.startsWith('javascript') || menu.attr('target')) {
  2026 					return;
  2174 					return;
       
  2175 				}
  2027 				ams.event.stop();
  2176 				ams.event.stop();
  2028 				var href_getter = ams.getFunctionByName(href);
  2177 				var href_getter = ams.getFunctionByName(href);
  2029 				if (typeof(href_getter) == 'function') {
  2178 				if (typeof(href_getter) === 'function') {
  2030 					href = href_getter.call(menu, target);
  2179 					href = href_getter.call(menu, target);
  2031 				}
  2180 				}
  2032 				if (typeof(href) == 'function') {
  2181 				if (typeof(href) === 'function') {
  2033 					// Javascript function call
  2182 					// Javascript function call
  2034 					href.call(menu, target);
  2183 					href.call(menu, target);
  2035 				} else {
  2184 				} else {
  2036 					// Standard AJAX or browser URL call
  2185 					// Standard AJAX or browser URL call
  2037 					// Convert %23 chars to #
  2186 					// Convert %23 chars to #
  2038 					href = href.replace(/\%23/, '#');
  2187 					href = href.replace(/\%23/, '#');
  2039 					var target = menu.data('ams-target');
  2188 					target = menu.data('ams-target');
  2040 					if (target) {
  2189 					if (target) {
  2041 						ams.form.confirmChangedForm(target, function () {
  2190 						ams.form.confirmChangedForm(target, function () {
  2042 							ams.skin.loadURL(href, target, menu.data('ams-link-options'), menu.data('ams-link-callback'));
  2191 							ams.skin.loadURL(href, target, menu.data('ams-link-options'), menu.data('ams-link-callback'));
  2043 						});
  2192 						});
  2044 					} else {
  2193 					} else {
  2045 						ams.form.confirmChangedForm(function () {
  2194 						ams.form.confirmChangedForm(function () {
  2046 							if (href.startsWith('#')) {
  2195 							if (href.startsWith('#')) {
  2047 								if (href != location.hash) {
  2196 								if (href !== location.hash) {
  2048 									if (ams.root.hasClass('mobile-view-activated')) {
  2197 									if (ams.root.hasClass('mobile-view-activated')) {
  2049 										ams.root.removeClass('hidden-menu');
  2198 										ams.root.removeClass('hidden-menu');
  2050 										window.setTimeout(function () {
  2199 										window.setTimeout(function () {
  2051 											window.location.hash = href;
  2200 											window.location.hash = href;
  2052 										}, 150);
  2201 										}, 150);
  2053 									} else
  2202 									} else {
  2054 										window.location.hash = href;
  2203 										window.location.hash = href;
       
  2204 									}
  2055 								}
  2205 								}
  2056 							} else
  2206 							} else {
  2057 								window.location = href;
  2207 								window.location = href;
       
  2208 							}
  2058 						});
  2209 						});
  2059 					}
  2210 					}
  2060 				}
  2211 				}
  2061 			}
  2212 			}
  2062 		},
  2213 		},
  2090 
  2241 
  2091 			// Initialize custom data attributes
  2242 			// Initialize custom data attributes
  2092 			ams.plugins.initData(element);
  2243 			ams.plugins.initData(element);
  2093 
  2244 
  2094 			// Check for disabled plug-ins
  2245 			// Check for disabled plug-ins
  2095 			var disabled = new Array();
  2246 			var disabled = [];
  2096 			$('[data-ams-plugins-disabled]', element).each(function() {
  2247 			$('[data-ams-plugins-disabled]', element).each(function() {
  2097 				var plugins = $(this).data('ams-plugins-disabled').split(/\s+/);
  2248 				var plugins = $(this).data('ams-plugins-disabled').split(/\s+/);
  2098 				for (var name in plugins) {
  2249 				for (var index=0; index < plugins.length; index++) {
  2099 					disabled.push(plugins[name]);
  2250 					disabled.push(plugins[index]);
  2100 				}
  2251 				}
  2101 			});
  2252 			});
  2102 
  2253 
  2103 			// Load and register new plug-ins
  2254 			// Load and register new plug-ins
  2104 			var name;
  2255 			var plugin;
  2105 			$('[data-ams-plugins]', element).each(function() {
  2256 			$('[data-ams-plugins]', element).each(function() {
  2106 				var source = $(this);
  2257 				var source = $(this);
  2107 				var plugins = {}
  2258 				var plugins = {};
       
  2259 				var name;
  2108 				if (typeof(source.data('ams-plugins')) === 'string') {
  2260 				if (typeof(source.data('ams-plugins')) === 'string') {
  2109 					var names = source.data('ams-plugins').split(/\s+/);
  2261 					var names = source.data('ams-plugins').split(/\s+/);
  2110 					for (var index in names) {
  2262 					for (var index=0; index < names.length; index++) {
  2111 						name = names[index];
  2263 						name = names[index];
  2112 						var plugin_options = {
  2264 						plugins[name] = {
  2113 							src: source.data('ams-plugin-' + name + '-src'),
  2265 							src: source.data('ams-plugin-' + name + '-src'),
  2114 							css: source.data('ams-plugin-' + name + '-css'),
  2266 							css: source.data('ams-plugin-' + name + '-css'),
  2115 							callback: source.data('ams-plugin-' + name + '-callback'),
  2267 							callback: source.data('ams-plugin-' + name + '-callback'),
  2116 							register: source.data('ams-plugin-' + name + '-register'),
  2268 							register: source.data('ams-plugin-' + name + '-register'),
  2117 							async: source.data('ams-plugin-' + name + '-async')
  2269 							async: source.data('ams-plugin-' + name + '-async')
  2118 						}
  2270 						};
  2119 						plugins[name] = plugin_options;
       
  2120 					}
  2271 					}
  2121 				} else {
  2272 				} else {
  2122 					plugins = source.data('ams-plugins');
  2273 					plugins = source.data('ams-plugins');
  2123 				}
  2274 				}
       
  2275 
       
  2276 				function executePlugin() {
       
  2277 					var callback = plugin.callback;
       
  2278 					if (callback) {
       
  2279 						var called = ams.getFunctionByName(callback);
       
  2280 						if (plugin.register !== false) {
       
  2281 							ams.plugins.enabled[name] = called;
       
  2282 						}
       
  2283 					} else {
       
  2284 						if (plugin.register !== false) {
       
  2285 							ams.plugins.enabled[name] = null;
       
  2286 						}
       
  2287 					}
       
  2288 					var css = plugin.css;
       
  2289 					if (css) {
       
  2290 						ams.getCSS(css, name + '_css');
       
  2291 					}
       
  2292 				}
       
  2293 
  2124 				for (name in plugins) {
  2294 				for (name in plugins) {
  2125 					if (ams.plugins.enabled[name] === undefined) {
  2295 					if (ams.plugins.enabled[name] === undefined) {
  2126 						var plugin = plugins[name];
  2296 						plugin = plugins[name];
  2127 						ams.getScript(plugin.src, function() {
  2297 						ams.getScript(plugin.src, executePlugin, {
  2128 							var callback = plugin.callback;
       
  2129 							if (callback) {
       
  2130 								var called = ams.getFunctionByName(callback);
       
  2131 								if (plugin.register !== false)
       
  2132 									ams.plugins.enabled[name] = called;
       
  2133 							} else {
       
  2134 								if (plugin.register !== false)
       
  2135 									ams.plugins.enabled[name] = null;
       
  2136 							}
       
  2137 							var css = plugin['css'];
       
  2138 							if (css) {
       
  2139 								ams.getCSS(css, name + '_css');
       
  2140 							}
       
  2141 						}, {
       
  2142 							async: plugin.async === undefined ? true : plugin.async
  2298 							async: plugin.async === undefined ? true : plugin.async
  2143 						});
  2299 						});
  2144 					}
  2300 					}
  2145 				}
  2301 				}
  2146 			});
  2302 			});
  2147 
  2303 
  2148 			// Run all enabled plug-ins
  2304 			// Run all enabled plug-ins
  2149 			for (var index in ams.plugins.enabled) {
  2305 			for (var index in ams.plugins.enabled) {
  2150 				if (disabled.indexOf(index) >= 0)
  2306 				if (!ams.plugins.enabled.hasOwnProperty(index)) {
  2151 					continue;
  2307 					continue;
  2152 				var plugin = ams.plugins.enabled[index];
  2308 				}
  2153 				if (typeof(plugin) == 'function')
  2309 				if (disabled.indexOf(index) >= 0) {
       
  2310 					continue;
       
  2311 				}
       
  2312 				plugin = ams.plugins.enabled[index];
       
  2313 				if (typeof(plugin) === 'function') {
  2154 					plugin(element);
  2314 					plugin(element);
       
  2315 				}
  2155 			}
  2316 			}
  2156 		},
  2317 		},
  2157 
  2318 
  2158 		/**
  2319 		/**
  2159 		 * Data initializer
  2320 		 * Data initializer
  2163 		 */
  2324 		 */
  2164 		initData: function(element) {
  2325 		initData: function(element) {
  2165 			$('[data-ams-data]', element).each(function() {
  2326 			$('[data-ams-data]', element).each(function() {
  2166 				var handler = $(this);
  2327 				var handler = $(this);
  2167 				var data = handler.data('ams-data');
  2328 				var data = handler.data('ams-data');
  2168 				for (var index in data) {
  2329 				if (data) {
  2169 					handler.attr('data-' + index, data[index]);
  2330 					for (var index=0; index < data.length; index++) {
       
  2331 						handler.attr('data-' + index, data[index]);
       
  2332 					}
  2170 				}
  2333 				}
  2171 			});
  2334 			});
  2172 		},
  2335 		},
  2173 
  2336 
  2174 		/**
  2337 		/**
  2177 		 * @plugin: plugin function caller or object containing plug-in properties
  2340 		 * @plugin: plugin function caller or object containing plug-in properties
  2178 		 * @name: if @plugin is a function, defines plug-in name
  2341 		 * @name: if @plugin is a function, defines plug-in name
  2179 		 * @callback: a callback function which can be called after plug-in registry
  2342 		 * @callback: a callback function which can be called after plug-in registry
  2180 		 */
  2343 		 */
  2181 		register: function(plugin, name, callback) {
  2344 		register: function(plugin, name, callback) {
  2182 			if (typeof(name) == 'function') {
  2345 			if (typeof(name) === 'function') {
  2183 				callback = name;
  2346 				callback = name;
  2184 				name = null;
  2347 				name = null;
  2185 			}
  2348 			}
  2186 			name = name || plugin.name;
  2349 			name = name || plugin.name;
  2187 			if (ams.plugins.enabled.indexOf(name) >= 0) {
  2350 			if (ams.plugins.enabled.indexOf(name) >= 0) {
  2188 				if (window.console)
  2351 				if (globals.console) {
  2189 					console.warn("Plugin "+name+" is already registered!");
  2352 					globals.console.warn("Plugin " + name + " is already registered!");
       
  2353 				}
  2190 				return;
  2354 				return;
  2191 			}
  2355 			}
  2192 			if (typeof(plugin) == 'object') {
  2356 			if (typeof(plugin) === 'object') {
  2193 				var src = plugin.src;
  2357 				var src = plugin.src;
  2194 				if (src) {
  2358 				if (src) {
  2195 					ams.ajax.check(plugin.callback, src, function(first_load) {
  2359 					ams.ajax.check(plugin.callback, src, function(first_load) {
  2196 						if (first_load) {
  2360 						if (first_load) {
  2197 							ams.plugins.enabled[name] = ams.getFunctionByName(plugin.callback);
  2361 							ams.plugins.enabled[name] = ams.getFunctionByName(plugin.callback);
  2200 							}
  2364 							}
  2201 							if (callback) {
  2365 							if (callback) {
  2202 								ams.executeFunctionByName(callback);
  2366 								ams.executeFunctionByName(callback);
  2203 							}
  2367 							}
  2204 						}
  2368 						}
  2205 					})
  2369 					});
  2206 				} else {
  2370 				} else {
  2207 					ams.plugins.enabled[name] = ams.getFunctionByName(plugin.callback);
  2371 					ams.plugins.enabled[name] = ams.getFunctionByName(plugin.callback);
  2208 					if (plugin.css) {
  2372 					if (plugin.css) {
  2209 						ams.getCSS(plugin.css, name + '_css');
  2373 						ams.getCSS(plugin.css, name + '_css');
  2210 					}
  2374 					}
  2211 					if (callback) {
  2375 					if (callback) {
  2212 						ams.executeFunctionByName(callback);
  2376 						ams.executeFunctionByName(callback);
  2213 					}
  2377 					}
  2214 				}
  2378 				}
  2215 			} else if (typeof(plugin) == 'function') {
  2379 			} else if (typeof(plugin) === 'function') {
  2216 				ams.plugins.enabled[name] = plugin;
  2380 				ams.plugins.enabled[name] = plugin;
  2217 				if (callback) {
  2381 				if (callback) {
  2218 					ams.executeFunctionByName(callback);
  2382 					ams.executeFunctionByName(callback);
  2219 				}
  2383 				}
  2220 			}
  2384 			}
  2238 			/**
  2402 			/**
  2239 			 * Label hints
  2403 			 * Label hints
  2240 			 */
  2404 			 */
  2241 			hint: function(element) {
  2405 			hint: function(element) {
  2242 				var hints = $('.hint:not(:parents(.nohints))', element);
  2406 				var hints = $('.hint:not(:parents(.nohints))', element);
  2243 				if (hints.length > 0)
  2407 				if (hints.length > 0) {
  2244 					ams.ajax.check($.fn.tipsy,
  2408 					ams.ajax.check($.fn.tipsy,
  2245 								   ams.baseURL + 'ext/jquery-tipsy' + ams.devext + '.js',
  2409 								   ams.baseURL + 'ext/jquery-tipsy' + ams.devext + '.js',
  2246 								   function() {
  2410 								   function () {
  2247 										ams.getCSS(ams.baseURL + '../css/ext/jquery-tipsy' + ams.devext + '.css',
  2411 									   ams.getCSS(ams.baseURL + '../css/ext/jquery-tipsy' + ams.devext + '.css',
  2248 												  'jquery-tipsy');
  2412 												  'jquery-tipsy');
  2249 										hints.each(function() {
  2413 									   hints.each(function () {
  2250 											var hint = $(this);
  2414 										   var hint = $(this);
  2251 											var data = hint.data();
  2415 										   var data = hint.data();
  2252 											var data_options = {
  2416 										   var data_options = {
  2253 												html: data.amsHintHtml,
  2417 											   html: data.amsHintHtml,
  2254 												title: ams.getFunctionByName(data.amsHintTitleGetter) || function() {
  2418 											   title: ams.getFunctionByName(data.amsHintTitleGetter) || function () {
  2255 													var hint = $(this);
  2419 												   var hint = $(this);
  2256 													return hint.attr('original-title') ||
  2420 												   return hint.attr('original-title') ||
  2257 														   hint.attr(data.amsHintTitleAttr || 'title') ||
  2421 														   hint.attr(data.amsHintTitleAttr || 'title') ||
  2258 														   (data.amsHintHtml ? hint.html() : hint.text());
  2422 														   (data.amsHintHtml ? hint.html() : hint.text());
  2259 												},
  2423 											   },
  2260 												opacity: data.amsHintOpacity || 0.95,
  2424 											   opacity: data.amsHintOpacity || 0.95,
  2261 												gravity: data.amsHintGravity || 'sw',
  2425 											   gravity: data.amsHintGravity || 'sw',
  2262 												offset: data.amsHintOffset || 0
  2426 											   offset: data.amsHintOffset || 0
  2263 											};
  2427 										   };
  2264 											var settings = $.extend({}, data_options, data.amsHintOptions);
  2428 										   var settings = $.extend({}, data_options, data.amsHintOptions);
  2265 											settings = ams.executeFunctionByName(data.amsHintInitCallback, hint, settings) || settings;
  2429 										   settings = ams.executeFunctionByName(data.amsHintInitCallback, hint, settings) || settings;
  2266 											var plugin = hint.tipsy(settings);
  2430 										   var plugin = hint.tipsy(settings);
  2267 											ams.executeFunctionByName(data.amsHintAfterInitCallback, hint, plugin, settings);
  2431 										   ams.executeFunctionByName(data.amsHintAfterInitCallback, hint, plugin, settings);
  2268 										});
  2432 									   });
  2269 								   });
  2433 								   });
       
  2434 				}
  2270 			},
  2435 			},
  2271 
  2436 
  2272 			/**
  2437 			/**
  2273 			 * Context menu plug-in
  2438 			 * Context menu plug-in
  2274 			 */
  2439 			 */
  2299 					var fieldset = legend.parent('fieldset');
  2464 					var fieldset = legend.parent('fieldset');
  2300 					var data = legend.data();
  2465 					var data = legend.data();
  2301 					if (!data.amsSwitcher) {
  2466 					if (!data.amsSwitcher) {
  2302 						$('<i class="fa fa-fw"></i>')
  2467 						$('<i class="fa fa-fw"></i>')
  2303 							.prependTo($(this))
  2468 							.prependTo($(this))
  2304 							.addClass(data.amsSwitcherState == 'open' ?
  2469 							.addClass(data.amsSwitcherState === 'open' ?
  2305 									  (data.amsSwitcherMinusClass || 'fa-minus') :
  2470 									  (data.amsSwitcherMinusClass || 'fa-minus') :
  2306 									  (data.amsSwitcherPlusClass || 'fa-plus'));
  2471 									  (data.amsSwitcherPlusClass || 'fa-plus'));
  2307 						legend.on('click', function(e) {
  2472 						legend.on('click', function(e) {
  2308 							e.preventDefault();
  2473 							e.preventDefault();
  2309 							var veto = {};
  2474 							var veto = {};
  2310 							legend.trigger('ams.switcher.before-switch', [legend, veto]);
  2475 							legend.trigger('ams.switcher.before-switch', [legend, veto]);
  2311 							if (veto.veto)
  2476 							if (veto.veto) {
  2312 								return;
  2477 								return;
       
  2478 							}
  2313 							if (fieldset.hasClass('switched')) {
  2479 							if (fieldset.hasClass('switched')) {
  2314 								fieldset.removeClass('switched');
  2480 								fieldset.removeClass('switched');
  2315 								$('.fa', legend).removeClass(data.amsSwitcherPlusClass || 'fa-plus')
  2481 								$('.fa', legend).removeClass(data.amsSwitcherPlusClass || 'fa-plus')
  2316 												.addClass(data.amsSwitcherMinusClass || 'fa-minus');
  2482 												.addClass(data.amsSwitcherMinusClass || 'fa-minus');
  2317 								legend.trigger('ams.switcher.opened', [legend]);
  2483 								legend.trigger('ams.switcher.opened', [legend]);
  2318 								var id = legend.attr('id');
  2484 								var id = legend.attr('id');
  2319 								if (id) {
  2485 								if (id) {
  2320 									$('legend.switcher[data-ams-switcher-sync="'+id+'"]', fieldset).each(function() {
  2486 									$('legend.switcher[data-ams-switcher-sync="'+id+'"]', fieldset).each(function() {
  2321 										var switcher = $(this);
  2487 										var switcher = $(this);
  2322 										if (switcher.parents('fieldset').hasClass('switched'))
  2488 										if (switcher.parents('fieldset').hasClass('switched')) {
  2323 											switcher.click();
  2489 											switcher.click();
       
  2490 										}
  2324 									});
  2491 									});
  2325 								}
  2492 								}
  2326 							} else {
  2493 							} else {
  2327 								fieldset.addClass('switched');
  2494 								fieldset.addClass('switched');
  2328 								$('.fa', legend).removeClass(data.amsSwitcherMinusClass || 'fa-minus')
  2495 								$('.fa', legend).removeClass(data.amsSwitcherMinusClass || 'fa-minus')
  2329 												.addClass(data.amsSwitcherPlusClass || 'fa-plus');
  2496 												.addClass(data.amsSwitcherPlusClass || 'fa-plus');
  2330 								legend.trigger('ams.switcher.closed', [legend]);
  2497 								legend.trigger('ams.switcher.closed', [legend]);
  2331 							}
  2498 							}
  2332 						});
  2499 						});
  2333 						if (data.amsSwitcherState != 'open')
  2500 						if (data.amsSwitcherState !== 'open') {
  2334 							fieldset.addClass('switched');
  2501 							fieldset.addClass('switched');
       
  2502 						}
  2335 						legend.data('ams-switcher', 'on');
  2503 						legend.data('ams-switcher', 'on');
  2336 					}
  2504 					}
  2337 				});
  2505 				});
  2338 			},
  2506 			},
  2339 
  2507 
  2354 						var checkedValue = data.amsCheckerHiddenValueOn || 'true';
  2522 						var checkedValue = data.amsCheckerHiddenValueOn || 'true';
  2355 						var uncheckedValue = data.amsCheckerHiddenValueOff || 'false';
  2523 						var uncheckedValue = data.amsCheckerHiddenValueOff || 'false';
  2356 						var marker = data.amsCheckerMarker || false;
  2524 						var marker = data.amsCheckerMarker || false;
  2357 						if (prefix) {
  2525 						if (prefix) {
  2358 							hidden = $('<input type="hidden">').attr('name', prefix + fieldname)
  2526 							hidden = $('<input type="hidden">').attr('name', prefix + fieldname)
  2359 															   .val(data.amsCheckerState == 'on' ? checkedValue : uncheckedValue)
  2527 															   .val(data.amsCheckerState === 'on' ? checkedValue : uncheckedValue)
  2360 															   .prependTo(legend);
  2528 															   .prependTo(legend);
  2361 						} else if (marker) {
  2529 						} else if (marker) {
  2362 							$('<input type="hidden">').attr('name', marker)
  2530 							$('<input type="hidden">').attr('name', marker)
  2363 													  .attr('value', 1)
  2531 													  .attr('value', 1)
  2364 													  .prependTo(legend);
  2532 													  .prependTo(legend);
  2366 						var input = $('<input type="checkbox">').attr('name', fieldname)
  2534 						var input = $('<input type="checkbox">').attr('name', fieldname)
  2367 																.attr('id', checkbox_id)
  2535 																.attr('id', checkbox_id)
  2368 																.data('ams-checker-hidden-input', hidden)
  2536 																.data('ams-checker-hidden-input', hidden)
  2369 																.data('ams-checker-init', true)
  2537 																.data('ams-checker-init', true)
  2370 																.val(data.amsCheckerValue || true)
  2538 																.val(data.amsCheckerValue || true)
  2371 																.attr('checked', data.amsCheckerState == 'on' ? 'checked' : null);
  2539 																.attr('checked', data.amsCheckerState === 'on' ? 'checked' : null);
  2372 						if (data.amsCheckerReadonly) {
  2540 						if (data.amsCheckerReadonly) {
  2373 							input.attr('disabled', 'disabled');
  2541 							input.attr('disabled', 'disabled');
  2374 						} else {
  2542 						} else {
  2375 							input.on('change', function(e) {
  2543 							input.on('change', function(e) {
  2376 								e.preventDefault();
  2544 								e.preventDefault();
  2384 								}
  2552 								}
  2385 								ams.executeFunctionByName(data.amsCheckerChangeHandler, legend, isChecked);
  2553 								ams.executeFunctionByName(data.amsCheckerChangeHandler, legend, isChecked);
  2386 								if (!data.amsCheckerCancelDefault) {
  2554 								if (!data.amsCheckerCancelDefault) {
  2387 									var hidden = input.data('ams-checker-hidden-input');
  2555 									var hidden = input.data('ams-checker-hidden-input');
  2388 									if (isChecked) {
  2556 									if (isChecked) {
  2389 										if (data.amsCheckerMode == 'disable')
  2557 										if (data.amsCheckerMode === 'disable') {
  2390 											fieldset.removeAttr('disabled');
  2558 											fieldset.removeAttr('disabled');
  2391 										else
  2559 										} else {
  2392 											fieldset.removeClass('switched');
  2560 											fieldset.removeClass('switched');
  2393 										if (hidden)
  2561 										}
       
  2562 										if (hidden) {
  2394 											hidden.val(checkedValue);
  2563 											hidden.val(checkedValue);
       
  2564 										}
  2395 										$('[data-required]', fieldset).attr('required', 'required');
  2565 										$('[data-required]', fieldset).attr('required', 'required');
  2396 										legend.trigger('ams.checker.opened', [legend]);
  2566 										legend.trigger('ams.checker.opened', [legend]);
  2397 									} else {
  2567 									} else {
  2398 										if (data.amsCheckerMode == 'disable')
  2568 										if (data.amsCheckerMode === 'disable') {
  2399 											fieldset.prop('disabled', 'disabled');
  2569 											fieldset.prop('disabled', 'disabled');
  2400 										else
  2570 										} else {
  2401 											fieldset.addClass('switched');
  2571 											fieldset.addClass('switched');
  2402 										if (hidden)
  2572 										}
       
  2573 										if (hidden) {
  2403 											hidden.val(uncheckedValue);
  2574 											hidden.val(uncheckedValue);
       
  2575 										}
  2404 										$('[data-required]', fieldset).removeAttr('required');
  2576 										$('[data-required]', fieldset).removeAttr('required');
  2405 										legend.trigger('ams.checker.closed', [legend]);
  2577 										legend.trigger('ams.checker.closed', [legend]);
  2406 									}
  2578 									}
  2407 								}
  2579 								}
  2408 							});
  2580 							});
  2411 						$('>label', legend).attr('for', input.attr('id'));
  2583 						$('>label', legend).attr('for', input.attr('id'));
  2412 						checker.append('<i></i>')
  2584 						checker.append('<i></i>')
  2413 							   .prependTo(legend);
  2585 							   .prependTo(legend);
  2414 						var required = $('[required]', fieldset);
  2586 						var required = $('[required]', fieldset);
  2415 						required.attr('data-required', true);
  2587 						required.attr('data-required', true);
  2416 						if (data.amsCheckerState == 'on') {
  2588 						if (data.amsCheckerState === 'on') {
  2417 							input.attr('checked', true);
  2589 							input.attr('checked', true);
  2418 						} else {
  2590 						} else {
  2419 							if (data.amsCheckerMode == 'disable')
  2591 							if (data.amsCheckerMode === 'disable') {
  2420 								fieldset.attr('disabled', 'disabled');
  2592 								fieldset.attr('disabled', 'disabled');
  2421 							else
  2593 							} else {
  2422 								fieldset.addClass('switched');
  2594 								fieldset.addClass('switched');
       
  2595 							}
  2423 							required.removeAttr('required');
  2596 							required.removeAttr('required');
  2424 						}
  2597 						}
  2425 						legend.data('ams-checker', 'on');
  2598 						legend.data('ams-checker', 'on');
  2426 					}
  2599 					}
  2427 				});
  2600 				});
  2568 												maximumSelectionSize: data.amsSelect2MaximumSelectionSize,
  2741 												maximumSelectionSize: data.amsSelect2MaximumSelectionSize,
  2569 												openOnEnter: data.amsSelect2EnterOpen === undefined ? true : data.amsSelect2EnterOpen,
  2742 												openOnEnter: data.amsSelect2EnterOpen === undefined ? true : data.amsSelect2EnterOpen,
  2570 												allowClear: data.amsSelect2AllowClear === undefined ? true : data.amsSelect2AllowClear,
  2743 												allowClear: data.amsSelect2AllowClear === undefined ? true : data.amsSelect2AllowClear,
  2571 												width: data.amsSelect2Width || '100%',
  2744 												width: data.amsSelect2Width || '100%',
  2572 												initSelection: ams.getFunctionByName(data.amsSelect2InitSelection),
  2745 												initSelection: ams.getFunctionByName(data.amsSelect2InitSelection),
  2573 												formatSelection: data.amsSelect2FormatSelection === undefined
  2746 												formatSelection: data.amsSelect2FormatSelection === undefined ?
  2574 																	? ams.helpers.select2FormatSelection
  2747 																	ams.helpers.select2FormatSelection
  2575 																	: ams.getFunctionByName(data.amsSelect2FormatSelection),
  2748 																	: ams.getFunctionByName(data.amsSelect2FormatSelection),
  2576 												formatResult: ams.getFunctionByName(data.amsSelect2FormatResult),
  2749 												formatResult: ams.getFunctionByName(data.amsSelect2FormatResult),
  2577 												formatMatches: data.amsSelect2FormatMatches === undefined
  2750 												formatMatches: data.amsSelect2FormatMatches === undefined ?
  2578 																	? function(matches) {
  2751 																	function(matches) {
  2579 																		if (matches == 1)
  2752 																		if (matches === 1) {
  2580 																			return ams.i18n.SELECT2_MATCH;
  2753 																			return ams.i18n.SELECT2_MATCH;
  2581 																		else
  2754 																		} else {
  2582 																			return matches + ams.i18n.SELECT2_MATCHES;
  2755 																			return matches + ams.i18n.SELECT2_MATCHES;
       
  2756 																		}
  2583 																	}
  2757 																	}
  2584 																	: ams.getFunctionByName(data.amsSelect2FormatMatches),
  2758 																	: ams.getFunctionByName(data.amsSelect2FormatMatches),
  2585 												formatNoMatches: data.amsSelect2FormatResult === undefined
  2759 												formatNoMatches: data.amsSelect2FormatResult === undefined ?
  2586 																	? function(term) {
  2760 																	function(term) {
  2587 																		return ams.i18n.SELECT2_NOMATCHES;
  2761 																		return ams.i18n.SELECT2_NOMATCHES;
  2588 																	}
  2762 																	}
  2589 																	: ams.getFunctionByName(data.amsSelect2FormatResult),
  2763 																	: ams.getFunctionByName(data.amsSelect2FormatResult),
  2590 												formatInputTooShort: data.amsSelect2FormatInputTooShort === undefined
  2764 												formatInputTooShort: data.amsSelect2FormatInputTooShort === undefined ?
  2591 																	? function(input, min) {
  2765 																	function(input, min) {
  2592 																		var n = min - input.length;
  2766 																		var n = min - input.length;
  2593 																		return ams.i18n.SELECT2_INPUT_TOOSHORT
  2767 																		return ams.i18n.SELECT2_INPUT_TOOSHORT
  2594 																						.replace(/\{0\}/, n)
  2768 																						.replace(/\{0\}/, n)
  2595 																						.replace(/\{1\}/, n == 1 ? "" : ams.i18n.SELECT2_PLURAL);
  2769 																						.replace(/\{1\}/, n === 1 ? "" : ams.i18n.SELECT2_PLURAL);
  2596 																	}
  2770 																	}
  2597 																	: ams.getFunctionByName(data.amsSelect2FormatInputTooShort),
  2771 																	: ams.getFunctionByName(data.amsSelect2FormatInputTooShort),
  2598 												formatInputTooLong: data.amsSelect2FormatInputTooLong === undefined
  2772 												formatInputTooLong: data.amsSelect2FormatInputTooLong === undefined ?
  2599 																	? function(input, max) {
  2773 																	function(input, max) {
  2600 																		var n = input.length - max;
  2774 																		var n = input.length - max;
  2601 																		return ams.i18n.SELECT2_INPUT_TOOLONG
  2775 																		return ams.i18n.SELECT2_INPUT_TOOLONG
  2602 																						.replace(/\{0\}/, n)
  2776 																						.replace(/\{0\}/, n)
  2603 																						.replace(/\{1\}/, n == 1 ? "" : ams.i18n.SELECT2_PLURAL);
  2777 																						.replace(/\{1\}/, n === 1 ? "" : ams.i18n.SELECT2_PLURAL);
  2604 																	}
  2778 																	}
  2605 																	: ams.getFunctionByName(data.amsSelect2FormatInputTooLong),
  2779 																	: ams.getFunctionByName(data.amsSelect2FormatInputTooLong),
  2606 												formatSelectionTooBig: data.amsSelect2FormatSelectionTooBig === undefined
  2780 												formatSelectionTooBig: data.amsSelect2FormatSelectionTooBig === undefined ?
  2607 																	? function(limit) {
  2781 																	function(limit) {
  2608 																		return ams.i18n.SELECT2_SELECTION_TOOBIG
  2782 																		return ams.i18n.SELECT2_SELECTION_TOOBIG
  2609 																						.replace(/\{0\}/, limit)
  2783 																						.replace(/\{0\}/, limit)
  2610 																						.replace(/\{1\}/, limit == 1 ? "" : ams.i18n.SELECT2_PLURAL);
  2784 																						.replace(/\{1\}/, limit === 1 ? "" : ams.i18n.SELECT2_PLURAL);
  2611 																	}
  2785 																	}
  2612 																	: ams.getFunctionByName(data.amsSelect2FormatSelectionTooBig),
  2786 																	: ams.getFunctionByName(data.amsSelect2FormatSelectionTooBig),
  2613 												formatLoadMore: data.amsSelect2FormatLoadMore === undefined
  2787 												formatLoadMore: data.amsSelect2FormatLoadMore === undefined ?
  2614 																	? function (pageNumber) {
  2788 																	function (pageNumber) {
  2615 																		return ams.i18n.SELECT2_LOADMORE;
  2789 																		return ams.i18n.SELECT2_LOADMORE;
  2616 																	}
  2790 																	}
  2617 																	: ams.getFunctionByName(data.amsSelect2FormatLoadMore),
  2791 																	: ams.getFunctionByName(data.amsSelect2FormatLoadMore),
  2618 												formatSearching: data.amsSelect2FormatSearching === undefined
  2792 												formatSearching: data.amsSelect2FormatSearching === undefined ?
  2619 																	? function() {
  2793 																	function() {
  2620 																		return ams.i18n.SELECT2_SEARCHING;
  2794 																		return ams.i18n.SELECT2_SEARCHING;
  2621 																	}
  2795 																	}
  2622 																	: ams.getFunctionByName(data.amsSelect2FormatSearching),
  2796 																	: ams.getFunctionByName(data.amsSelect2FormatSearching),
  2623 												separator: data.amsSelect2Separator || ',',
  2797 												separator: data.amsSelect2Separator || ',',
  2624 												tokenSeparators: data.amsSelect2TokensSeparators || [','],
  2798 												tokenSeparators: data.amsSelect2TokensSeparators || [','],
  2636 																$(element.val().split(data_options.separator)).each(function() {
  2810 																$(element.val().split(data_options.separator)).each(function() {
  2637 																	data.push({id: this,
  2811 																	data.push({id: this,
  2638 																			   text: values_data[this] || this});
  2812 																			   text: values_data[this] || this});
  2639 																});
  2813 																});
  2640 																callback(data);
  2814 																callback(data);
  2641 															}
  2815 															};
  2642 														}
  2816 														}
  2643 													}
  2817 													}
  2644 													break;
  2818 													break;
  2645 												default:
  2819 												default:
  2646 													break;
  2820 													break;
  2647 											}
  2821 											}
  2648 
  2822 
  2649 											if (select.attr('readonly')) {
  2823 											if (select.attr('readonly')) {
  2650 												if (select.attr('type') == 'hidden') {
  2824 												if (select.attr('type') === 'hidden') {
  2651 													data_options.query = function () {
  2825 													data_options.query = function () {
  2652 														return [];
  2826 														return [];
  2653 													};
  2827 													};
  2654 												}
  2828 												}
  2655 											} else if (data.amsSelect2Query) {
  2829 											} else if (data.amsSelect2Query) {
  2728 															   });
  2902 															   });
  2729 											}
  2903 											}
  2730 
  2904 
  2731 											select.on('change', function() {
  2905 											select.on('change', function() {
  2732 												var validator = $(select.get(0).form).data('validator');
  2906 												var validator = $(select.get(0).form).data('validator');
  2733 												if (validator !== undefined)
  2907 												if (validator !== undefined) {
  2734 													$(select).valid();
  2908 													$(select).valid();
       
  2909 												}
  2735 											});
  2910 											});
  2736 										});
  2911 										});
  2737 								   });
  2912 								   });
  2738 				}
  2913 				}
  2739 			},
  2914 			},
  2903 												},
  3078 												},
  2904 												errorElement: 'span',
  3079 												errorElement: 'span',
  2905 												errorClass: 'state-error',
  3080 												errorClass: 'state-error',
  2906 												errorPlacement: function(error, element) {
  3081 												errorPlacement: function(error, element) {
  2907 													var label = element.parents('label:first');
  3082 													var label = element.parents('label:first');
  2908 													if (label.length)
  3083 													if (label.length) {
  2909 														error.insertAfter(label);
  3084 														error.insertAfter(label);
  2910 													else
  3085 													} else {
  2911 														error.insertAfter(element);
  3086 														error.insertAfter(element);
       
  3087 													}
  2912 												}
  3088 												}
  2913 											});
  3089 											});
  2914 											if (ams.plugins.i18n) {
  3090 											if (ams.plugins.i18n) {
  2915 												for (var key in ams.plugins.i18n.validate) {
  3091 												for (var key in ams.plugins.i18n.validate) {
       
  3092 													if (!ams.plugins.i18n.validate.hasOwnProperty(key)) {
       
  3093 														continue;
       
  3094 													}
  2916 													var message = ams.plugins.i18n.validate[key];
  3095 													var message = ams.plugins.i18n.validate[key];
  2917 													if ((typeof(message) == 'string') &&
  3096 													if ((typeof(message) === 'string') &&
  2918 														(message.indexOf('{0}') > -1))
  3097 														(message.indexOf('{0}') > -1)) {
  2919 														ams.plugins.i18n.validate[key] = $.validator.format(message);
  3098 														ams.plugins.i18n.validate[key] = $.validator.format(message);
       
  3099 													}
  2920 												}
  3100 												}
  2921 												$.extend($.validator.messages, ams.plugins.i18n.validate);
  3101 												$.extend($.validator.messages, ams.plugins.i18n.validate);
  2922 											}
  3102 											}
  2923 										}
  3103 										}
  2924 										forms.each(function() {
  3104 										forms.each(function() {
  2925 											var form = $(this);
  3105 											var form = $(this);
  2926 											var data = form.data();
  3106 											var data = form.data();
  2927 											var data_options = {
  3107 											var data_options = {
  2928 												ignore: null,
  3108 												ignore: null,
  2929 												submitHandler: form.attr('data-async') !== undefined
  3109 												submitHandler: form.attr('data-async') !== undefined ?
  2930 															   ? data.amsFormSubmitHandler === undefined
  3110 															   data.amsFormSubmitHandler === undefined ?
  2931 																	? function() {
  3111 																	function() {
  2932 																		// JQuery-form plug-in must be loaded synchronously!!
  3112 																		// JQuery-form plug-in must be loaded synchronously!!
  2933 																		// Otherwise, hidden input fields created by jquery-validate plug-in
  3113 																		// Otherwise, hidden input fields created by jquery-validate plug-in
  2934 																		// and matching named buttons will be deleted (on first form submit)
  3114 																		// and matching named buttons will be deleted (on first form submit)
  2935 																		// before JQuery-form plug-in can get them when submitting the form...
  3115 																		// before JQuery-form plug-in can get them when submitting the form...
  2936 																		$('.state-error', form).removeClass('state-error');
  3116 																		$('.state-error', form).removeClass('state-error');
  2938 																					   ams.baseURL + 'ext/jquery-form-3.49' + ams.devext + '.js');
  3118 																					   ams.baseURL + 'ext/jquery-form-3.49' + ams.devext + '.js');
  2939 																		return ams.form.submit(form);
  3119 																		return ams.form.submit(form);
  2940 																	}
  3120 																	}
  2941 																	: ams.getFunctionByName(data.amsFormSubmitHandler)
  3121 																	: ams.getFunctionByName(data.amsFormSubmitHandler)
  2942 															   : undefined,
  3122 															   : undefined,
  2943 												invalidHandler: form.attr('data-async') !== undefined
  3123 												invalidHandler: form.attr('data-async') !== undefined ?
  2944 																? data.amsFormInvalidHandler === undefined
  3124 																data.amsFormInvalidHandler === undefined ?
  2945 																	? function(event, validator) {
  3125 																	function(event, validator) {
  2946 																		$('.state-error', form).removeClass('state-error');
  3126 																		$('.state-error', form).removeClass('state-error');
  2947 																		for (var index in validator.errorList) {
  3127 																		for (var index=0; index < validator.errorList.length; index++) {
  2948 																			var error = validator.errorList[index];
  3128 																			var error = validator.errorList[index];
  2949 																			var tab_index = $(error.element).parents('.tab-pane').index() + 1;
  3129 																			var tab_index = $(error.element).parents('.tab-pane').index() + 1;
  2950 																			if (tab_index > 0) {
  3130 																			if (tab_index > 0) {
  2951 																				var nav_tabs = $('.nav-tabs', $(error.element).parents('.tabforms'));
  3131 																				var nav_tabs = $('.nav-tabs', $(error.element).parents('.tabforms'));
  2952 																				$('li:nth-child(' + tab_index + ')', nav_tabs)
  3132 																				$('li:nth-child(' + tab_index + ')', nav_tabs)
  2976 				if (tables.length > 0) {
  3156 				if (tables.length > 0) {
  2977 					ams.ajax.check($.fn.dataTable,
  3157 					ams.ajax.check($.fn.dataTable,
  2978 								   ams.baseURL + 'ext/jquery-dataTables-1.9.4' + ams.devext + '.js',
  3158 								   ams.baseURL + 'ext/jquery-dataTables-1.9.4' + ams.devext + '.js',
  2979 								   function(first_load) {
  3159 								   function(first_load) {
  2980 										$(tables).each(function() {
  3160 										$(tables).each(function() {
  2981 											ams.ajax.check($.fn.dataTableExt.oPagination['bootstrap_full'],
  3161 											ams.ajax.check($.fn.dataTableExt.oPagination.bootstrap_full,
  2982 														   ams.baseURL + 'myams-dataTables' + ams.devext + '.js');
  3162 														   ams.baseURL + 'myams-dataTables' + ams.devext + '.js');
  2983 											var table = $(this);
  3163 											var table = $(this);
  2984 											var data = table.data();
  3164 											var data = table.data();
  2985 											var extensions = (data.amsDatatableExtensions || '').split(/\s+/);
  3165 											var extensions = (data.amsDatatableExtensions || '').split(/\s+/);
  2986 											// Check DOM elements
  3166 											// Check DOM elements
  2996 												">r<'dt-wrapper't" +
  3176 												">r<'dt-wrapper't" +
  2997 												(extensions.indexOf('scroller') >= 0 ? 'S' : '') +
  3177 												(extensions.indexOf('scroller') >= 0 ? 'S' : '') +
  2998 												"><'dt-row dt-bottom-row'<'row'<'col-sm-6'" +
  3178 												"><'dt-row dt-bottom-row'<'row'<'col-sm-6'" +
  2999 												(data.amsDatatableInformation === false ? '': 'i') +
  3179 												(data.amsDatatableInformation === false ? '': 'i') +
  3000 												"><'col-sm-6 text-right'p>>";
  3180 												"><'col-sm-6 text-right'p>>";
       
  3181 
  3001 											var index;
  3182 											var index;
  3002 											// Check initial sorting
  3183 											// Check initial sorting
  3003 											var sorting = data.amsDatatableSorting;
  3184 											var sorting = data.amsDatatableSorting;
  3004 											if (typeof(sorting) === 'string') {
  3185 											if (typeof(sorting) === 'string') {
  3005 												var sortings = sorting.split(';');
  3186 												var sortings = sorting.split(';');
  3006 												sorting = [];
  3187 												sorting = [];
  3007 												for (index in sortings) {
  3188 												for (index=0; index < sortings.length; index++) {
  3008 													var col_sorting = sortings[index].split(',');
  3189 													var col_sorting = sortings[index].split(',');
  3009 													col_sorting[0] = parseInt(col_sorting[0]);
  3190 													col_sorting[0] = parseInt(col_sorting[0]);
  3010 													sorting.push(col_sorting);
  3191 													sorting.push(col_sorting);
  3011 												}
  3192 												}
  3012 											}
  3193 											}
  3013 											// Check columns types
  3194 											// Check columns types
  3014 											var columns = [];
  3195 											var columns = [];
  3015 											var sort_types = $('th', table).listattr('data-ams-datatable-stype');
  3196 											var sort_types = $('th', table).listattr('data-ams-datatable-stype');
  3016 											for (index in sort_types) {
  3197 											for (index=0; index < sort_types.length; index++) {
  3017 												var sort_type = sort_types[index];
  3198 												var sort_type = sort_types[index];
  3018 												if (sort_type) {
  3199 												if (sort_type) {
  3019 													var column = columns[index] || {};
  3200 													var column = columns[index] || {};
  3020 													column.sType = sort_type;
  3201 													column.sType = sort_type;
  3021 													columns[index] = column;
  3202 													columns[index] = column;
  3041 																	   .html((ams.plugins.i18n.datatables.sColumns || "Columns") + ' <i class="fa fa-fw fa-caret-down"></i>');
  3222 																	   .html((ams.plugins.i18n.datatables.sColumns || "Columns") + ' <i class="fa fa-fw fa-caret-down"></i>');
  3042 												}
  3223 												}
  3043 											};
  3224 											};
  3044 											var settings = $.extend({}, data_options, data.amsDatatableOptions);
  3225 											var settings = $.extend({}, data_options, data.amsDatatableOptions);
  3045 											if (extensions.length > 0) {
  3226 											if (extensions.length > 0) {
  3046 												for (index in extensions) {
  3227 												for (index=0; index < extensions.length; index++) {
  3047 													switch (extensions[index]) {
  3228 													switch (extensions[index]) {
  3048 														case 'autofill':
  3229 														case 'autofill':
  3049 															ams.ajax.check($.fn.dataTable.AutoFill,
  3230 															ams.ajax.check($.fn.dataTable.AutoFill,
  3050 																		   ams.baseURL + 'ext/jquery-dataTables-autoFill' + ams.devext + '.js');
  3231 																		   ams.baseURL + 'ext/jquery-dataTables-autoFill' + ams.devext + '.js');
  3051 															break;
  3232 															break;
  3108 											settings = ams.executeFunctionByName(data.amsDatatableInitCallback, table, settings) || settings;
  3289 											settings = ams.executeFunctionByName(data.amsDatatableInitCallback, table, settings) || settings;
  3109 											try {  // Some settings can easilly generate DataTables exceptions...
  3290 											try {  // Some settings can easilly generate DataTables exceptions...
  3110 												var plugin = table.dataTable(settings);
  3291 												var plugin = table.dataTable(settings);
  3111 												ams.executeFunctionByName(data.amsDatatableAfterInitCallback, table, plugin, settings);
  3292 												ams.executeFunctionByName(data.amsDatatableAfterInitCallback, table, plugin, settings);
  3112 												if (extensions.length > 0) {
  3293 												if (extensions.length > 0) {
  3113 													for (index in extensions) {
  3294 													for (index=0; index < extensions.length; index++) {
  3114 														switch (extensions[index]) {
  3295 														switch (extensions[index]) {
  3115 															case 'autofill':
  3296 															case 'autofill':
  3116 																var af_settings = $.extend({}, data.amsDatatableAutofillOptions, settings.autofill);
  3297 																var af_settings = $.extend({}, data.amsDatatableAutofillOptions, settings.autofill);
  3117 																af_settings = ams.executeFunctionByName(data.amsDatatableAutofillInitCallback, table, af_settings) || af_settings;
  3298 																af_settings = ams.executeFunctionByName(data.amsDatatableAutofillInitCallback, table, af_settings) || af_settings;
  3118 																table.data('ams-autofill', data.amsDatatableAutofillConstructor === undefined
  3299 																table.data('ams-autofill', data.amsDatatableAutofillConstructor === undefined ?
  3119 																							? new $.fn.dataTable.AutoFill(table, af_settings)
  3300 																							new $.fn.dataTable.AutoFill(table, af_settings)
  3120 																							: ams.executeFunctionByName(data.amsDatatableAutofillConstructor, table, plugin, af_settings));
  3301 																							: ams.executeFunctionByName(data.amsDatatableAutofillConstructor, table, plugin, af_settings));
  3121 																break;
  3302 																break;
  3122 															case 'columnfilter':
  3303 															case 'columnfilter':
  3123 																var cf_default = {
  3304 																var cf_default = {
  3124 																	sPlaceHolder: 'head:after'
  3305 																	sPlaceHolder: 'head:after'
  3125 																};
  3306 																};
  3126 																var cf_settings = $.extend({}, cf_default, data.amsDatatableColumnfilterOptions, settings.columnfilter);
  3307 																var cf_settings = $.extend({}, cf_default, data.amsDatatableColumnfilterOptions, settings.columnfilter);
  3127 																cf_settings = ams.executeFunctionByName(data.amsDatatableColumnfilterInitCallback, table, cf_settings) || cf_settings;
  3308 																cf_settings = ams.executeFunctionByName(data.amsDatatableColumnfilterInitCallback, table, cf_settings) || cf_settings;
  3128 																table.data('ams-columnfilter', data.amsDatatableColumnfilterConstructor === undefined
  3309 																table.data('ams-columnfilter', data.amsDatatableColumnfilterConstructor === undefined ?
  3129 																							? plugin.columnFilter(cf_settings)
  3310 																							plugin.columnFilter(cf_settings)
  3130 																							: ams.executeFunctionByName(data.amsDatatableColumnfilterConstructor, table, plugin, cf_settings));
  3311 																							: ams.executeFunctionByName(data.amsDatatableColumnfilterConstructor, table, plugin, cf_settings));
  3131 																break;
  3312 																break;
  3132 															case 'editable':
  3313 															case 'editable':
  3133 																var ed_settings = $.extend({}, data.amsDatatableEditableOptions, settings.editable);
  3314 																var ed_settings = $.extend({}, data.amsDatatableEditableOptions, settings.editable);
  3134 																ed_settings = ams.executeFunctionByName(data.amsDatatableEditableInitCallback, table, ed_settings) || ed_settings;
  3315 																ed_settings = ams.executeFunctionByName(data.amsDatatableEditableInitCallback, table, ed_settings) || ed_settings;
  3135 																table.data('ams-editable', data.amsDatatableEditableConstructor === undefined
  3316 																table.data('ams-editable', data.amsDatatableEditableConstructor === undefined ?
  3136 																							? table.makeEditable(ed_settings)
  3317 																							table.makeEditable(ed_settings)
  3137 																							: ams.executeFunctionByName(data.amsDatatableEditableConstructor, table, plugin, ed_settings));
  3318 																							: ams.executeFunctionByName(data.amsDatatableEditableConstructor, table, plugin, ed_settings));
  3138 																break;
  3319 																break;
  3139 															case 'fixedcolumns':
  3320 															case 'fixedcolumns':
  3140 																var fc_settings = $.extend({}, data.amsDatatableFixedcolumnsOptions, settings.fixedcolumns);
  3321 																var fc_settings = $.extend({}, data.amsDatatableFixedcolumnsOptions, settings.fixedcolumns);
  3141 																fc_settings = ams.executeFunctionByName(data.amsDatatableFixedcolumnsInitCallback, table, fc_settings) || fc_settings;
  3322 																fc_settings = ams.executeFunctionByName(data.amsDatatableFixedcolumnsInitCallback, table, fc_settings) || fc_settings;
  3142 																table.data('ams-fixedcolumns', data.amsDatatableFixedcolumnsConstructor === undefined
  3323 																table.data('ams-fixedcolumns', data.amsDatatableFixedcolumnsConstructor === undefined ?
  3143 																							? new $.fn.dataTable.FixedColumns(table, fc_settings)
  3324 																							new $.fn.dataTable.FixedColumns(table, fc_settings)
  3144 																							: ams.executeFunctionByName(data.amsDatatableFixedcolumnsConstructor, table, plugin, fc_settings));
  3325 																							: ams.executeFunctionByName(data.amsDatatableFixedcolumnsConstructor, table, plugin, fc_settings));
  3145 																break;
  3326 																break;
  3146 															case 'fixedheader':
  3327 															case 'fixedheader':
  3147 																var fh_settings = $.extend({}, data.amsDatatableFixedheaderOptions, settings.fixedheader);
  3328 																var fh_settings = $.extend({}, data.amsDatatableFixedheaderOptions, settings.fixedheader);
  3148 																fh_settings = ams.executeFunctionByName(data.amsDatatableFixedheadeInitCallback, table, fh_settings) || fh_settings;
  3329 																fh_settings = ams.executeFunctionByName(data.amsDatatableFixedheadeInitCallback, table, fh_settings) || fh_settings;
  3149 																table.data('ams-fixedheader', data.amsDatatableFixedheaderConstructor === undefined
  3330 																table.data('ams-fixedheader', data.amsDatatableFixedheaderConstructor === undefined ?
  3150 																							? new $.fn.dataTable.FixedHeader(table, fh_settings)
  3331 																							new $.fn.dataTable.FixedHeader(table, fh_settings)
  3151 																							: ams.executeFunctionByName(data.amsDatatableFixedheaderConstructor, table, plugin, fh_settings));
  3332 																							: ams.executeFunctionByName(data.amsDatatableFixedheaderConstructor, table, plugin, fh_settings));
  3152 																break;
  3333 																break;
  3153 															case 'keytable':
  3334 															case 'keytable':
  3154 																var kt_default = {
  3335 																var kt_default = {
  3155 																	table: table.get(0),
  3336 																	table: table.get(0),
  3156 																	datatable: plugin
  3337 																	datatable: plugin
  3157 																};
  3338 																};
  3158 																var kt_settings = $.extend({}, kt_default, data.amsDatatableKeytableOptions, settings.keytable);
  3339 																var kt_settings = $.extend({}, kt_default, data.amsDatatableKeytableOptions, settings.keytable);
  3159 																kt_settings = ams.executeFunctionByName(data.amsDatatableKeytableInitCallback, table, kt_settings) || kt_settings;
  3340 																kt_settings = ams.executeFunctionByName(data.amsDatatableKeytableInitCallback, table, kt_settings) || kt_settings;
  3160 																table.data('ams-keytable', data.amsDatatableKeytableConstructor === undefined
  3341 																table.data('ams-keytable', data.amsDatatableKeytableConstructor === undefined ?
  3161 																							? new KeyTable(kt_settings)
  3342 																							new KeyTable(kt_settings)
  3162 																							: ams.executeFunctionByName(data.amsDatatableKeytableConstructor, table, plugin, kt_settings));
  3343 																							: ams.executeFunctionByName(data.amsDatatableKeytableConstructor, table, plugin, kt_settings));
  3163 																break;
  3344 																break;
  3164 															case 'rowgrouping':
  3345 															case 'rowgrouping':
  3165 																var rg_settings = $.extend({}, data.amsDatatableRowgroupingOptions, settings.rowgrouping);
  3346 																var rg_settings = $.extend({}, data.amsDatatableRowgroupingOptions, settings.rowgrouping);
  3166 																rg_settings = ams.executeFunctionByName(data.amsDatatableRowgroupingInitCallback, table, rg_settings) || rg_settings;
  3347 																rg_settings = ams.executeFunctionByName(data.amsDatatableRowgroupingInitCallback, table, rg_settings) || rg_settings;
  3167 																table.data('ams-rowgrouping', data.amsDatatableRowgroupingConstructor === undefined
  3348 																table.data('ams-rowgrouping', data.amsDatatableRowgroupingConstructor === undefined ?
  3168 																							? table.rowGrouping(rg_settings)
  3349 																							table.rowGrouping(rg_settings)
  3169 																							: ams.executeFunctionByName(data.amsDatatableRowgroupingConstructor, table, plugin, rg_settings));
  3350 																							: ams.executeFunctionByName(data.amsDatatableRowgroupingConstructor, table, plugin, rg_settings));
  3170 																break;
  3351 																break;
  3171 															case 'rowreordering':
  3352 															case 'rowreordering':
  3172 																var rr_settings = $.extend({}, data.amsDatatableRowreorderingOptions, settings.rowreordering);
  3353 																var rr_settings = $.extend({}, data.amsDatatableRowreorderingOptions, settings.rowreordering);
  3173 																rr_settings = ams.executeFunctionByName(data.amsDatatableRowreorderingInitCallback, table, rr_settings) || rr_settings;
  3354 																rr_settings = ams.executeFunctionByName(data.amsDatatableRowreorderingInitCallback, table, rr_settings) || rr_settings;
  3174 																table.data('ams-rowreordering', data.amsDatatableRowreorderingConstructor === undefined
  3355 																table.data('ams-rowreordering', data.amsDatatableRowreorderingConstructor === undefined ?
  3175 																							? table.rowReordering(rr_settings)
  3356 																							table.rowReordering(rr_settings)
  3176 																							: ams.executeFunctionByName(data.amsDatatableRowreorderingConstructor, table, plugin, rr_settings));
  3357 																							: ams.executeFunctionByName(data.amsDatatableRowreorderingConstructor, table, plugin, rr_settings));
  3177 																break;
  3358 																break;
  3178 															default:
  3359 															default:
  3179 																break;
  3360 																break;
  3180 														}
  3361 														}
  3181 													}
  3362 													}
  3182 												}
  3363 												}
  3183 												var finalizers = (data.amsDatatableFinalizeCallback || '').split(/\s+/);
  3364 												var finalizers = (data.amsDatatableFinalizeCallback || '').split(/\s+/);
  3184 												if (finalizers.length > 0) {
  3365 												if (finalizers.length > 0) {
  3185 													for (index in finalizers) {
  3366 													for (index=0; index < finalizers.length; index++) {
  3186 														ams.executeFunctionByName(finalizers[index], table, plugin, settings);
  3367 														ams.executeFunctionByName(finalizers[index], table, plugin, settings);
  3187 													}
  3368 													}
  3188 												}
  3369 												}
  3189 											}
  3370 											}
  3190 											catch (e) {}
  3371 											catch (e) {}
  3220 													var target = data.amsTabledndDropTarget;
  3401 													var target = data.amsTabledndDropTarget;
  3221 													if (target) {
  3402 													if (target) {
  3222 														var rows = [];
  3403 														var rows = [];
  3223 														$(dnd_table.rows).each(function() {
  3404 														$(dnd_table.rows).each(function() {
  3224 															var row_id = $(this).data('ams-element-name');
  3405 															var row_id = $(this).data('ams-element-name');
  3225 															if (row_id)
  3406 															if (row_id) {
  3226 																rows.push(row_id);
  3407 																rows.push(row_id);
       
  3408 															}
  3227 														});
  3409 														});
  3228 														var local_target = ams.getFunctionByName(target);
  3410 														var local_target = ams.getFunctionByName(target);
  3229 														if (typeof(local_target) == 'function') {
  3411 														if (typeof(local_target) === 'function') {
  3230 															local_target.call(table, dnd_table, rows);
  3412 															local_target.call(table, dnd_table, rows);
  3231 														} else {
  3413 														} else {
  3232 															ams.ajax.post(target, {names: JSON.stringify(rows)});
  3414 															ams.ajax.post(target, {names: JSON.stringify(rows)});
  3233 														}
  3415 														}
  3234 													}
  3416 													}
  3251 				var images = $('.imgareaselect', element);
  3433 				var images = $('.imgareaselect', element);
  3252 				if (images.length > 0) {
  3434 				if (images.length > 0) {
  3253 					ams.ajax.check($.fn.imgAreaSelect,
  3435 					ams.ajax.check($.fn.imgAreaSelect,
  3254 								   ams.baseURL + 'ext/jquery-imgareaselect-0.9.10' + ams.devext + '.js',
  3436 								   ams.baseURL + 'ext/jquery-imgareaselect-0.9.10' + ams.devext + '.js',
  3255 								   function(first_load) {
  3437 								   function(first_load) {
  3256 									   if (first_load)
  3438 									   if (first_load) {
  3257 										   ams.getCSS(ams.baseURL + '../css/ext/jquery-imgareaselect' + ams.devext + '.css');
  3439 										   ams.getCSS(ams.baseURL + '../css/ext/jquery-imgareaselect' + ams.devext + '.css');
       
  3440 									   }
  3258 									   images.each(function() {
  3441 									   images.each(function() {
  3259 										   var image = $(this);
  3442 										   var image = $(this);
  3260 										   var data = image.data();
  3443 										   var data = image.data();
  3261 										   var parent = data.amsImgareaselectParent ? image.parents(data.amsImgareaselectParent) : 'body';
  3444 										   var parent = data.amsImgareaselectParent ? image.parents(data.amsImgareaselectParent) : 'body';
  3262 										   var data_options = {
  3445 										   var data_options = {
  3287 										   // Add update timeout when plug-in is displayed into a modal dialog
  3470 										   // Add update timeout when plug-in is displayed into a modal dialog
  3288 										   setTimeout(function() {
  3471 										   setTimeout(function() {
  3289 											   plugin.update();
  3472 											   plugin.update();
  3290 										   }, 250);
  3473 										   }, 250);
  3291 									   });
  3474 									   });
  3292 								   })
  3475 								   });
  3293 				}
  3476 				}
  3294 			},
  3477 			},
  3295 
  3478 
  3296 			/**
  3479 			/**
  3297 			 * FancyBox plug-in
  3480 			 * FancyBox plug-in
  3300 				var fancyboxes = $('.fancybox', element);
  3483 				var fancyboxes = $('.fancybox', element);
  3301 				if (fancyboxes.length > 0) {
  3484 				if (fancyboxes.length > 0) {
  3302 					ams.ajax.check($.fn.fancybox,
  3485 					ams.ajax.check($.fn.fancybox,
  3303 								   ams.baseURL + 'ext/jquery-fancybox-2.1.5' + ams.devext + '.js',
  3486 								   ams.baseURL + 'ext/jquery-fancybox-2.1.5' + ams.devext + '.js',
  3304 								   function(first_load) {
  3487 								   function(first_load) {
  3305 										if (first_load)
  3488 										if (first_load) {
  3306 											ams.getCSS(ams.baseURL + '../css/ext/jquery-fancybox-2.1.5' + ams.devext + '.css');
  3489 											ams.getCSS(ams.baseURL + '../css/ext/jquery-fancybox-2.1.5' + ams.devext + '.css');
       
  3490 										}
  3307 										fancyboxes.each(function() {
  3491 										fancyboxes.each(function() {
  3308 											var fancybox = $(this);
  3492 											var fancybox = $(this);
  3309 											var data = fancybox.data();
  3493 											var data = fancybox.data();
  3310 											var helpers = (data.amsFancyboxHelpers || '').split(/\s+/);
  3494 											var helpers = (data.amsFancyboxHelpers || '').split(/\s+/);
  3311 											if (helpers.length > 0) {
  3495 											if (helpers.length > 0) {
  3312 												for (var index in helpers) {
  3496 												for (var index=0; index < helpers.length; index++) {
  3313 													var helper = helpers[index];
  3497 													var helper = helpers[index];
  3314 													switch (helper) {
  3498 													switch (helper) {
  3315 														case 'buttons':
  3499 														case 'buttons':
  3316 															ams.ajax.check($.fancybox.helpers.buttons,
  3500 															ams.ajax.check($.fancybox.helpers.buttons,
  3317 																		   ams.baseURL + 'ext/fancybox-helpers/fancybox-buttons' + ams.devext + '.js');
  3501 																		   ams.baseURL + 'ext/fancybox-helpers/fancybox-buttons' + ams.devext + '.js');
  3375 								   ams.baseURL + 'ext/jquery-mousewheel.min.js',
  3559 								   ams.baseURL + 'ext/jquery-mousewheel.min.js',
  3376 								   function() {
  3560 								   function() {
  3377 										ams.ajax.check($.fn.mCustomScrollbar,
  3561 										ams.ajax.check($.fn.mCustomScrollbar,
  3378 													   ams.baseURL + 'ext/jquery-mCustomScrollbar' + ams.devext + '.js',
  3562 													   ams.baseURL + 'ext/jquery-mCustomScrollbar' + ams.devext + '.js',
  3379 													   function(first_load) {
  3563 													   function(first_load) {
  3380 															if (first_load)
  3564 															if (first_load) {
  3381 																ams.getCSS(ams.baseURL + '../css/ext/jquery-mCustomScrollbar.css',
  3565 																ams.getCSS(ams.baseURL + '../css/ext/jquery-mCustomScrollbar.css',
  3382 																		  'jquery-mCustomScrollbar');
  3566 																		   'jquery-mCustomScrollbar');
       
  3567 															}
  3383 															scrollbars.each(function() {
  3568 															scrollbars.each(function() {
  3384 																var scrollbar = $(this);
  3569 																var scrollbar = $(this);
  3385 																var data = scrollbar.data();
  3570 																var data = scrollbar.data();
  3386 																var data_options = {
  3571 																var data_options = {
  3387 																	theme: data.amsScrollbarTheme || 'light'
  3572 																	theme: data.amsScrollbarTheme || 'light'
  3425 					if (data.amsCallbackSource) {
  3610 					if (data.amsCallbackSource) {
  3426 						ams.getScript(data.amsCallbackSource,
  3611 						ams.getScript(data.amsCallbackSource,
  3427 									  function() {
  3612 									  function() {
  3428 										ams.executeFunctionByName(data.amsCallback, self, data.amsCallbackOptions);
  3613 										ams.executeFunctionByName(data.amsCallback, self, data.amsCallbackOptions);
  3429 									  });
  3614 									  });
  3430 					} else if (window.console) {
  3615 					} else if (globals.console) {
  3431 						console.warn("Undefined callback: " + data.amsCallback);
  3616 						globals.console.warn("Undefined callback: " + data.amsCallback);
  3432 					}
  3617 					}
  3433 				} else {
  3618 				} else {
  3434 					callback.call(self, data.amsCallbackOptions);
  3619 					callback.call(self, data.amsCallbackOptions);
  3435 				}
  3620 				}
  3436 			})
  3621 			});
  3437 		},
  3622 		},
  3438 
  3623 
  3439 		/**
  3624 		/**
  3440 		 * Standard alert message callback
  3625 		 * Standard alert message callback
  3441 		 *
  3626 		 *
  3535 		 */
  3720 		 */
  3536 		init: function(element) {
  3721 		init: function(element) {
  3537 			$('[data-ams-events-handlers]', element).each(function() {
  3722 			$('[data-ams-events-handlers]', element).each(function() {
  3538 				var element = $(this);
  3723 				var element = $(this);
  3539 				var handlers = element.data('ams-events-handlers');
  3724 				var handlers = element.data('ams-events-handlers');
  3540 				for (var event in handlers) {
  3725 				if (handlers) {
  3541 					element.on(event, ams.getFunctionByName(handlers[event]));
  3726 					for (var event in handlers) {
       
  3727 						if (handlers.hasOwnProperty(event)) {
       
  3728 							element.on(event, ams.getFunctionByName(handlers[event]));
       
  3729 						}
       
  3730 					}
  3542 				}
  3731 				}
  3543 			});
  3732 			});
  3544 		}
  3733 		}
  3545 	};
  3734 	};
  3546 
  3735 
  3575 				MyAMS.skin.bigBox({
  3764 				MyAMS.skin.bigBox({
  3576 					title: ams.i18n.WARNING,
  3765 					title: ams.i18n.WARNING,
  3577 					content: '<i class="text-danger fa fa-2x fa-bell shake animated"></i>&nbsp; ' + ams.i18n.DELETE_WARNING,
  3766 					content: '<i class="text-danger fa fa-2x fa-bell shake animated"></i>&nbsp; ' + ams.i18n.DELETE_WARNING,
  3578 					buttons: ams.i18n.BTN_OK_CANCEL
  3767 					buttons: ams.i18n.BTN_OK_CANCEL
  3579 				}, function(button) {
  3768 				}, function(button) {
  3580 					if (button == ams.i18n.BTN_OK) {
  3769 					if (button === ams.i18n.BTN_OK) {
  3581 						var table = link.parents('table');
  3770 						var table = link.parents('table');
  3582 						var location = table.data('ams-location') || '';
  3771 						var location = table.data('ams-location') || '';
  3583 						var tr = link.parents('tr');
  3772 						var tr = link.parents('tr');
  3584 						var delete_target = tr.data('ams-delete-target') || table.data('ams-delete-target') || 'delete-element.json';
  3773 						var delete_target = tr.data('ams-delete-target') || table.data('ams-delete-target') || 'delete-element.json';
  3585 						var object_name = tr.data('ams-element-name');
  3774 						var object_name = tr.data('ams-element-name');
  3586 						MyAMS.ajax.post(location + '/' + delete_target, {'object_name': object_name}, function(result, status) {
  3775 						MyAMS.ajax.post(location + '/' + delete_target, {'object_name': object_name}, function(result, status) {
  3587 							if (result.status == 'success') {
  3776 							if (result.status === 'success') {
  3588 								if (table.hasClass('datatable')) {
  3777 								if (table.hasClass('datatable')) {
  3589 									table.dataTable().fnDeleteRow(tr[0]);
  3778 									table.dataTable().fnDeleteRow(tr[0]);
  3590 								} else {
  3779 								} else {
  3591 									tr.remove();
  3780 									tr.remove();
  3592 								}
  3781 								}
  3593 							}
  3782 							}
  3594 						});
  3783 						});
  3595 					}
  3784 					}
  3596 				});
  3785 				});
  3597 			}
  3786 			};
  3598 		}
  3787 		}
  3599 	};
  3788 	};
  3600 
  3789 
  3601 
  3790 
  3602 	/**
  3791 	/**
  3622 
  3811 
  3623 		/**
  3812 		/**
  3624 		 * Check width for mobile devices
  3813 		 * Check width for mobile devices
  3625 		 */
  3814 		 */
  3626 		_checkMobileWidth: function() {
  3815 		_checkMobileWidth: function() {
  3627 			if ($(window).width() < 979)
  3816 			if ($(window).width() < 979) {
  3628 				ams.root.addClass('mobile-view-activated')
  3817 				ams.root.addClass('mobile-view-activated');
  3629 			else if (ams.root.hasClass('mobile-view-activated'))
  3818 			} else if (ams.root.hasClass('mobile-view-activated')) {
  3630 				ams.root.removeClass('mobile-view-activated');
  3819 				ams.root.removeClass('mobile-view-activated');
       
  3820 			}
  3631 		},
  3821 		},
  3632 
  3822 
  3633 		/**
  3823 		/**
  3634 		 * Show/hide shortcut buttons
  3824 		 * Show/hide shortcut buttons
  3635 		 */
  3825 		 */
  3637 			ams.shortcuts.animate({
  3827 			ams.shortcuts.animate({
  3638 				height: 'show'
  3828 				height: 'show'
  3639 			}, 200, 'easeOutCirc');
  3829 			}, 200, 'easeOutCirc');
  3640 			ams.root.addClass('shortcut-on');
  3830 			ams.root.addClass('shortcut-on');
  3641 		},
  3831 		},
  3642 		
  3832 
  3643 		_hideShortcutButtons: function() {
  3833 		_hideShortcutButtons: function() {
  3644 			ams.shortcuts.animate({
  3834 			ams.shortcuts.animate({
  3645 				height: 'hide'
  3835 				height: 'hide'
  3646 			}, 300, 'easeOutCirc');
  3836 			}, 300, 'easeOutCirc');
  3647 			ams.root.removeClass('shortcut-on');
  3837 			ams.root.removeClass('shortcut-on');
  3649 
  3839 
  3650 		/**
  3840 		/**
  3651 		 * Check notification badge
  3841 		 * Check notification badge
  3652 		 */
  3842 		 */
  3653 		checkNotification: function() {
  3843 		checkNotification: function() {
  3654 			$this = $('#activity > .badge');
  3844 			var badge = $('#activity > .badge');
  3655 			if (parseInt($this.text()) > 0)
  3845 			if (parseInt(badge.text()) > 0) {
  3656 				$this.removeClass("hidden")
  3846 				badge.removeClass("hidden")
  3657 					 .addClass("bg-color-red bounceIn animated");
  3847 					 .addClass("bg-color-red bounceIn animated");
  3658 			else
  3848 			} else {
  3659 				$this.addClass("hidden")
  3849 				badge.addClass("hidden")
  3660 					 .removeClass("bg-color-red bounceIn animated");
  3850 					 .removeClass("bg-color-red bounceIn animated");
       
  3851 			}
  3661 		},
  3852 		},
  3662 
  3853 
  3663 		/**
  3854 		/**
  3664 		 * Initialize desktop and mobile widgets
  3855 		 * Initialize desktop and mobile widgets
  3665 		 */
  3856 		 */
  3666 		_initDesktopWidgets: function(element) {
  3857 		_initDesktopWidgets: function(element) {
  3667 			if (ams.enable_widgets) {
  3858 			if (ams.enable_widgets) {
  3668 				var widgets = $('.ams-widget', element);
  3859 				var widgets = $('.ams-widget', element);
  3669 				if (widgets.length > 0)
  3860 				if (widgets.length > 0) {
  3670 					ams.ajax.check($.fn.MyAMSWidget,
  3861 					ams.ajax.check($.fn.MyAMSWidget,
  3671 								   ams.baseURL + 'myams-widgets' + ams.devext + '.js',
  3862 								   ams.baseURL + 'myams-widgets' + ams.devext + '.js',
  3672 								   function() {
  3863 								   function () {
  3673 										widgets.each(function() {
  3864 									   widgets.each(function () {
  3674 											var widget = $(this);
  3865 										   var widget = $(this);
  3675 											var data = widget.data();
  3866 										   var data = widget.data();
  3676 											var data_options = {
  3867 										   var data_options = {
  3677 												deleteSettingsKey: '#deletesettingskey-options',
  3868 											   deleteSettingsKey: '#deletesettingskey-options',
  3678 												deletePositionKey: '#deletepositionkey-options'
  3869 											   deletePositionKey: '#deletepositionkey-options'
  3679 											};
  3870 										   };
  3680 											var settings = $.extend({}, data_options, data.amsWidgetOptions);
  3871 										   var settings = $.extend({}, data_options, data.amsWidgetOptions);
  3681 											settings = ams.executeFunctionByName(data.amsWidgetInitcallback, widget, settings) || settings;
  3872 										   settings = ams.executeFunctionByName(data.amsWidgetInitcallback, widget, settings) || settings;
  3682 											widget.MyAMSWidget(settings);
  3873 										   widget.MyAMSWidget(settings);
  3683 										});
  3874 									   });
  3684 										MyAMSWidget.initWidgetsGrid($('.ams-widget-grid', element));
  3875 									   globals.MyAMSWidget.initWidgetsGrid($('.ams-widget-grid', element));
  3685 									});
  3876 								   });
       
  3877 				}
  3686 			}
  3878 			}
  3687 		},
  3879 		},
  3688 
  3880 
  3689 		_initMobileWidgets: function(element) {
  3881 		_initMobileWidgets: function(element) {
  3690 			if (ams.enable_mobile && ams.enable_widgets)
  3882 			if (ams.enable_mobile && ams.enable_widgets) {
  3691 				ams.skin._initDesktopWidgets(element);
  3883 				ams.skin._initDesktopWidgets(element);
       
  3884 			}
  3692 		},
  3885 		},
  3693 
  3886 
  3694 		/**
  3887 		/**
  3695 		 * Add an alert on top of a container
  3888 		 * Add an alert on top of a container
  3696 		 *
  3889 		 *
  3701 		 * @subtitle: optional subtitle
  3894 		 * @subtitle: optional subtitle
  3702 		 * @margin: if true, a margin will be displayed around alert
  3895 		 * @margin: if true, a margin will be displayed around alert
  3703 		 */
  3896 		 */
  3704 		alert: function(parent, status, header, message, subtitle, margin) {
  3897 		alert: function(parent, status, header, message, subtitle, margin) {
  3705 			$('.alert', parent).remove();
  3898 			$('.alert', parent).remove();
  3706 			if (status == 'error')
  3899 			if (status === 'error') {
  3707 				status = 'danger';
  3900 				status = 'danger';
       
  3901 			}
  3708 			var content = '<div class="' + (margin ? 'margin-10' : '') + ' alert alert-block alert-' + status + ' fade in">' +
  3902 			var content = '<div class="' + (margin ? 'margin-10' : '') + ' alert alert-block alert-' + status + ' fade in">' +
  3709 							'<a class="close" data-dismiss="alert"><i class="fa fa-check"></i></a>' +
  3903 				'<a class="close" data-dismiss="alert"><i class="fa fa-check"></i></a>' +
  3710 							'<h4 class="alert-heading">' +
  3904 				'<h4 class="alert-heading">' +
  3711 								'<i class="fa fa-fw fa-warning"></i> ' + header +
  3905 				'<i class="fa fa-fw fa-warning"></i> ' + header +
  3712 							'</h4>' +
  3906 				'</h4>' +
  3713 							(subtitle ? ('<p>' + subtitle + '</p>') : '');
  3907 				(subtitle ? ('<p>' + subtitle + '</p>') : '');
  3714 			if (typeof(message) == 'string')
  3908 			if (typeof(message) === 'string') {
  3715 				content += '<ul><li>' + message + '</li></ul>';
  3909 				content += '<ul><li>' + message + '</li></ul>';
  3716 			else if (message) {
  3910 			} else if (message) {
  3717 				content += '<ul>';
  3911 				content += '<ul>';
  3718 				for (var index in message) {
  3912 				for (var index in message) {
  3719 					if (!$.isNumeric(index))  // IE check
  3913 					if (!$.isNumeric(index)) {  // IE check
  3720 						continue;
  3914 						continue;
       
  3915 					}
  3721 					content += '<li>' + message[index] + '</li>';
  3916 					content += '<li>' + message[index] + '</li>';
  3722 				};
  3917 				}
  3723 				content += '</ul>';
  3918 				content += '</ul>';
  3724 			}
  3919 			}
  3725 			content += '</div>';
  3920 			content += '</div>';
  3726 			var alert = $(content).prependTo(parent);
  3921 			var alert = $(content).prependTo(parent);
  3727 			if (parent.exists) {
  3922 			if (parent.exists) {
  3728 				ams.ajax.check($.scrollTo,
  3923 				ams.ajax.check($.scrollTo,
  3729 							   ams.baseURL + 'ext/jquery-scrollTo.min.js',
  3924 							   ams.baseURL + 'ext/jquery-scrollTo.min.js',
  3730 							   function() {
  3925 							   function() {
  3731 									$.scrollTo(parent, {offset: {top: -50}});
  3926 								   $.scrollTo(parent, {offset: {top: -50}});
  3732 							   });
  3927 							   });
  3733 			}
  3928 			}
  3734 		},
  3929 		},
  3735 
  3930 
  3736 		/**
  3931 		/**
  3746 
  3941 
  3747 		/**
  3942 		/**
  3748 		 * Medium notification message box, displayed on page's bottom right
  3943 		 * Medium notification message box, displayed on page's bottom right
  3749 		 */
  3944 		 */
  3750 		messageBox: function(status, options, callback) {
  3945 		messageBox: function(status, options, callback) {
  3751 			if (typeof(status) == 'object') {
  3946 			if (typeof(status) === 'object') {
  3752 				callback = options;
  3947 				callback = options;
  3753 				options = status || {};
  3948 				options = status || {};
  3754 				status = 'info';
  3949 				status = 'info';
  3755 			}
  3950 			}
  3756 			ams.ajax.check(ams.notify,
  3951 			ams.ajax.check(ams.notify,
  3757 						   ams.baseURL + 'myams-notify' + ams.devext + '.js',
  3952 						   ams.baseURL + 'myams-notify' + ams.devext + '.js',
  3758 						   function() {
  3953 						   function() {
  3759 								switch (status) {
  3954 							   switch (status) {
  3760 									case 'error':
  3955 								   case 'error':
  3761 									case 'danger':
  3956 								   case 'danger':
  3762 										options.color = '#C46A69';
  3957 									   options.color = '#C46A69';
  3763 										break;
  3958 									   break;
  3764 									case 'warning':
  3959 								   case 'warning':
  3765 										options.color = '#C79121';
  3960 									   options.color = '#C79121';
  3766 										break;
  3961 									   break;
  3767 									case 'success':
  3962 								   case 'success':
  3768 										options.color = '#739E73';
  3963 									   options.color = '#739E73';
  3769 										break;
  3964 									   break;
  3770 									default:
  3965 								   default:
  3771 										options.color = options.color || '#3276B1';
  3966 									   options.color = options.color || '#3276B1';
  3772 								}
  3967 							   }
  3773 								options.sound = false;
  3968 							   options.sound = false;
  3774 								ams.notify.bigBox(options, callback);
  3969 							   ams.notify.bigBox(options, callback);
  3775 						   });
  3970 						   });
  3776 		},
  3971 		},
  3777 
  3972 
  3778 		/**
  3973 		/**
  3779 		 * Small notification message box, displayed on page's top right
  3974 		 * Small notification message box, displayed on page's top right
  3780 		 */
  3975 		 */
  3781 		smallBox: function(status, options, callback) {
  3976 		smallBox: function(status, options, callback) {
  3782 			if (typeof(status) == 'object') {
  3977 			if (typeof(status) === 'object') {
  3783 				callback = options;
  3978 				callback = options;
  3784 				options = status || {};
  3979 				options = status || {};
  3785 				status = 'info';
  3980 				status = 'info';
  3786 			}
  3981 			}
  3787 			ams.ajax.check(ams.notify,
  3982 			ams.ajax.check(ams.notify,
  3788 						   ams.baseURL + 'myams-notify' + ams.devext + '.js',
  3983 						   ams.baseURL + 'myams-notify' + ams.devext + '.js',
  3789 						   function() {
  3984 						   function () {
  3790 								switch (status) {
  3985 							   switch (status) {
  3791 									case 'error':
  3986 								   case 'error':
  3792 									case 'danger':
  3987 								   case 'danger':
  3793 										options.color = '#C46A69';
  3988 									   options.color = '#C46A69';
  3794 										break;
  3989 									   break;
  3795 									case 'warning':
  3990 								   case 'warning':
  3796 										options.color = '#C79121';
  3991 									   options.color = '#C79121';
  3797 										break;
  3992 									   break;
  3798 									case 'success':
  3993 								   case 'success':
  3799 										options.color = '#739E73';
  3994 									   options.color = '#739E73';
  3800 										break;
  3995 									   break;
  3801 									default:
  3996 								   default:
  3802 										options.color = options.color || '#3276B1';
  3997 									   options.color = options.color || '#3276B1';
  3803 								}
  3998 							   }
  3804 								options.sound = false;
  3999 							   options.sound = false;
  3805 								ams.notify.smallBox(options, callback);
  4000 							   ams.notify.smallBox(options, callback);
  3806 						   });
  4001 						   });
  3807 		},
  4002 		},
  3808 
  4003 
  3809 		/**
  4004 		/**
  3810 		 * Initialize breadcrumbs based on active menu position
  4005 		 * Initialize breadcrumbs based on active menu position
  3811 		 */
  4006 		 */
  3812 		_drawBreadCrumb: function() {
  4007 		_drawBreadCrumb: function() {
  3813 			var crumb = $('#ribbon OL.breadcrumb');
  4008 			var crumb = $('#ribbon OL.breadcrumb');
  3814 			crumb.empty()
  4009 			crumb.empty()
  3815 				 .append($('<li></li>').append($('<a></a>').text(ams.i18n.HOME)
  4010 				 .append($('<li></li>').append($('<a></a>').text(ams.i18n.HOME)
  3816 				 										   .attr('href', $('nav a[href!="#"]:first').attr('href'))));
  4011 														   .attr('href', $('nav a[href!="#"]:first').attr('href'))));
  3817 			$('nav LI.active >A').each(function() {
  4012 			$('nav LI.active >A').each(function() {
  3818 				var menu = $(this);
  4013 				var menu = $(this);
  3819 				var body = $.trim(menu.clone()
  4014 				var body = $.trim(menu.clone()
  3820 									  .children(".badge")
  4015 									  .children(".badge")
  3821 									  .remove()
  4016 									  .remove()
  3822 									  .end()
  4017 									  .end()
  3823 									  .text());
  4018 									  .text());
  3824 				var item = $("<li></li>").append(menu.attr('href').replace(/^#/, '')
  4019 				var item = $("<li></li>").append(menu.attr('href').replace(/^#/, '') ?
  3825 													? $("<a></a>").html(body)
  4020 												 $("<a></a>").html(body).attr('href', menu.attr('href'))
  3826 																  .attr('href', menu.attr('href'))
  4021 												 : body);
  3827 													: body);
       
  3828 				crumb.append(item);
  4022 				crumb.append(item);
  3829 			});
  4023 			});
  3830 		},
  4024 		},
  3831 
  4025 
  3832 		/**
  4026 		/**
  3837 			function updateActiveMenus(menu) {
  4031 			function updateActiveMenus(menu) {
  3838 				$('nav .active').removeClass('active');
  4032 				$('nav .active').removeClass('active');
  3839 				menu.addClass('open')
  4033 				menu.addClass('open')
  3840 					.addClass('active');
  4034 					.addClass('active');
  3841 				menu.parents('li').addClass('open active')
  4035 				menu.parents('li').addClass('open active')
  3842 								  .children('ul').addClass('active')
  4036 					.children('ul').addClass('active')
  3843 												 .show();
  4037 					.show();
  3844 				menu.parents('li:first').removeClass('open');
  4038 				menu.parents('li:first').removeClass('open');
  3845 				menu.parents('ul').addClass(menu.attr('href').replace(/^#/, '') ? 'active' : '')
  4039 				menu.parents('ul').addClass(menu.attr('href').replace(/^#/, '') ? 'active' : '')
  3846 								  .show();
  4040 					.show();
  3847 			}
  4041 			}
  3848 
  4042 
       
  4043 			var menu;
  3849 			var hash = location.hash;
  4044 			var hash = location.hash;
  3850 			var url = hash.replace(/^#/, '');
  4045 			var url = hash.replace(/^#/, '');
  3851 			if (url) {
  4046 			if (url) {
  3852 				var container = $('#content');
  4047 				var container = $('#content');
  3853 				if (!container.exists())
  4048 				if (!container.exists()) {
  3854 					container = $('body');
  4049 					container = $('body');
  3855 				var menu = $('nav A[href="' + hash + '"]');
  4050 				}
  3856 				if (menu.exists())
  4051 				menu = $('nav A[href="' + hash + '"]');
       
  4052 				if (menu.exists()) {
  3857 					updateActiveMenus(menu);
  4053 					updateActiveMenus(menu);
       
  4054 				}
  3858 				ams.skin.loadURL(url, container);
  4055 				ams.skin.loadURL(url, container);
  3859 				document.title = $('[data-ams-page-title]:first', container).data('ams-page-title') ||
  4056 				document.title = $('[data-ams-page-title]:first', container).data('ams-page-title') ||
  3860 								 menu.attr('title') ||
  4057 								 menu.attr('title') ||
  3861 								 document.title;
  4058 								 document.title;
  3862 			} else {
  4059 			} else {
  3866 				} else {
  4063 				} else {
  3867 					menu = $('nav >UL >LI >A[href!="#"]').first();
  4064 					menu = $('nav >UL >LI >A[href!="#"]').first();
  3868 				}
  4065 				}
  3869 				if (menu.exists()) {
  4066 				if (menu.exists()) {
  3870 					updateActiveMenus(menu);
  4067 					updateActiveMenus(menu);
  3871 					if (active_url)
  4068 					if (active_url) {
  3872 						ams.skin._drawBreadCrumb();
  4069 						ams.skin._drawBreadCrumb();
  3873 					else
  4070 					} else {
  3874 						window.location.hash = menu.attr('href');
  4071 						window.location.hash = menu.attr('href');
       
  4072 					}
  3875 				}
  4073 				}
  3876 			}
  4074 			}
  3877 		},
  4075 		},
  3878 
  4076 
  3879 		/**
  4077 		/**
  3886 		/**
  4084 		/**
  3887 		 * Register a callback which should be called before a container is replaced
  4085 		 * Register a callback which should be called before a container is replaced
  3888 		 */
  4086 		 */
  3889 		registerCleanCallback: function(callback) {
  4087 		registerCleanCallback: function(callback) {
  3890 			var callbacks = ams.skin._clean_callbacks;
  4088 			var callbacks = ams.skin._clean_callbacks;
  3891 			if (callbacks.indexOf(callback) < 0)
  4089 			if (callbacks.indexOf(callback) < 0) {
  3892 				callbacks.push(callback);
  4090 				callbacks.push(callback);
       
  4091 			}
  3893 		},
  4092 		},
  3894 
  4093 
  3895 		/**
  4094 		/**
  3896 		 * Call registered cleaning callbacks on given container
  4095 		 * Call registered cleaning callbacks on given container
  3897 		 */
  4096 		 */
  3898 		cleanContainer: function(container) {
  4097 		cleanContainer: function(container) {
  3899 			var callbacks = ams.skin._clean_callbacks;
  4098 			var callbacks = ams.skin._clean_callbacks;
  3900 			for (var index in callbacks) {
  4099 			for (var index=0; index < callbacks.length; index++) {
  3901 				callbacks[index].call(container);
  4100 				callbacks[index].call(container);
  3902 			}
  4101 			}
  3903 		},
  4102 		},
  3904 
  4103 
  3905 		/**
  4104 		/**
  3907 		 */
  4106 		 */
  3908 		loadURL: function(url, container, options, callback) {
  4107 		loadURL: function(url, container, options, callback) {
  3909 			if (url.startsWith('#')) {
  4108 			if (url.startsWith('#')) {
  3910 				url = url.substr(1);
  4109 				url = url.substr(1);
  3911 			}
  4110 			}
  3912 			if (typeof(options) == 'function') {
  4111 			if (typeof(options) === 'function') {
  3913 				callback = options;
  4112 				callback = options;
  3914 				options = {};
  4113 				options = {};
  3915 			}
  4114 			}
  3916 			container = $(container);
  4115 			container = $(container);
  3917 			var defaults = {
  4116 			var defaults = {
  3920 				dataType: 'html',
  4119 				dataType: 'html',
  3921 				cache: false,
  4120 				cache: false,
  3922 				beforeSend: function() {
  4121 				beforeSend: function() {
  3923 					ams.skin.cleanContainer(container);
  4122 					ams.skin.cleanContainer(container);
  3924 					container.html('<h1 class="loading"><i class="fa fa-cog fa-spin"></i> Loading... </h1>');
  4123 					container.html('<h1 class="loading"><i class="fa fa-cog fa-spin"></i> Loading... </h1>');
  3925 					if (container[0] == $('#content')[0]) {
  4124 					if (container[0] === $('#content')[0]) {
  3926 						ams.skin._drawBreadCrumb();
  4125 						ams.skin._drawBreadCrumb();
  3927 						document.title = $('.breadcrumb LI:last-child').text();
  4126 						document.title = $('.breadcrumb LI:last-child').text();
  3928 						$('html, body').animate({scrollTop: 0}, 'fast');
  4127 						$('html, body').animate({scrollTop: 0}, 'fast');
  3929 					} else {
  4128 					} else {
  3930 						container.animate({scrollTop: 0}, 'fast');
  4129 						container.animate({scrollTop: 0}, 'fast');
  3931 					}
  4130 					}
  3932 				},
  4131 				},
  3933 				success: function(data, status, request) {
  4132 				success: function(data, status, request) {
  3934 					if (callback)
  4133 					if (callback) {
  3935 						ams.executeFunctionByName(callback, this, data, status, request, options);
  4134 						ams.executeFunctionByName(callback, this, data, status, request, options);
  3936 					else {
  4135 					} else {
  3937 						var request_data = ams.ajax.getResponse(request);
  4136 						var request_data = ams.ajax.getResponse(request);
  3938 						var data_type = request_data.content_type;
  4137 						var data_type = request_data.content_type;
  3939 						var result = request_data.data;
  4138 						var result = request_data.data;
  3940 						$('.loading', container).remove();
  4139 						$('.loading', container).remove();
  3941 						switch (data_type) {
  4140 						switch (data_type) {
  3945 							case 'script':
  4144 							case 'script':
  3946 								break;
  4145 								break;
  3947 							case 'xml':
  4146 							case 'xml':
  3948 								break;
  4147 								break;
  3949 							case 'html':
  4148 							case 'html':
       
  4149 								/* falls through */
  3950 							case 'text':
  4150 							case 'text':
       
  4151 								/* falls through */
  3951 							default:
  4152 							default:
       
  4153 								// Show and init container
  3952 								container.parents('.hidden').removeClass('hidden');
  4154 								container.parents('.hidden').removeClass('hidden');
  3953 								$('.alert', container.parents('.alerts-container')).remove();
  4155 								$('.alert', container.parents('.alerts-container')).remove();
  3954 								container.css({opacity: '0.0'})
  4156 								container.css({opacity: '0.0'})
  3955 										 .html(data)
  4157 										 .html(data)
  3956 										 .removeClass('hidden')
  4158 										 .removeClass('hidden')
  3957 										 .delay(50)
  4159 										 .delay(50)
  3958 										 .animate({opacity: '1.0'}, 300);
  4160 										 .animate({opacity: '1.0'}, 300);
  3959 								ams.initContent(container);
  4161 								ams.initContent(container);
       
  4162 								// Set focus to first input
       
  4163 								var focused = $('[data-ams-focus-target]', container).first();
       
  4164 								if (!focused.exists()) {
       
  4165 									focused = $('input, select', container).first();
       
  4166 								}
       
  4167 								if (focused.exists()) {
       
  4168 									focused.focus();
       
  4169 								}
  3960 						}
  4170 						}
  3961 						if (options && options.afterLoadCallback) {
  4171 						if (options && options.afterLoadCallback) {
  3962 							ams.executeFunctionByName(options.afterLoadCallback, this);
  4172 							ams.executeFunctionByName(options.afterLoadCallback, this);
  3963 						}
  4173 						}
  3964 					}
  4174 					}
  4004 		}
  4214 		}
  4005 	};
  4215 	};
  4006 
  4216 
  4007 
  4217 
  4008 	/**
  4218 	/**
       
  4219 	 * Statistics management
       
  4220 	 */
       
  4221 	MyAMS.stats = {
       
  4222 
       
  4223 		/**
       
  4224 		 * Send event to Google Analytics platform
       
  4225 		 *
       
  4226 		 * @param category
       
  4227 		 * @param action
       
  4228 		 * @param label
       
  4229 		 */
       
  4230 		logEvent: function(category, action, label) {
       
  4231 			if (typeof(globals._gaq) === 'undefined') {
       
  4232 				return;
       
  4233 			}
       
  4234 			if (typeof(category) === 'object') {
       
  4235 				action = category.action;
       
  4236 				label = category.label;
       
  4237 				category = category.category;
       
  4238 			}
       
  4239 			globals._gaq.push(['_trackEvent', category, action, label]);
       
  4240 		}
       
  4241 	};
       
  4242 
       
  4243 
       
  4244 	/**
  4009 	 * Main page initialization
  4245 	 * Main page initialization
  4010 	 * This code is called only once to register global events and callbacks
  4246 	 * This code is called only once to register global events and callbacks
  4011 	 */
  4247 	 */
  4012 	MyAMS.initPage = function() {
  4248 	MyAMS.initPage = function() {
  4013 
  4249 
  4024 		$.ajaxSetup({
  4260 		$.ajaxSetup({
  4025 			progress: ams.ajax.progress,
  4261 			progress: ams.ajax.progress,
  4026 			progressUpload: ams.ajax.progress,
  4262 			progressUpload: ams.ajax.progress,
  4027 			xhr: function() {
  4263 			xhr: function() {
  4028 				var request = jquery_xhr();
  4264 				var request = jquery_xhr();
  4029 				if (request && (typeof(request.addEventListener) == "function")) {
  4265 				if (request && (typeof(request.addEventListener) === "function")) {
  4030 					var that = this;
  4266 					var that = this;
  4031 					request.addEventListener("progress", function(evt) {
  4267 					request.addEventListener("progress", function(evt) {
  4032 						that.progress(evt);
  4268 						that.progress(evt);
  4033 					}, false);
  4269 					}, false);
  4034 				}
  4270 				}
  4074 		ams.shortcuts.click(function(e) {
  4310 		ams.shortcuts.click(function(e) {
  4075 			ams.skin._hideShortcutButtons();
  4311 			ams.skin._hideShortcutButtons();
  4076 		});
  4312 		});
  4077 
  4313 
  4078 		$(document).mouseup(function(e) {
  4314 		$(document).mouseup(function(e) {
  4079 			if (!ams.shortcuts.is(e.target)
  4315 			if (!ams.shortcuts.is(e.target) &&
  4080 				&& ams.shortcuts.has(e.target).length === 0) {
  4316 				ams.shortcuts.has(e.target).length === 0) {
  4081 				ams.skin._hideShortcutButtons();
  4317 				ams.skin._hideShortcutButtons();
  4082 			}
  4318 			}
  4083 		});
  4319 		});
  4084 
  4320 
  4085 		// Show & hide mobile search field
  4321 		// Show & hide mobile search field
  4099 				dropdown.css('left', activity.position().left - dropdown.innerWidth() / 2 + activity.innerWidth() / 2)
  4335 				dropdown.css('left', activity.position().left - dropdown.innerWidth() / 2 + activity.innerWidth() / 2)
  4100 						.fadeIn(150);
  4336 						.fadeIn(150);
  4101 				activity.addClass('active');
  4337 				activity.addClass('active');
  4102 			} else {
  4338 			} else {
  4103 				dropdown.fadeOut(150);
  4339 				dropdown.fadeOut(150);
  4104 				activity.removeClass('active')
  4340 				activity.removeClass('active');
  4105 			}
  4341 			}
  4106 			e.preventDefault();
  4342 			e.preventDefault();
  4107 		});
  4343 		});
  4108 		ams.skin.checkNotification();
  4344 		ams.skin.checkNotification();
  4109 
  4345 
  4116 			}
  4352 			}
  4117 		});
  4353 		});
  4118 
  4354 
  4119 		$('input[name="activity"]').change(function() {
  4355 		$('input[name="activity"]').change(function() {
  4120 			var url = $(this).data('ams-url');
  4356 			var url = $(this).data('ams-url');
  4121 			container = $('.ajax-notifications');
  4357 			var container = $('.ajax-notifications');
  4122 			ams.skin.loadURL(url, container);
  4358 			ams.skin.loadURL(url, container);
  4123 		});
  4359 		});
  4124 
  4360 
  4125 		// Logout button
  4361 		// Logout button
  4126 		$('#logout a').click(function(e) {
  4362 		$('#logout a').click(function(e) {
  4133 				title : "<i class='fa fa-sign-out txt-color-orangeDark'></i> " + ams.i18n.LOGOUT +
  4369 				title : "<i class='fa fa-sign-out txt-color-orangeDark'></i> " + ams.i18n.LOGOUT +
  4134 						" <span class='txt-color-orangeDark'><strong>" + $('#show-shortcut').text() + "</strong></span> ?",
  4370 						" <span class='txt-color-orangeDark'><strong>" + $('#show-shortcut').text() + "</strong></span> ?",
  4135 				content : ams.i18n.LOGOUT_COMMENT,
  4371 				content : ams.i18n.LOGOUT_COMMENT,
  4136 				buttons : '['+ams.i18n.BTN_NO+']['+ams.i18n.BTN_YES+']'
  4372 				buttons : '['+ams.i18n.BTN_NO+']['+ams.i18n.BTN_YES+']'
  4137 			}, function(ButtonPressed) {
  4373 			}, function(ButtonPressed) {
  4138 				if (ButtonPressed == ams.i18n.BTN_YES) {
  4374 				if (ButtonPressed === ams.i18n.BTN_YES) {
  4139 					ams.root.addClass('animated fadeOutUp');
  4375 					ams.root.addClass('animated fadeOutUp');
  4140 					setTimeout(ams.skin.logout, 1000)
  4376 					setTimeout(ams.skin.logout, 1000);
  4141 				}
  4377 				}
  4142 			});
  4378 			});
  4143 		});
  4379 		});
  4144 
  4380 
  4145 		// Initialize left nav
  4381 		// Initialize left nav
  4160 			ams.skin.bigBox({
  4396 			ams.skin.bigBox({
  4161 				title: "<i class='fa fa-refresh' style='color: green'></i> " + ams.i18n.CLEAR_STORAGE_TITLE,
  4397 				title: "<i class='fa fa-refresh' style='color: green'></i> " + ams.i18n.CLEAR_STORAGE_TITLE,
  4162 				content: ams.i18n.CLEAR_STORAGE_CONTENT,
  4398 				content: ams.i18n.CLEAR_STORAGE_CONTENT,
  4163 				buttons: '['+ams.i18n.BTN_CANCEL+']['+ams.i18n.BTN_OK+']'
  4399 				buttons: '['+ams.i18n.BTN_CANCEL+']['+ams.i18n.BTN_OK+']'
  4164 			}, function(buttonPressed) {
  4400 			}, function(buttonPressed) {
  4165 				if (buttonPressed == ams.i18n.BTN_OK && localStorage) {
  4401 				if (buttonPressed === ams.i18n.BTN_OK && localStorage) {
  4166 					localStorage.clear();
  4402 					localStorage.clear();
  4167 					location.reload();
  4403 					location.reload();
  4168 				}
  4404 				}
  4169 			});
  4405 			});
  4170 			e.preventDefault();
  4406 			e.preventDefault();
  4173 		// Check active pop-overs
  4409 		// Check active pop-overs
  4174 		body.on('click', function(e) {
  4410 		body.on('click', function(e) {
  4175 			var element = $(this);
  4411 			var element = $(this);
  4176 			if (!element.is(e.target) &&
  4412 			if (!element.is(e.target) &&
  4177 				element.has(e.target).length === 0 &&
  4413 				element.has(e.target).length === 0 &&
  4178 				$('.popover').has(e.target).length === 0)
  4414 				$('.popover').has(e.target).length === 0) {
  4179 				element.popover('hide');
  4415 				element.popover('hide');
       
  4416 			}
  4180 		});
  4417 		});
  4181 
  4418 
  4182 		// Resize events
  4419 		// Resize events
  4183 		ams.ajax.check($.resize,
  4420 		ams.ajax.check($.resize,
  4184 					   ams.baseURL + 'ext/jquery-resize' + ams.devext + '.js',
  4421 					   ams.baseURL + 'ext/jquery-resize' + ams.devext + '.js',
  4198 				e.preventDefault();
  4435 				e.preventDefault();
  4199 			});
  4436 			});
  4200 			$(document).on('click', 'a[href!="#"]:not([data-toggle]), [data-ams-url]:not([data-toggle])', function(e) {
  4437 			$(document).on('click', 'a[href!="#"]:not([data-toggle]), [data-ams-url]:not([data-toggle])', function(e) {
  4201 				var link = $(e.currentTarget);
  4438 				var link = $(e.currentTarget);
  4202 				var href = link.attr('href') || link.data('ams-url');
  4439 				var href = link.attr('href') || link.data('ams-url');
  4203 				if (!href || href.startsWith('javascript:') || link.attr('target') || (link.data('ams-context-menu') === true))
  4440 				if (!href || href.startsWith('javascript') || link.attr('target') || (link.data('ams-context-menu') === true)) {
  4204 					return;
  4441 					return;
       
  4442 				}
  4205 				e.preventDefault();
  4443 				e.preventDefault();
  4206 				e.stopPropagation();
  4444 				e.stopPropagation();
  4207 				var href_getter = ams.getFunctionByName(href);
  4445 				var href_getter = ams.getFunctionByName(href);
  4208 				if (typeof(href_getter) == 'function') {
  4446 				if (typeof(href_getter) === 'function') {
  4209 					href = href_getter.call(link);
  4447 					href = href_getter.call(link);
  4210 				}
  4448 				}
  4211 				if (typeof(href) == 'function') {
  4449 				if (typeof(href) === 'function') {
  4212 					// Javascript function call
  4450 					// Javascript function call
  4213 					href.call(link);
  4451 					href.call(link);
  4214 				} else {
  4452 				} else {
  4215 					// Standard AJAX or browser URL call
  4453 					// Standard AJAX or browser URL call
  4216 					// Convert %23 chars to #
  4454 					// Convert %23 chars to #
  4221 							ams.skin.loadURL(href, target, link.data('ams-link-options'), link.data('ams-link-callback'));
  4459 							ams.skin.loadURL(href, target, link.data('ams-link-options'), link.data('ams-link-callback'));
  4222 						});
  4460 						});
  4223 					} else {
  4461 					} else {
  4224 						ams.form.confirmChangedForm(function () {
  4462 						ams.form.confirmChangedForm(function () {
  4225 							if (href.startsWith('#')) {
  4463 							if (href.startsWith('#')) {
  4226 								if (href != location.hash) {
  4464 								if (href !== location.hash) {
  4227 									if (ams.root.hasClass('mobile-view-activated')) {
  4465 									if (ams.root.hasClass('mobile-view-activated')) {
  4228 										ams.root.removeClass('hidden-menu');
  4466 										ams.root.removeClass('hidden-menu');
  4229 										window.setTimeout(function () {
  4467 										window.setTimeout(function () {
  4230 											window.location.hash = href;
  4468 											window.location.hash = href;
  4231 										}, 50);
  4469 										}, 50);
  4232 									} else
  4470 									} else {
  4233 										window.location.hash = href;
  4471 										window.location.hash = href;
       
  4472 									}
  4234 								}
  4473 								}
  4235 							} else
  4474 							} else {
  4236 								window.location = href;
  4475 								window.location = href;
       
  4476 							}
  4237 						});
  4477 						});
  4238 					}
  4478 					}
  4239 				}
  4479 				}
  4240 			});
  4480 			});
  4241 			$(document).on('click', 'a[target="_blank"]', function(e) {
  4481 			$(document).on('click', 'a[target="_blank"]', function(e) {
  4255 
  4495 
  4256 		// Initialize modal dialogs links
  4496 		// Initialize modal dialogs links
  4257 		$(document).off('click.modal')
  4497 		$(document).off('click.modal')
  4258 				   .on('click', '[data-toggle="modal"]', function(e) {
  4498 				   .on('click', '[data-toggle="modal"]', function(e) {
  4259 			var source = $(this);
  4499 			var source = $(this);
  4260 			if (source.data('ams-context-menu') === true)
  4500 			if (source.data('ams-context-menu') === true) {
  4261 				return;
  4501 				return;
  4262 			if (source.data('ams-stop-propagation') === true)
  4502 			}
       
  4503 			if (source.data('ams-stop-propagation') === true) {
  4263 				e.stopPropagation();
  4504 				e.stopPropagation();
       
  4505 			}
  4264 			e.preventDefault();
  4506 			e.preventDefault();
  4265 			ams.dialog.open(source);
  4507 			ams.dialog.open(source);
  4266 			if (source.parents('#shortcut').exists())
  4508 			if (source.parents('#shortcut').exists()) {
  4267 				setTimeout(ams.skin._hideShortcutButtons, 300);
  4509 				setTimeout(ams.skin._hideShortcutButtons, 300);
       
  4510 			}
  4268 		});
  4511 		});
  4269 
  4512 
  4270 		// Initialize form buttons
  4513 		// Initialize form buttons
  4271 		$(document).on('click', 'button[type="submit"], button.submit', function() {
  4514 		$(document).on('click', 'button[type="submit"], button.submit', function() {
  4272 			var button = $(this);
  4515 			var button = $(this);
  4276 		// Initialize custom click handlers
  4519 		// Initialize custom click handlers
  4277 		$(document).on('click', '[data-ams-click-handler]', function(e) {
  4520 		$(document).on('click', '[data-ams-click-handler]', function(e) {
  4278 			var source = $(this);
  4521 			var source = $(this);
  4279 			var data = source.data();
  4522 			var data = source.data();
  4280 			if (data.amsClickHandler) {
  4523 			if (data.amsClickHandler) {
  4281 				if ((data.amsStopPropagation === true) || (data.amsClickStopPropagation === true))
  4524 				if ((data.amsStopPropagation === true) || (data.amsClickStopPropagation === true)) {
  4282 					e.stopPropagation();
  4525 					e.stopPropagation();
  4283 				if (data.amsClickKeepDefault !== true)
  4526 				}
       
  4527 				if (data.amsClickKeepDefault !== true) {
  4284 					e.preventDefault();
  4528 					e.preventDefault();
       
  4529 				}
  4285 				var callback = ams.getFunctionByName(data.amsClickHandler);
  4530 				var callback = ams.getFunctionByName(data.amsClickHandler);
  4286 				if (callback !== undefined)
  4531 				if (callback !== undefined) {
  4287 					callback.call(source, data.amsClickHandlerOptions);
  4532 					callback.call(source, data.amsClickHandlerOptions);
       
  4533 				}
  4288 			}
  4534 			}
  4289 		});
  4535 		});
  4290 
  4536 
  4291 		// Initialize custom change handlers
  4537 		// Initialize custom change handlers
  4292 		$(document).on('change', '[data-ams-change-handler]', function(e) {
  4538 		$(document).on('change', '[data-ams-change-handler]', function(e) {
  4293 			var source = $(this);
  4539 			var source = $(this);
  4294 			var data = source.data();
  4540 			var data = source.data();
  4295 			if (data.amsChangeHandler) {
  4541 			if (data.amsChangeHandler) {
  4296 				if (data.amsChangeKeepDefault !== true)
  4542 				if (data.amsChangeKeepDefault !== true) {
  4297 					e.preventDefault();
  4543 					e.preventDefault();
       
  4544 				}
  4298 				var callback = ams.getFunctionByName(data.amsChangeHandler);
  4545 				var callback = ams.getFunctionByName(data.amsChangeHandler);
  4299 				if (callback !== undefined)
  4546 				if (callback !== undefined) {
  4300 					callback.call(source, data.amsChangeHandlerOptions);
  4547 					callback.call(source, data.amsChangeHandlerOptions);
       
  4548 				}
  4301 			}
  4549 			}
  4302 		});
  4550 		});
  4303 
  4551 
  4304 		// Notify reset to update Select2 widgets
  4552 		// Notify reset to update Select2 widgets
  4305 		$(document).on('reset', 'form', function(e) {
  4553 		$(document).on('reset', 'form', function(e) {
  4306 			var form = $(this);
  4554 			var form = $(this);
  4307 			setTimeout(function() {
  4555 			setTimeout(function() {
  4308 				form.find('.select2').trigger('change');
  4556 				form.find('.select2').trigger('change');
  4309 			}, 10);
  4557 			}, 10);
       
  4558 			// Set focus to first input
       
  4559 			var focused = $('[data-ams-focus-target]', form).first();
       
  4560 			if (!focused.exists()) {
       
  4561 				focused = $('input, select', form).first();
       
  4562 			}
       
  4563 			if (focused.exists()) {
       
  4564 				focused.focus();
       
  4565 			}
  4310 		});
  4566 		});
  4311 
  4567 
  4312 		// Initialize custom reset handlers
  4568 		// Initialize custom reset handlers
  4313 		$(document).on('reset', '[data-ams-reset-handler]', function(e) {
  4569 		$(document).on('reset', '[data-ams-reset-handler]', function(e) {
  4314 			var form = $(this);
  4570 			var form = $(this);
  4315 			var data = form.data();
  4571 			var data = form.data();
  4316 			if (data.amsResetHandler) {
  4572 			if (data.amsResetHandler) {
  4317 				if (data.amsResetKeepDefault !== true)
  4573 				if (data.amsResetKeepDefault !== true) {
  4318 					e.preventDefault();
  4574 					e.preventDefault();
       
  4575 				}
  4319 				var callback = ams.getFunctionByName(data.amsResetHandler);
  4576 				var callback = ams.getFunctionByName(data.amsResetHandler);
  4320 				if (callback !== undefined)
  4577 				if (callback !== undefined) {
  4321 					callback.call(form, data.amsResetHandlerOptions);
  4578 					callback.call(form, data.amsResetHandlerOptions);
       
  4579 				}
  4322 			}
  4580 			}
  4323 		});
  4581 		});
  4324 
  4582 
  4325 		// Handle update on file upload placeholder
  4583 		// Handle update on file upload placeholder
  4326 		$(document).on('change', 'input[type="file"]', function(e) {
  4584 		$(document).on('change', 'input[type="file"]', function(e) {
  4350 		// Enable tabs dynamic loading
  4608 		// Enable tabs dynamic loading
  4351 		$(document).on('show.bs.tab', function(e) {
  4609 		$(document).on('show.bs.tab', function(e) {
  4352 			var link = $(e.target);
  4610 			var link = $(e.target);
  4353 			var data = link.data();
  4611 			var data = link.data();
  4354 			if (data.amsUrl) {
  4612 			if (data.amsUrl) {
  4355 				if (data.amsTabLoaded)
  4613 				if (data.amsTabLoaded) {
  4356 					return;
  4614 					return;
       
  4615 				}
  4357 				try {
  4616 				try {
  4358 					link.append('<i class="fa fa-spin fa-cog margin-left-5"></i>');
  4617 					link.append('<i class="fa fa-spin fa-cog margin-left-5"></i>');
  4359 					ams.skin.loadURL(data.amsUrl, link.attr('href'));
  4618 					ams.skin.loadURL(data.amsUrl, link.attr('href'));
  4360 					if (data.amsTabLoadOnce)
  4619 					if (data.amsTabLoadOnce) {
  4361 						link.data('ams-tab-loaded', true);
  4620 						link.data('ams-tab-loaded', true);
       
  4621 					}
  4362 				}
  4622 				}
  4363 				finally {
  4623 				finally {
  4364 					$('i', link).remove();
  4624 					$('i', link).remove();
  4365 				}
  4625 				}
  4366 			}
  4626 			}
  4367 		});
  4627 		});
  4368 
  4628 
  4369 		// Init page content
  4629 		// Init page content
  4370 		ams.initContent(document);
  4630 		ams.initContent(document);
  4371 		if (ams.ajax_nav && $('nav').exists())
  4631 		if (ams.ajax_nav && $('nav').exists()) {
  4372 			ams.skin.checkURL();
  4632 			ams.skin.checkURL();
       
  4633 		}
  4373 
  4634 
  4374 		// Add unload event listener to check for modified forms
  4635 		// Add unload event listener to check for modified forms
  4375 		$(window).on('beforeunload', ams.form.checkBeforeUnload);
  4636 		$(window).on('beforeunload', ams.form.checkBeforeUnload);
  4376 
  4637 
  4377 	};
  4638 	};
  4401 		ams.callbacks.init(element);
  4662 		ams.callbacks.init(element);
  4402 		ams.events.init(element);
  4663 		ams.events.init(element);
  4403 		ams.form.init(element);
  4664 		ams.form.init(element);
  4404 
  4665 
  4405 		// Initialize widgets
  4666 		// Initialize widgets
  4406 		if (ams.device === 'desktop')
  4667 		if (ams.device === 'desktop') {
  4407 			ams.skin._initDesktopWidgets(element);
  4668 			ams.skin._initDesktopWidgets(element);
  4408 		else
  4669 		} else {
  4409 			ams.skin._initMobileWidgets(element);
  4670 			ams.skin._initMobileWidgets(element);
       
  4671 		}
  4410 		ams.skin._setPageHeight();
  4672 		ams.skin._setPageHeight();
  4411 
  4673 
  4412 	};
  4674 	};
  4413 
  4675 
  4414 
  4676 
  4483 		} else {
  4745 		} else {
  4484 			MyAMS.initPage();
  4746 			MyAMS.initPage();
  4485 		}
  4747 		}
  4486 	});
  4748 	});
  4487 
  4749 
  4488 })(jQuery);
  4750 })(jQuery, this);