src/ztfy/myams/resources/js/myams.js
changeset 180 172ddcb92995
parent 178 2c3ba8d90123
child 182 681edeb5c6ef
equal deleted inserted replaced
179:a36bac847ea7 180:172ddcb92995
    55 				}
    55 				}
    56 			}
    56 			}
    57 			return -1;
    57 			return -1;
    58 		};
    58 		};
    59 	}
    59 	}
       
    60 
       
    61 
       
    62 	/**
       
    63 	 * JQuery 'hasvalue' expression
       
    64 	 * Filter inputs containing value
       
    65 	 */
       
    66 	$.expr[":"].hasvalue =  function(obj, index, meta /*, stack*/) {
       
    67 		return $(obj).val() !== "";
       
    68 	};
    60 
    69 
    61 
    70 
    62 	/**
    71 	/**
    63 	 * JQuery 'econtains' expression
    72 	 * JQuery 'econtains' expression
    64 	 * Case insensitive contains expression
    73 	 * Case insensitive contains expression
   214 												top: getMenuPosition(e.clientY, 'height', 'scrollTop') - 10
   223 												top: getMenuPosition(e.clientY, 'height', 'scrollTop') - 10
   215 											})
   224 											})
   216 											.off('click')
   225 											.off('click')
   217 											.on('click', function (e) {
   226 											.on('click', function (e) {
   218 												$(this).hide();
   227 												$(this).hide();
   219 												var $invokedOn = $(this).data("invokedOn");
   228 												var invokedOn = $(this).data("invokedOn");
   220 												var $selectedMenu = $(e.target);
   229 												var selectedMenu = $(e.target);
   221 												settings.menuSelected.call(this, $invokedOn, $selectedMenu);
   230 												settings.menuSelected.call(this, invokedOn, selectedMenu);
   222 												ams.event.stop(e);
   231 												ams.event.stop(e);
   223 											});
   232 											});
   224 					return false;
   233 					return false;
   225 				});
   234 				});
   226 
   235 
   247 			// Assign current element to variable, in this case is UL element
   256 			// Assign current element to variable, in this case is UL element
   248 			var menu = $(this);
   257 			var menu = $(this);
   249 
   258 
   250 			// Add a mark [+] to a multilevel menu
   259 			// Add a mark [+] to a multilevel menu
   251 			menu.find("LI").each(function() {
   260 			menu.find("LI").each(function() {
   252 				var menu_item = $(this);
   261 				var menuItem = $(this);
   253 				if (menu_item.find("UL").size() > 0) {
   262 				if (menuItem.find("UL").size() > 0) {
   254 
   263 
   255 					// add the multilevel sign next to the link
   264 					// add the multilevel sign next to the link
   256 					menu_item.find("A:first")
   265 					menuItem.find("A:first")
   257 							 .append("<b class='collapse-sign'>" + settings.closedSign + "</b>");
   266 							 .append("<b class='collapse-sign'>" + settings.closedSign + "</b>");
   258 
   267 
   259 					// avoid jumping to the top of the page when the href is an #
   268 					// avoid jumping to the top of the page when the href is an #
   260 					var first_link = menu_item.find("A:first");
   269 					var firstLink = menuItem.find("A:first");
   261 					if (first_link.attr('href') === "#") {
   270 					if (firstLink.attr('href') === "#") {
   262 						first_link.click(function() {
   271 						firstLink.click(function() {
   263 							return false;
   272 							return false;
   264 						});
   273 						});
   265 					}
   274 					}
   266 				}
   275 				}
   267 			});
   276 			});
   268 
   277 
   269 			// Open active level
   278 			// Open active level
   270 			menu.find("LI.active").each(function() {
   279 			menu.find("LI.active").each(function() {
   271 				var active_parent = $(this).parents('UL');
   280 				var activeParent = $(this).parents('UL');
   272 				var active_item = active_parent.parent('LI');
   281 				var activeItem = activeParent.parent('LI');
   273 				active_parent.slideDown(settings.speed);
   282 				activeParent.slideDown(settings.speed);
   274 				active_item.find("b:first").html(settings.openedSign);
   283 				activeItem.find("b:first").html(settings.openedSign);
   275 				active_item.addClass("open");
   284 				activeItem.addClass("open");
   276 			});
   285 			});
   277 
   286 
   278 			menu.find("LI A").on('click', function() {
   287 			menu.find("LI A").on('click', function() {
   279 				var link = $(this);
   288 				var link = $(this);
   280 				if (link.hasClass('active')) {
   289 				if (link.hasClass('active')) {
   281 					return;
   290 					return;
   282 				}
   291 				}
   283 				var href = link.attr('href').replace(/^#/,'');
   292 				var href = link.attr('href').replace(/^#/,'');
   284 				var parent_ul = link.parent().find("UL");
   293 				var parentUL = link.parent().find("UL");
   285 				if (settings.accordion) {
   294 				if (settings.accordion) {
   286 					var parents = link.parent().parents("UL");
   295 					var parents = link.parent().parents("UL");
   287 					var visible = menu.find("UL:visible");
   296 					var visible = menu.find("UL:visible");
   288 					visible.each(function(visibleIndex) {
   297 					visible.each(function(visibleIndex) {
   289 						var close = true;
   298 						var close = true;
   292 								close = false;
   301 								close = false;
   293 								return false;
   302 								return false;
   294 							}
   303 							}
   295 						});
   304 						});
   296 						if (close) {
   305 						if (close) {
   297 							if (parent_ul !== visible[visibleIndex]) {
   306 							if (parentUL !== visible[visibleIndex]) {
   298 								var visibleItem = $(visible[visibleIndex]);
   307 								var visibleItem = $(visible[visibleIndex]);
   299 								if (href || !visibleItem.hasClass('active')) {
   308 								if (href || !visibleItem.hasClass('active')) {
   300 									visibleItem.slideUp(settings.speed, function () {
   309 									visibleItem.slideUp(settings.speed, function () {
   301 										$(this).parent("LI")
   310 										$(this).parent("LI")
   302 											.removeClass('open')
   311 											   .removeClass('open')
   303 											.find("B:first")
   312 											   .find("B:first")
   304 											.delay(settings.speed)
   313 											   .delay(settings.speed)
   305 											.html(settings.closedSign);
   314 											   .html(settings.closedSign);
   306 									});
   315 									});
   307 								}
   316 								}
   308 							}
   317 							}
   309 						}
   318 						}
   310 					});
   319 					});
   311 				}
   320 				}
   312 				var first_ul = link.parent().find("UL:first");
   321 				var firstUL = link.parent().find("UL:first");
   313 				if (!href && first_ul.is(":visible") && !first_ul.hasClass("active")) {
   322 				if (!href && firstUL.is(":visible") && !firstUL.hasClass("active")) {
   314 					first_ul.slideUp(settings.speed, function() {
   323 					firstUL.slideUp(settings.speed, function() {
   315 						link.parent("LI")
   324 						link.parent("LI")
   316 							.removeClass("open")
   325 							.removeClass("open")
   317 							.find("B:first")
   326 							.find("B:first")
   318 							.delay(settings.speed)
   327 							.delay(settings.speed)
   319 							.html(settings.closedSign);
   328 							.html(settings.closedSign);
   320 					});
   329 					});
   321 				} else /*if (link.attr('href') !== location.hash)*/ {
   330 				} else /*if (link.attr('href') !== location.hash)*/ {
   322 					first_ul.slideDown(settings.speed, function() {
   331 					firstUL.slideDown(settings.speed, function() {
   323 						link.parent("LI")
   332 						link.parent("LI")
   324 							.addClass("open")
   333 							.addClass("open")
   325 							.find("B:first")
   334 							.find("B:first")
   326 							.delay(settings.speed)
   335 							.delay(settings.speed)
   327 							.html(settings.openedSign);
   336 							.html(settings.openedSign);
   402 	if (globals.MyAMS === undefined) {
   411 	if (globals.MyAMS === undefined) {
   403 		globals.MyAMS = {
   412 		globals.MyAMS = {
   404 			devmode: true,
   413 			devmode: true,
   405 			devext: '',
   414 			devext: '',
   406 			lang: 'en',
   415 			lang: 'en',
   407 			throttle_delay: 350,
   416 			throttleDelay: 350,
   408 			menu_speed: 235,
   417 			menuSpeed: 235,
   409 			navbar_height: 49,
   418 			navbarHeight: 49,
   410 			ajax_nav: true,
   419 			ajaxNav: true,
   411 			enable_widgets: true,
   420 			enableWidgets: true,
   412 			enable_mobile: false,
   421 			enableMobile: false,
   413 			enable_fastclick: false,
   422 			enableFastclick: false,
   414 			warn_on_form_change: false,
   423 			warnOnFormChange: false,
   415 			ismobile: (/iphone|ipad|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase()))
   424 			ismobile: (/iphone|ipad|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase()))
   416 		};
   425 		};
   417 	}
   426 	}
   418 	var MyAMS = globals.MyAMS;
   427 	var MyAMS = globals.MyAMS;
   419 	var ams = MyAMS;
   428 	var ams = MyAMS;
   659 		 */
   668 		 */
   660 		ajax: function(event, response, request, error) {
   669 		ajax: function(event, response, request, error) {
   661 			if (response.statusText === 'OK') {
   670 			if (response.statusText === 'OK') {
   662 				return;
   671 				return;
   663 			}
   672 			}
   664 			var ajax_response = ams.ajax.getResponse(response);
   673 			var response = ams.ajax.getResponse(response);
   665 			if (ajax_response.content_type === 'json') {
   674 			if (response.contentType === 'json') {
   666 				ams.ajax.handleJSON(ajax_response.data);
   675 				ams.ajax.handleJSON(response.data);
   667 			} else {
   676 			} else {
   668 				var title = event.statusText || event.type;
   677 				var title = event.statusText || event.type;
   669 				var message = response.responseText;
   678 				var message = response.responseText;
   670 				ams.skin.messageBox('error', {
   679 				ams.skin.messageBox('error', {
   671 					title: ams.i18n.ERROR_OCCURED,
   680 					title: ams.i18n.ERROR_OCCURED,
   686 		show: function(request, status, error) {
   695 		show: function(request, status, error) {
   687 			if (!error) {
   696 			if (!error) {
   688 				return;
   697 				return;
   689 			}
   698 			}
   690 			var response = ams.ajax.getResponse(request);
   699 			var response = ams.ajax.getResponse(request);
   691 			if (response.content_type === 'json') {
   700 			if (response.contentType === 'json') {
   692 				ams.ajax.handleJSON(response.data);
   701 				ams.ajax.handleJSON(response.data);
   693 			} else {
   702 			} else {
   694 				ams.skin.messageBox('error', {
   703 				ams.skin.messageBox('error', {
   695 					title: ams.i18n.ERRORS_OCCURED,
   704 					title: ams.i18n.ERRORS_OCCURED,
   696 					content: '<h4>' + status + '</h4><p>' + error + '</p>',
   705 					content: '<h4>' + status + '</h4><p>' + error + '</p>',
   767 
   776 
   768 		/**
   777 		/**
   769 		 * Handle AJAX upload and download progress
   778 		 * Handle AJAX upload and download progress
   770 		 *
   779 		 *
   771 		 * @param event: the source event
   780 		 * @param event: the source event
   772 		 * @param request: the request
       
   773 		 * @param options: AJAX options
       
   774 		 */
   781 		 */
   775 		progress: function(event) {
   782 		progress: function(event) {
   776 			if (!event.lengthComputable) {
   783 			if (!event.lengthComputable) {
   777 				return;
   784 				return;
   778 			}
   785 			}
   827 
   834 
   828 		/**
   835 		/**
   829 		 * Extract data type and result from response
   836 		 * Extract data type and result from response
   830 		 */
   837 		 */
   831 		getResponse: function(request) {
   838 		getResponse: function(request) {
   832 			var content_type = request.getResponseHeader('content-type'),
   839 			var contentType = request.getResponseHeader('content-type'),
   833 				data_type,
   840 				dataType,
   834 				result;
   841 				result;
   835 			if (content_type) {
   842 			if (contentType) {
   836 				// Got server response
   843 				// Got server response
   837 				if (content_type.startsWith('application/javascript')) {
   844 				if (contentType.startsWith('application/javascript')) {
   838 					data_type = 'script';
   845 					dataType = 'script';
   839 					result = request.responseText;
   846 					result = request.responseText;
   840 				} else if (content_type.startsWith('text/html')) {
   847 				} else if (contentType.startsWith('text/html')) {
   841 					data_type = 'html';
   848 					dataType = 'html';
   842 					result = request.responseText;
   849 					result = request.responseText;
   843 				} else if (content_type.startsWith('text/xml')) {
   850 				} else if (contentType.startsWith('text/xml')) {
   844 					data_type = 'xml';
   851 					dataType = 'xml';
   845 					result = request.responseText;
   852 					result = request.responseText;
   846 				} else {
   853 				} else {
   847 					result = request.responseJSON;
   854 					result = request.responseJSON;
   848 					if (result) {
   855 					if (result) {
   849 						data_type = 'json';
   856 						dataType = 'json';
   850 					} else {
   857 					} else {
   851 						try {
   858 						try {
   852 							result = JSON.parse(request.responseText);
   859 							result = JSON.parse(request.responseText);
   853 							data_type = 'json';
   860 							dataType = 'json';
   854 						} catch (e) {
   861 						} catch (e) {
   855 							result = request.responseText;
   862 							result = request.responseText;
   856 							data_type = 'text';
   863 							dataType = 'text';
   857 						}
   864 						}
   858 					}
   865 					}
   859 				}
   866 				}
   860 			} else {
   867 			} else {
   861 				// Probably no response from server...
   868 				// Probably no response from server...
   862 				data_type = 'json';
   869 				dataType = 'json';
   863 				result = {
   870 				result = {
   864 					status: 'alert',
   871 					status: 'alert',
   865 					alert: {
   872 					alert: {
   866 						title: ams.i18n.ERROR_OCCURED,
   873 						title: ams.i18n.ERROR_OCCURED,
   867 						content: ams.i18n.NO_SERVER_RESPONSE
   874 						content: ams.i18n.NO_SERVER_RESPONSE
   868 					}
   875 					}
   869 				};
   876 				};
   870 			}
   877 			}
   871 			return {content_type: data_type,
   878 			return {contentType: dataType,
   872 					data: result};
   879 					data: result};
   873 		},
   880 		},
   874 
   881 
   875 		/**
   882 		/**
   876 		 * Handle server response in JSON format
   883 		 * Handle server response in JSON format
  1027 											title: ams.i18n.ERROR_OCCURED,
  1034 											title: ams.i18n.ERROR_OCCURED,
  1028 											content: message,
  1035 											content: message,
  1029 											timeout: 10000
  1036 											timeout: 10000
  1030 										});
  1037 										});
  1031 				} else {
  1038 				} else {
  1032 					var message_status = message.status || 'info';
  1039 					var messageStatus = message.status || 'info';
  1033 					if (message_status === 'error' && form && target) {
  1040 					if (messageStatus === 'error' && form && target) {
  1034 						ams.executeFunctionByName(form.data('ams-form-submit-error') || 'MyAMS.form.finalizeSubmitOnError', form, target);
  1041 						ams.executeFunctionByName(form.data('ams-form-submit-error') || 'MyAMS.form.finalizeSubmitOnError', form, target);
  1035 					}
  1042 					}
  1036 					ams.skin.messageBox(message_status,
  1043 					ams.skin.messageBox(messageStatus,
  1037 										{title: message.title || ams.i18n.ERROR_OCCURED,
  1044 										{title: message.title || ams.i18n.ERROR_OCCURED,
  1038 										 content: message.content,
  1045 										 content: message.content,
  1039 										 icon: message.icon,
  1046 										 icon: message.icon,
  1040 										 number: message.number,
  1047 										 number: message.number,
  1041 										 timeout: message.timeout === null ? undefined : (message.timeout || 10000)});
  1048 										 timeout: message.timeout === null ? undefined : (message.timeout || 10000)});
  1246 		 * @param element: the parent element
  1253 		 * @param element: the parent element
  1247 		 */
  1254 		 */
  1248 		init: function(element) {
  1255 		init: function(element) {
  1249 			// Activate form changes if required
  1256 			// Activate form changes if required
  1250 			var forms;
  1257 			var forms;
  1251 			if (ams.warn_on_form_change) {
  1258 			if (ams.warnOnFormChange) {
  1252 				forms = $('FORM[data-ams-warn-on-change!="false"]', element);
  1259 				forms = $('FORM[data-ams-warn-on-change!="false"]', element);
  1253 			} else {
  1260 			} else {
  1254 				forms = $('FORM[data-ams-warn-on-change="true"]', element);
  1261 				forms = $('FORM[data-ams-warn-on-change="true"]', element);
  1255 			}
  1262 			}
  1256 			forms.each(function() {
  1263 			forms.each(function() {
  1357 		},
  1364 		},
  1358 
  1365 
  1359 		/**
  1366 		/**
  1360 		 * Submit given form
  1367 		 * Submit given form
  1361 		 */
  1368 		 */
  1362 		submit: function(form, handler, submit_options) {
  1369 		submit: function(form, handler, submitOptions) {
  1363 			// Check params
  1370 			// Check params
  1364 			form = $(form);
  1371 			form = $(form);
  1365 			if (!form.exists()) {
  1372 			if (!form.exists()) {
  1366 				return false;
  1373 				return false;
  1367 			}
  1374 			}
  1368 			if (typeof(handler) === 'object') {
  1375 			if (typeof(handler) === 'object') {
  1369 				submit_options = handler;
  1376 				submitOptions = handler;
  1370 				handler = undefined;
  1377 				handler = undefined;
  1371 			}
  1378 			}
  1372 			// Prevent multiple submits of the same form
  1379 			// Prevent multiple submits of the same form
  1373 			if (form.data('submitted')) {
  1380 			if (form.data('submitted')) {
  1374 				if (!form.data('ams-form-hide-submitted')) {
  1381 				if (!form.data('ams-form-hide-submitted')) {
  1398 						   function() {
  1405 						   function() {
  1399 
  1406 
  1400 								function _submitAjaxForm(form, options) {
  1407 								function _submitAjaxForm(form, options) {
  1401 
  1408 
  1402 									var button,
  1409 									var button,
  1403 										button_data,
  1410 										buttonData,
  1404 										button_target;
  1411 										buttonTarget;
  1405 									var data = form.data();
  1412 									var data = form.data();
  1406 									var form_options = data.amsFormOptions;
  1413 									var formOptions = data.amsFormOptions;
  1407 									var form_data;
  1414 									var formData;
  1408 									var form_data_callback;
  1415 									var formDataCallback;
  1409 
  1416 
  1410 									var progress_handler;
  1417 									var progressHandler;
  1411 									var progress_interval;
  1418 									var progressInterval;
  1412 									var progress_callback;
  1419 									var progressCallback;
  1413 									var progress_end_callback;
  1420 									var progressEndCallback;
  1414 
  1421 
  1415 									// Inner progress status handler
  1422 									// Inner progress status handler
  1416 									function _getProgress(handler, progress_id) {
  1423 									function _getProgress(handler, progress_id) {
  1417 
  1424 
  1418 										var interval;
  1425 										var interval;
  1419 
  1426 
  1420 										function _clearProgressStatus() {
  1427 										function _clearProgressStatus() {
  1421 											button.button('reset');
  1428 											button.button('reset');
  1422 											clearInterval(interval);
  1429 											clearInterval(interval);
  1423 											ams.executeFunctionByName(progress_end_callback, form, button);
  1430 											ams.executeFunctionByName(progressEndCallback, form, button);
  1424 										}
  1431 										}
  1425 
  1432 
  1426 										function _getProgressStatus() {
  1433 										function _getProgressStatus() {
  1427 											ams.ajax.post(handler,
  1434 											ams.ajax.post(handler,
  1428 														  {progress_id: progress_id},
  1435 														  {progress_id: progress_id},
  1429 														  {error: _clearProgressStatus},
  1436 														  {error: _clearProgressStatus},
  1430 														  ams.getFunctionByName(progress_callback) || function(result, status) {
  1437 														  ams.getFunctionByName(progressCallback) || function(result, status) {
  1431 															if (status == 'success') {
  1438 															if (status == 'success') {
  1432 																if (result.status === 'running') {
  1439 																if (result.status === 'running') {
  1433 																	if (result.message) {
  1440 																	if (result.message) {
  1434 																		button.text(result.message);
  1441 																		button.text(result.message);
  1435 																	} else {
  1442 																	} else {
  1444 															}
  1451 															}
  1445 														  });
  1452 														  });
  1446 										}
  1453 										}
  1447 
  1454 
  1448 										button.button('loading');
  1455 										button.button('loading');
  1449 										interval = setInterval(_getProgressStatus, progress_interval);
  1456 										interval = setInterval(_getProgressStatus, progressInterval);
  1450 									}
  1457 									}
  1451 
  1458 
  1452 									// Initialize form data
  1459 									// Initialize form data
  1453 									if (submit_options) {
  1460 									if (submitOptions) {
  1454 										form_data_callback = submit_options.formDataInitCallback;
  1461 										formDataCallback = submitOptions.formDataInitCallback;
  1455 									}
  1462 									}
  1456 									if (form_data_callback) {
  1463 									if (formDataCallback) {
  1457 										delete submit_options.formDataInitCallback;
  1464 										delete submitOptions.formDataInitCallback;
  1458 									} else {
  1465 									} else {
  1459 										form_data_callback = data.amsFormDataInitCallback;
  1466 										formDataCallback = data.amsFormDataInitCallback;
  1460 									}
  1467 									}
  1461 									if (form_data_callback) {
  1468 									if (formDataCallback) {
  1462 										var veto = {};
  1469 										var veto = {};
  1463 										if (typeof(form_data_callback) === 'function') {
  1470 										if (typeof(formDataCallback) === 'function') {
  1464 											form_data = form_data_callback.call(form, veto);
  1471 											formData = formDataCallback.call(form, veto);
  1465 										} else {
  1472 										} else {
  1466 											form_data = ams.executeFunctionByName(form_data_callback, form, veto);
  1473 											formData = ams.executeFunctionByName(formDataCallback, form, veto);
  1467 										}
  1474 										}
  1468 										if (veto.veto) {
  1475 										if (veto.veto) {
  1469 											button = form.data('ams-submit-button');
  1476 											button = form.data('ams-submit-button');
  1470 											if (button) {
  1477 											if (button) {
  1471 												button.button('reset');
  1478 												button.button('reset');
  1472 											}
  1479 											}
  1473 											ams.form.finalizeSubmitFooter.call(form);
  1480 											ams.form.finalizeSubmitFooter.call(form);
  1474 											return false;
  1481 											return false;
  1475 										}
  1482 										}
  1476 									} else {
  1483 									} else {
  1477 										form_data = data.amsFormData || {};
  1484 										formData = data.amsFormData || {};
  1478 									}
  1485 									}
  1479 
  1486 
  1480 									// Check submit button for custom action handler and target
  1487 									// Check submit button for custom action handler and target
  1481 									button = $(form.data('ams-submit-button'));
  1488 									button = $(form.data('ams-submit-button'));
  1482 									if (button && button.exists()) {
  1489 									if (button && button.exists()) {
  1483 										button_data = button.data();
  1490 										buttonData = button.data();
  1484 										button_target = button_data.amsFormSubmitTarget;
  1491 										buttonTarget = buttonData.amsFormSubmitTarget;
  1485 									} else {
  1492 									} else {
  1486 										button_data = {};
  1493 										buttonData = {};
  1487 									}
  1494 									}
  1488 
  1495 
  1489 									// Check action URL
  1496 									// Check action URL
  1490 									var url;
  1497 									var url;
  1491 									var form_handler = handler || button_data.amsFormHandler || data.amsFormHandler || '';
  1498 									var formHandler = handler || buttonData.amsFormHandler || data.amsFormHandler || '';
  1492 									if (form_handler.startsWith(window.location.protocol)) {
  1499 									if (formHandler.startsWith(window.location.protocol)) {
  1493 										url = form_handler;
  1500 										url = formHandler;
  1494 									} else {
  1501 									} else {
  1495 										var action = button_data.amsFormAction || form.attr('action').replace(/#/, '');
  1502 										var action = buttonData.amsFormAction || form.attr('action').replace(/#/, '');
  1496 										if (action.startsWith(window.location.protocol)) {
  1503 										if (action.startsWith(window.location.protocol)) {
  1497 											url = action;
  1504 											url = action;
  1498 										} else {
  1505 										} else {
  1499 											url = ams.ajax.getAddr() + action;
  1506 											url = ams.ajax.getAddr() + action;
  1500 										}
  1507 										}
  1501 										url += form_handler;
  1508 										url += formHandler;
  1502 									}
  1509 									}
  1503 									progress_handler = button_data.amsProgressHandler || data.amsProgressHandler || '';
  1510 									progressHandler = buttonData.amsProgressHandler || data.amsProgressHandler || '';
  1504 									progress_interval = button_data.amsProgressInterval || data.amsProgressInterval || 1000;
  1511 									progressInterval = buttonData.amsProgressInterval || data.amsProgressInterval || 1000;
  1505 									progress_callback = button_data.amsProgressCallback || data.amsProgressCallback;
  1512 									progressCallback = buttonData.amsProgressCallback || data.amsProgressCallback;
  1506 									progress_end_callback = button_data.amsProgressEndCallback || data.amsProgressEndCallback;
  1513 									progressEndCallback = buttonData.amsProgressEndCallback || data.amsProgressEndCallback;
  1507 
  1514 
  1508 									// Initialize submit target with AJAX indicator
  1515 									// Initialize submit target with AJAX indicator
  1509 									var target = null;
  1516 									var target = null;
  1510 									if (submit_options && submit_options.initSubmitTarget) {
  1517 									if (submitOptions && submitOptions.initSubmitTarget) {
  1511 										ams.executeFunctionByName(submit_options.initSubmitTarget, form);
  1518 										ams.executeFunctionByName(submitOptions.initSubmitTarget, form);
  1512 									} else {
  1519 									} else {
  1513 										if (data.amsFormInitSubmitTarget) {
  1520 										if (data.amsFormInitSubmitTarget) {
  1514 											target = $(button_target || data.amsFormSubmitTarget || '#content');
  1521 											target = $(buttonTarget || data.amsFormSubmitTarget || '#content');
  1515 											ams.executeFunctionByName(data.amsFormInitSubmit || 'MyAMS.form.initSubmit', form, target);
  1522 											ams.executeFunctionByName(data.amsFormInitSubmit || 'MyAMS.form.initSubmit', form, target);
  1516 										} else if (!data.amsFormHideSubmitFooter) {
  1523 										} else if (!data.amsFormHideSubmitFooter) {
  1517 											ams.executeFunctionByName(data.amsFormInitSubmit || 'MyAMS.form.initSubmitFooter', form);
  1524 											ams.executeFunctionByName(data.amsFormInitSubmit || 'MyAMS.form.initSubmitFooter', form);
  1518 										}
  1525 										}
  1519 									}
  1526 									}
  1520 
  1527 
  1521 									// Complete form data
  1528 									// Complete form data
  1522 									if (submit_options) {
  1529 									if (submitOptions) {
  1523 										form_data = $.extend({}, form_data, submit_options.form_data);
  1530 										formData = $.extend({}, formData, submitOptions.form_data);
  1524 									}
  1531 									}
  1525 
  1532 
  1526 									// Check progress handler
  1533 									// Check progress handler
  1527 									var hasUpload;
  1534 									var hasUpload;
  1528 									if (progress_handler) {
  1535 									if (progressHandler) {
  1529 										form_data.progress_id = ams.generateUUID();
  1536 										formData.progress_id = ams.generateUUID();
  1530 									} else {
  1537 									} else {
  1531 										// Check progress meter via Apache progress module
  1538 										// Check progress meter via Apache progress module
  1532 										hasUpload = typeof(options.uuid) !== 'undefined';
  1539 										hasUpload = typeof(options.uuid) !== 'undefined';
  1533 										if (hasUpload) {
  1540 										if (hasUpload) {
  1534 											if (url.indexOf('X-Progress-ID') < 0) {
  1541 											if (url.indexOf('X-Progress-ID') < 0) {
  1541 									// Initialize default AJAX settings
  1548 									// Initialize default AJAX settings
  1542 									var defaults = {
  1549 									var defaults = {
  1543 										url: url,
  1550 										url: url,
  1544 										type: 'post',
  1551 										type: 'post',
  1545 										cache: false,
  1552 										cache: false,
  1546 										data: form_data,
  1553 										data: formData,
  1547 										dataType: data.amsFormDatatype,
  1554 										dataType: data.amsFormDatatype,
  1548 										beforeSerialize: function(/*form, options*/) {
  1555 										beforeSerialize: function(/*form, options*/) {
  1549 											if (typeof(globals.tinyMCE) !== 'undefined') {
  1556 											if (typeof(globals.tinyMCE) !== 'undefined') {
  1550 												globals.tinyMCE.triggerSave();
  1557 												globals.tinyMCE.triggerSave();
  1551 											}
  1558 											}
  1561 										},
  1568 										},
  1562 										iframe: hasUpload
  1569 										iframe: hasUpload
  1563 									};
  1570 									};
  1564 
  1571 
  1565 									// Initialize IFrame for custom download target
  1572 									// Initialize IFrame for custom download target
  1566 									var download_target = (submit_options && submit_options.downloadTarget) || data.amsFormDownloadTarget;
  1573 									var downloadTarget = (submitOptions && submitOptions.downloadTarget) || data.amsFormDownloadTarget;
  1567 									if (download_target) {
  1574 									if (downloadTarget) {
  1568 										var iframe = $('iframe[name="' + download_target + '"]');
  1575 										var iframe = $('iframe[name="' + downloadTarget + '"]');
  1569 										if (!iframe.exists()) {
  1576 										if (!iframe.exists()) {
  1570 											iframe = $('<iframe></iframe>').hide()
  1577 											iframe = $('<iframe></iframe>').hide()
  1571 																		   .attr('name', download_target)
  1578 																		   .attr('name', downloadTarget)
  1572 																		   .appendTo($('body'));
  1579 																		   .appendTo($('body'));
  1573 										}
  1580 										}
  1574 										defaults = $.extend({}, defaults, {
  1581 										defaults = $.extend({}, defaults, {
  1575 											iframe: true,
  1582 											iframe: true,
  1576 											iframeTarget: iframe,
  1583 											iframeTarget: iframe,
  1621 												}
  1628 												}
  1622 											},
  1629 											},
  1623 											iframe: hasUpload
  1630 											iframe: hasUpload
  1624 										});
  1631 										});
  1625 									}
  1632 									}
  1626 									var settings = $.extend({}, defaults, options, form_options, submit_options);
  1633 									var settings = $.extend({}, defaults, options, formOptions, submitOptions);
  1627 
  1634 
  1628 									// Initialize progress handler
  1635 									// Initialize progress handler
  1629 									if (progress_handler) {
  1636 									if (progressHandler) {
  1630 										_getProgress(progress_handler, form_data.progress_id);
  1637 										_getProgress(progressHandler, formData.progress_id);
  1631 									}
  1638 									}
  1632 
  1639 
  1633 									// Submit form
  1640 									// Submit form
  1634 									$(form).ajaxSubmit(settings);
  1641 									$(form).ajaxSubmit(settings);
  1635 
  1642 
  1636 									// If external download target is specified, reset form submit button and footer
  1643 									// If external download target is specified, reset form submit button and footer
  1637 									if (download_target) {
  1644 									if (downloadTarget) {
  1638 										var modal = $(form).parents('.modal-dialog');
  1645 										var modal = $(form).parents('.modal-dialog');
  1639 										var keep_modal = modal.exists() && button.exists() && button.data('ams-keep-modal');
  1646 										var keepModal = modal.exists() && button.exists() && button.data('ams-keep-modal');
  1640 										if (modal.exists() && (keep_modal !== true)) {
  1647 										if (modal.exists() && (keepModal !== true)) {
  1641 											ams.dialog.close(form);
  1648 											ams.dialog.close(form);
  1642 										} else {
  1649 										} else {
  1643 											setTimeout(function() {
  1650 											setTimeout(function() {
  1644 												ams.form.resetAfterSubmit(form, button);
  1651 												ams.form.resetAfterSubmit(form, button);
  1645 												ams.form.resetChanged(form);
  1652 												ams.form.resetChanged(form);
  1778 					button.button('reset');
  1785 					button.button('reset');
  1779 				}
  1786 				}
  1780 			}
  1787 			}
  1781 
  1788 
  1782 			var data = form.data();
  1789 			var data = form.data();
  1783 			var data_type;
  1790 			var dataType;
  1784 			if (data.amsFormDatatype) {
  1791 			if (data.amsFormDatatype) {
  1785 				data_type = data.amsFormDatatype;
  1792 				dataType = data.amsFormDatatype;
  1786 			} else {
  1793 			} else {
  1787 				var request_data = ams.ajax.getResponse(request);
  1794 				var response = ams.ajax.getResponse(request);
  1788 				data_type = request_data.content_type;
  1795 				dataType = response.contentType;
  1789 				result = request_data.data;
  1796 				result = response.data;
  1790 			}
  1797 			}
  1791 
  1798 
  1792 			var target;
  1799 			var target;
  1793 			if (button) {
  1800 			if (button) {
  1794 				target = $(button.data('ams-form-submit-target') || data.amsFormSubmitTarget || '#content');
  1801 				target = $(button.data('ams-form-submit-target') || data.amsFormSubmitTarget || '#content');
  1795 			} else {
  1802 			} else {
  1796 				target = $(data.amsFormSubmitTarget || '#content');
  1803 				target = $(data.amsFormSubmitTarget || '#content');
  1797 			}
  1804 			}
  1798 
  1805 
  1799 			switch (data_type) {
  1806 			switch (dataType) {
  1800 				case 'json':
  1807 				case 'json':
  1801 					ams.ajax.handleJSON(result, form, target);
  1808 					ams.ajax.handleJSON(result, form, target);
  1802 					break;
  1809 					break;
  1803 				case 'script':
  1810 				case 'script':
  1804 					break;
  1811 					break;
  1835 		/**
  1842 		/**
  1836 		 * Get list of custom validators called before submit
  1843 		 * Get list of custom validators called before submit
  1837 		 */
  1844 		 */
  1838 		_getSubmitValidators: function(form) {
  1845 		_getSubmitValidators: function(form) {
  1839 			var validators = [];
  1846 			var validators = [];
  1840 			var form_validator = form.data('ams-form-validator');
  1847 			var formValidator = form.data('ams-form-validator');
  1841 			if (form_validator) {
  1848 			if (formValidator) {
  1842 				validators.push([form, form_validator]);
  1849 				validators.push([form, formValidator]);
  1843 			}
  1850 			}
  1844 			$('[data-ams-form-validator]', form).each(function() {
  1851 			$('[data-ams-form-validator]', form).each(function() {
  1845 				var source = $(this);
  1852 				var source = $(this);
  1846 				validators.push([source, source.data('ams-form-validator')]);
  1853 				validators.push([source, source.data('ams-form-validator')]);
  1847 			});
  1854 			});
  1866 			var result = true;
  1873 			var result = true;
  1867 			for (var index=0; index < validators.length; index++) {
  1874 			for (var index=0; index < validators.length; index++) {
  1868 				var validator = validators[index];
  1875 				var validator = validators[index];
  1869 				var source = validator[0];
  1876 				var source = validator[0];
  1870 				var handler = validator[1];
  1877 				var handler = validator[1];
  1871 				var validator_result = ams.executeFunctionByName(handler, form, source);
  1878 				var validatorResult = ams.executeFunctionByName(handler, form, source);
  1872 				if (validator_result === false) {
  1879 				if (validatorResult === false) {
  1873 					result = false;
  1880 					result = false;
  1874 				} else if (typeof(validator_result) === 'string') {
  1881 				} else if (typeof(validatorResult) === 'string') {
  1875 					output.push(validator_result);
  1882 					output.push(validatorResult);
  1876 				} else if (result.length && (result.length > 0)) {
  1883 				} else if (result.length && (result.length > 0)) {
  1877 					output = output.concat(result);
  1884 					output = output.concat(result);
  1878 				}
  1885 				}
  1879 			}
  1886 			}
  1880 			if (output.length > 0) {
  1887 			if (output.length > 0) {
  1923 					}
  1930 					}
  1924 				}
  1931 				}
  1925 				if (errors.widgets) {
  1932 				if (errors.widgets) {
  1926 					for (index = 0; index < errors.widgets.length; index++) {
  1933 					for (index = 0; index < errors.widgets.length; index++) {
  1927 						// set widget status message
  1934 						// set widget status message
  1928 						var widget_data = errors.widgets[index];
  1935 						var widgetData = errors.widgets[index];
  1929 						var widget = $('[name="' + widget_data.name + '"]', form);
  1936 						var widget = $('[name="' + widgetData.name + '"]', form);
  1930 						widget.parents('label:first')
  1937 						widget.parents('label:first')
  1931 								.removeClassPrefix('state-')
  1938 								.removeClassPrefix('state-')
  1932 								.addClass('state-error')
  1939 								.addClass('state-error')
  1933 								.after('<span for="name" class="state-error">' + widget_data.message + '</span>');
  1940 								.after('<span for="name" class="state-error">' + widgetData.message + '</span>');
  1934 						// complete form alert message
  1941 						// complete form alert message
  1935 						if (widget_data.label) {
  1942 						if (widgetData.label) {
  1936 							message.push(widget_data.label + ' : ' + widget_data.message);
  1943 							message.push(widgetData.label + ' : ' + widgetData.message);
  1937 						}
  1944 						}
  1938 						// mark parent tab (if any) with error status
  1945 						// mark parent tab (if any) with error status
  1939 						var tab_index = widget.parents('.tab-pane').index() + 1;
  1946 						var tabIndex = widget.parents('.tab-pane').index() + 1;
  1940 						if (tab_index > 0) {
  1947 						if (tabIndex > 0) {
  1941 							var nav_tabs = $('.nav-tabs', $(widget).parents('.tabforms'));
  1948 							var navTabs = $('.nav-tabs', $(widget).parents('.tabforms'));
  1942 							$('li:nth-child(' + tab_index + ')', nav_tabs).removeClassPrefix('state-')
  1949 							$('li:nth-child(' + tabIndex + ')', navTabs).removeClassPrefix('state-')
  1943 									.addClass('state-error');
  1950 																		.addClass('state-error');
  1944 							$('li.state-error:first a', form).click();
  1951 							$('li.state-error:first a', form).click();
  1945 						}
  1952 						}
  1946 					}
  1953 					}
  1947 				}
  1954 				}
  1948 				ams.skin.alert($('fieldset:first', form), errors.error_level || 'error', header, message, errors.error_message);
  1955 				ams.skin.alert($('fieldset:first', form), errors.error_level || 'error', header, message, errors.error_message);
  2032 													'<div class="progress-bar" style="width: 100%;"></div>' +
  2039 													'<div class="progress-bar" style="width: 100%;"></div>' +
  2033 												'</div>' +
  2040 												'</div>' +
  2034 											'</div>';
  2041 											'</div>';
  2035 									}
  2042 									}
  2036 
  2043 
  2037 									var source_data;
  2044 									var sourceData;
  2038 									var url;
  2045 									var url;
  2039 									if (typeof(source) === 'string') {
  2046 									if (typeof(source) === 'string') {
  2040 										source_data = {};
  2047 										sourceData = {};
  2041 										url = source;
  2048 										url = source;
  2042 									} else {
  2049 									} else {
  2043 										source_data = source.data();
  2050 										sourceData = source.data();
  2044 										url = source.attr('href') || source_data.amsUrl;
  2051 										url = source.attr('href') || sourceData.amsUrl;
  2045 										var url_getter = ams.getFunctionByName(url);
  2052 										var url_getter = ams.getFunctionByName(url);
  2046 										if (typeof(url_getter) === 'function') {
  2053 										if (typeof(url_getter) === 'function') {
  2047 											url = url_getter.call(source);
  2054 											url = url_getter.call(source);
  2048 										}
  2055 										}
  2049 									}
  2056 									}
  2057 									} else {
  2064 									} else {
  2058 										// Remote URL modal dialog
  2065 										// Remote URL modal dialog
  2059 										$.ajax({
  2066 										$.ajax({
  2060 											url: url,
  2067 											url: url,
  2061 											type: 'get',
  2068 											type: 'get',
  2062 											cache: source_data.amsAllowCache === undefined ? false : source_data.amsAllowCache,
  2069 											cache: sourceData.amsAllowCache === undefined ? false : sourceData.amsAllowCache,
  2063 											data: options,
  2070 											data: options,
  2064 											success: function(data, status, request) {
  2071 											success: function(data, status, request) {
  2065 												$('body').modalmanager('removeLoading');
  2072 												$('body').modalmanager('removeLoading');
  2066 												var request_data = ams.ajax.getResponse(request);
  2073 												var response = ams.ajax.getResponse(request);
  2067 												var data_type = request_data.content_type;
  2074 												var dataType = response.contentType;
  2068 												var result = request_data.data;
  2075 												var result = response.data;
  2069 												switch (data_type) {
  2076 												switch (dataType) {
  2070 													case 'json':
  2077 													case 'json':
  2071 														ams.ajax.handleJSON(result, $($(source).data('ams-json-target') || '#content'));
  2078 														ams.ajax.handleJSON(result, $($(source).data('ams-json-target') || '#content'));
  2072 														break;
  2079 														break;
  2073 													case 'script':
  2080 													case 'script':
  2074 														break;
  2081 														break;
  2079 													case 'text':
  2086 													case 'text':
  2080 														/* falls through */
  2087 														/* falls through */
  2081 													default:
  2088 													default:
  2082 														var content = $(result);
  2089 														var content = $(result);
  2083 														var dialog = $('.modal-dialog', content.wrap('<div></div>').parent());
  2090 														var dialog = $('.modal-dialog', content.wrap('<div></div>').parent());
  2084 														var dialog_data = dialog.data();
  2091 														var dialogData = dialog.data();
  2085 														var data_options = {
  2092 														var dataOptions = {
  2086 															backdrop: 'static',
  2093 															backdrop: 'static',
  2087 															overflow: dialog_data.amsModalOverflow || '.modal-viewport',
  2094 															overflow: dialogData.amsModalOverflow || '.modal-viewport',
  2088 															maxHeight: dialog_data.amsModalMaxHeight === undefined ?
  2095 															maxHeight: dialogData.amsModalMaxHeight === undefined ?
  2089 																	function() {
  2096 																	function() {
  2090 																		return $(window).height() -
  2097 																		return $(window).height() -
  2091 																					$('.modal-header', content).outerHeight(true) -
  2098 																					$('.modal-header', content).outerHeight(true) -
  2092 																					$('footer', content).outerHeight(true) - 85;
  2099 																					$('footer', content).outerHeight(true) - 85;
  2093 																	}
  2100 																	}
  2094 																	: ams.getFunctionByName(dialog_data.amsModalMaxHeight)
  2101 																	: ams.getFunctionByName(dialogData.amsModalMaxHeight)
  2095 														};
  2102 														};
  2096 														var settings = $.extend({}, data_options, dialog_data.amsModalOptions);
  2103 														var settings = $.extend({}, dataOptions, dialogData.amsModalOptions);
  2097 														settings = ams.executeFunctionByName(dialog_data.amsModalInitCallback, dialog, settings) || settings;
  2104 														settings = ams.executeFunctionByName(dialogData.amsModalInitCallback, dialog, settings) || settings;
  2098 														$('<div>').addClass('modal fade')
  2105 														$('<div>').addClass('modal fade')
  2099 																  .append(content)
  2106 																  .append(content)
  2100 																  .modal(settings)
  2107 																  .modal(settings)
  2101 																  .on('shown', ams.dialog.shown)
  2108 																  .on('shown', ams.dialog.shown)
  2102 																  .on('hidden', ams.dialog.hidden);
  2109 																  .on('hidden', ams.dialog.hidden);
  2103 														ams.initContent(content);
  2110 														ams.initContent(content);
  2104 														if (source_data.amsLogEvent !== false) {
  2111 														if (sourceData.amsLogEvent !== false) {
  2105 															ams.stats.logPageview(url);
  2112 															ams.stats.logPageview(url);
  2106 														}
  2113 														}
  2107 												}
  2114 												}
  2108 											}
  2115 											}
  2109 										});
  2116 										});
  2118 		 */
  2125 		 */
  2119 		shown: function(e) {
  2126 		shown: function(e) {
  2120 
  2127 
  2121 			function resetViewport(ev) {
  2128 			function resetViewport(ev) {
  2122 				var top = $('.scrollmarker.top', viewport);
  2129 				var top = $('.scrollmarker.top', viewport);
  2123 				var top_position = viewport.scrollTop();
  2130 				var topPosition = viewport.scrollTop();
  2124 				if (top_position > 0) {
  2131 				if (topPosition > 0) {
  2125 					top.show();
  2132 					top.show();
  2126 				} else {
  2133 				} else {
  2127 					top.hide();
  2134 					top.hide();
  2128 				}
  2135 				}
  2129 				var bottom = $('.scrollmarker.bottom', viewport);
  2136 				var bottom = $('.scrollmarker.bottom', viewport);
  2130 				if (maxHeight + top_position >= viewport.get(0).scrollHeight) {
  2137 				if (maxHeight + topPosition >= viewport.get(0).scrollHeight) {
  2131 					bottom.hide();
  2138 					bottom.hide();
  2132 				} else {
  2139 				} else {
  2133 					bottom.show();
  2140 					bottom.show();
  2134 				}
  2141 				}
  2135 			}
  2142 			}
  2312 			}
  2319 			}
  2313 		},
  2320 		},
  2314 
  2321 
  2315 		/** Context menu handler */
  2322 		/** Context menu handler */
  2316 		contextMenuHandler: function(target, menu) {
  2323 		contextMenuHandler: function(target, menu) {
  2317 			var menu_data = menu.data();
  2324 			var menuData = menu.data();
  2318 			if (menu_data.toggle === 'modal') {
  2325 			if (menuData.toggle === 'modal') {
  2319 				ams.dialog.open(menu);
  2326 				ams.dialog.open(menu);
  2320 			} else {
  2327 			} else {
  2321 				var href = menu.attr('href') || menu_data.amsUrl;
  2328 				var href = menu.attr('href') || menuData.amsUrl;
  2322 				if (!href || href.startsWith('javascript') || menu.attr('target')) {
  2329 				if (!href || href.startsWith('javascript') || menu.attr('target')) {
  2323 					return;
  2330 					return;
  2324 				}
  2331 				}
  2325 				ams.event.stop();
  2332 				ams.event.stop();
  2326 				var href_getter = ams.getFunctionByName(href);
  2333 				var hrefGetter = ams.getFunctionByName(href);
  2327 				if (typeof(href_getter) === 'function') {
  2334 				if (typeof(hrefGetter) === 'function') {
  2328 					href = href_getter.call(menu, target);
  2335 					href = hrefGetter.call(menu, target);
  2329 				}
  2336 				}
  2330 				if (typeof(href) === 'function') {
  2337 				if (typeof(href) === 'function') {
  2331 					// Javascript function call
  2338 					// Javascript function call
  2332 					href.call(menu, target);
  2339 					href.call(menu, target);
  2333 				} else {
  2340 				} else {
  2434 			}
  2441 			}
  2435 
  2442 
  2436 			$('[data-ams-plugins]', element).each(function() {
  2443 			$('[data-ams-plugins]', element).each(function() {
  2437 
  2444 
  2438 				var source = $(this);
  2445 				var source = $(this);
  2439 				var ams_plugins = source.data('ams-plugins');
  2446 				var amsPlugins = source.data('ams-plugins');
  2440 				if (typeof(ams_plugins) === 'string') {
  2447 				if (typeof(amsPlugins) === 'string') {
  2441 					var names = source.data('ams-plugins').split(/\s+/);
  2448 					var names = source.data('ams-plugins').split(/\s+/);
  2442 					for (var index = 0; index < names.length; index++) {
  2449 					for (var index = 0; index < names.length; index++) {
  2443 						name = names[index];
  2450 						name = names[index];
  2444 						var new_plugin = {
  2451 						var newPlugin = {
  2445 							src: source.data('ams-plugin-' + name + '-src'),
  2452 							src: source.data('ams-plugin-' + name + '-src'),
  2446 							css: source.data('ams-plugin-' + name + '-css'),
  2453 							css: source.data('ams-plugin-' + name + '-css'),
  2447 							callback: source.data('ams-plugin-' + name + '-callback'),
  2454 							callback: source.data('ams-plugin-' + name + '-callback'),
  2448 							register: source.data('ams-plugin-' + name + '-register'),
  2455 							register: source.data('ams-plugin-' + name + '-register'),
  2449 							async: source.data('ams-plugin-' + name + '-async')
  2456 							async: source.data('ams-plugin-' + name + '-async')
  2450 						};
  2457 						};
  2451 						_registerPlugin(name, new_plugin);
  2458 						_registerPlugin(name, newPlugin);
  2452 					}
  2459 					}
  2453 				} else {
  2460 				} else {
  2454 					for (name in ams_plugins) {
  2461 					for (name in amsPlugins) {
  2455 						if (!ams_plugins.hasOwnProperty(name)) {
  2462 						if (!amsPlugins.hasOwnProperty(name)) {
  2456 							continue;
  2463 							continue;
  2457 						}
  2464 						}
  2458 						_registerPlugin(name, ams_plugins[name]);
  2465 						_registerPlugin(name, amsPlugins[name]);
  2459 					}
  2466 					}
  2460 				}
  2467 				}
  2461 			});
  2468 			});
  2462 
  2469 
  2463 			for (name in plugins) {
  2470 			for (name in plugins) {
  2509 					switch (typeof(callbacks)) {
  2516 					switch (typeof(callbacks)) {
  2510 						case 'function':
  2517 						case 'function':
  2511 							callbacks(element);
  2518 							callbacks(element);
  2512 							break;
  2519 							break;
  2513 						default:
  2520 						default:
  2514 							for (var cb_index = 0; cb_index < callbacks.length; cb_index++) {
  2521 							for (var cbIndex = 0; cbIndex < callbacks.length; cbIndex++) {
  2515 								var callback = callbacks[cb_index];
  2522 								var callback = callbacks[cbIndex];
  2516 								if (typeof(callback) === 'function') {
  2523 								if (typeof(callback) === 'function') {
  2517 									callback(element);
  2524 									callback(element);
  2518 								}
  2525 								}
  2519 							}
  2526 							}
  2520 					}
  2527 					}
  2528 		 * This way of defining data attributes can be used with HTML templates engines which don't allow you
  2535 		 * This way of defining data attributes can be used with HTML templates engines which don't allow you
  2529 		 * to create dynamic attributes easily.
  2536 		 * to create dynamic attributes easily.
  2530 		 */
  2537 		 */
  2531 		initData: function(element) {
  2538 		initData: function(element) {
  2532 			$('[data-ams-data]', element).each(function() {
  2539 			$('[data-ams-data]', element).each(function() {
  2533 				var data_element = $(this);
  2540 				var dataElement = $(this);
  2534 				var data = data_element.data('ams-data');
  2541 				var data = dataElement.data('ams-data');
  2535 				if (data) {
  2542 				if (data) {
  2536 					for (var name in data) {
  2543 					for (var name in data) {
  2537 						if (data.hasOwnProperty(name)) {
  2544 						if (data.hasOwnProperty(name)) {
  2538 							data_element.attr('data-' + name, data[name]);
  2545 							dataElement.attr('data-' + name, data[name]);
  2539 						}
  2546 						}
  2540 					}
  2547 					}
  2541 				}
  2548 				}
  2542 			});
  2549 			});
  2543 		},
  2550 		},
  2619 									   ams.getCSS(ams.baseURL + '../css/ext/jquery-tipsy' + ams.devext + '.css',
  2626 									   ams.getCSS(ams.baseURL + '../css/ext/jquery-tipsy' + ams.devext + '.css',
  2620 												  'jquery-tipsy');
  2627 												  'jquery-tipsy');
  2621 									   hints.each(function () {
  2628 									   hints.each(function () {
  2622 										   var hint = $(this);
  2629 										   var hint = $(this);
  2623 										   var data = hint.data();
  2630 										   var data = hint.data();
  2624 										   var data_options = {
  2631 										   var dataOptions = {
  2625 											   html: data.amsHintHtml,
  2632 											   html: data.amsHintHtml,
  2626 											   title: ams.getFunctionByName(data.amsHintTitleGetter) || function () {
  2633 											   title: ams.getFunctionByName(data.amsHintTitleGetter) || function () {
  2627 												   var hint = $(this);
  2634 												   var hint = $(this);
  2628 												   return hint.attr('original-title') ||
  2635 												   return hint.attr('original-title') ||
  2629 														   hint.attr(data.amsHintTitleAttr || 'title') ||
  2636 														   hint.attr(data.amsHintTitleAttr || 'title') ||
  2631 											   },
  2638 											   },
  2632 											   opacity: data.amsHintOpacity || 0.95,
  2639 											   opacity: data.amsHintOpacity || 0.95,
  2633 											   gravity: data.amsHintGravity || 'sw',
  2640 											   gravity: data.amsHintGravity || 'sw',
  2634 											   offset: data.amsHintOffset || 0
  2641 											   offset: data.amsHintOffset || 0
  2635 										   };
  2642 										   };
  2636 										   var settings = $.extend({}, data_options, data.amsHintOptions);
  2643 										   var settings = $.extend({}, dataOptions, data.amsHintOptions);
  2637 										   settings = ams.executeFunctionByName(data.amsHintInitCallback, hint, settings) || settings;
  2644 										   settings = ams.executeFunctionByName(data.amsHintInitCallback, hint, settings) || settings;
  2638 										   var plugin = hint.tipsy(settings);
  2645 										   var plugin = hint.tipsy(settings);
  2639 										   ams.executeFunctionByName(data.amsHintAfterInitCallback, hint, plugin, settings);
  2646 										   ams.executeFunctionByName(data.amsHintAfterInitCallback, hint, plugin, settings);
  2640 									   });
  2647 									   });
  2641 								   });
  2648 								   });
  2649 				var menus = $('.context-menu', element);
  2656 				var menus = $('.context-menu', element);
  2650 				if (menus.length > 0) {
  2657 				if (menus.length > 0) {
  2651 					menus.each(function() {
  2658 					menus.each(function() {
  2652 						var menu = $(this);
  2659 						var menu = $(this);
  2653 						var data = menu.data();
  2660 						var data = menu.data();
  2654 						var data_options = {
  2661 						var dataOptions = {
  2655 							menuSelector: data.amsContextmenuSelector,
  2662 							menuSelector: data.amsContextmenuSelector,
  2656 							menuSelected: ams.helpers.contextMenuHandler
  2663 							menuSelected: ams.helpers.contextMenuHandler
  2657 						};
  2664 						};
  2658 						var settings = $.extend({}, data_options, data.amsContextmenuOptions);
  2665 						var settings = $.extend({}, dataOptions, data.amsContextmenuOptions);
  2659 						settings = ams.executeFunctionByName(data.amsContextmenuInitCallback, menu, settings) || settings;
  2666 						settings = ams.executeFunctionByName(data.amsContextmenuInitCallback, menu, settings) || settings;
  2660 						var plugin = menu.contextMenu(settings);
  2667 						var plugin = menu.contextMenu(settings);
  2661 						ams.executeFunctionByName(data.amsContextmenuAfterInitCallback, menu, plugin, settings);
  2668 						ams.executeFunctionByName(data.amsContextmenuAfterInitCallback, menu, plugin, settings);
  2662 					});
  2669 					});
  2663 				}
  2670 				}
  2722 					var fieldset = legend.parent('fieldset');
  2729 					var fieldset = legend.parent('fieldset');
  2723 					var data = legend.data();
  2730 					var data = legend.data();
  2724 					if (!data.amsChecker) {
  2731 					if (!data.amsChecker) {
  2725 						var checker = $('<label class="checkbox"></label>');
  2732 						var checker = $('<label class="checkbox"></label>');
  2726 						var fieldname = data.amsCheckerFieldname || ('checker_'+ams.generateId());
  2733 						var fieldname = data.amsCheckerFieldname || ('checker_'+ams.generateId());
  2727 						var checkbox_id = fieldname.replace(/\./, '_');
  2734 						var checkboxId = fieldname.replace(/\./, '_');
  2728 						var prefix = data.amsCheckerHiddenPrefix;
  2735 						var prefix = data.amsCheckerHiddenPrefix;
  2729 						var hidden = null;
  2736 						var hidden = null;
  2730 						var checkedValue = data.amsCheckerHiddenValueOn || 'true';
  2737 						var checkedValue = data.amsCheckerHiddenValueOn || 'true';
  2731 						var uncheckedValue = data.amsCheckerHiddenValueOff || 'false';
  2738 						var uncheckedValue = data.amsCheckerHiddenValueOff || 'false';
  2732 						var marker = data.amsCheckerMarker || false;
  2739 						var marker = data.amsCheckerMarker || false;
  2738 							$('<input type="hidden">').attr('name', marker)
  2745 							$('<input type="hidden">').attr('name', marker)
  2739 													  .attr('value', 1)
  2746 													  .attr('value', 1)
  2740 													  .prependTo(legend);
  2747 													  .prependTo(legend);
  2741 						}
  2748 						}
  2742 						var input = $('<input type="checkbox">').attr('name', fieldname)
  2749 						var input = $('<input type="checkbox">').attr('name', fieldname)
  2743 																.attr('id', checkbox_id)
  2750 																.attr('id', checkboxId)
  2744 																.data('ams-checker-hidden-input', hidden)
  2751 																.data('ams-checker-hidden-input', hidden)
  2745 																.data('ams-checker-init', true)
  2752 																.data('ams-checker-init', true)
  2746 																.val(data.amsCheckerValue || true)
  2753 																.val(data.amsCheckerValue || true)
  2747 																.attr('checked', data.amsCheckerState === 'on' ? 'checked' : null);
  2754 																.attr('checked', data.amsCheckerState === 'on' ? 'checked' : null);
  2748 						if (data.amsCheckerReadonly) {
  2755 						if (data.amsCheckerReadonly) {
  2818 								   ams.baseURL + 'ext/bootstrap-slider-2.0.0' + ams.devext + '.js',
  2825 								   ams.baseURL + 'ext/bootstrap-slider-2.0.0' + ams.devext + '.js',
  2819 								   function() {
  2826 								   function() {
  2820 										sliders.each(function() {
  2827 										sliders.each(function() {
  2821 											var slider = $(this);
  2828 											var slider = $(this);
  2822 											var data = slider.data();
  2829 											var data = slider.data();
  2823 											var data_options = {};
  2830 											var dataOptions = {};
  2824 											var settings = $.extend({}, data_options, slider.data.amsSliderOptions);
  2831 											var settings = $.extend({}, dataOptions, slider.data.amsSliderOptions);
  2825 											settings = ams.executeFunctionByName(data.amsSliderInitCallback, slider, settings) || settings;
  2832 											settings = ams.executeFunctionByName(data.amsSliderInitCallback, slider, settings) || settings;
  2826 											var plugin = slider.slider(settings);
  2833 											var plugin = slider.slider(settings);
  2827 											ams.executeFunctionByName(data.amsSliderAfterInitCallback, slider, plugin, settings);
  2834 											ams.executeFunctionByName(data.amsSliderAfterInitCallback, slider, plugin, settings);
  2828 										});
  2835 										});
  2829 								   });
  2836 								   });
  2837 				var draggables = $('.draggable', element);
  2844 				var draggables = $('.draggable', element);
  2838 				if (draggables.length > 0) {
  2845 				if (draggables.length > 0) {
  2839 					draggables.each(function() {
  2846 					draggables.each(function() {
  2840 						var draggable = $(this);
  2847 						var draggable = $(this);
  2841 						var data = draggable.data();
  2848 						var data = draggable.data();
  2842 						var data_options = {
  2849 						var dataOptions = {
  2843 							containment: data.amsDraggableContainment,
  2850 							containment: data.amsDraggableContainment,
  2844 							helper: ams.getFunctionByName(data.amsDraggableHelper) || data.amsDraggableHelper,
  2851 							helper: ams.getFunctionByName(data.amsDraggableHelper) || data.amsDraggableHelper,
  2845 							start: ams.getFunctionByName(data.amsDraggableStart),
  2852 							start: ams.getFunctionByName(data.amsDraggableStart),
  2846 							stop: ams.getFunctionByName(data.amsDraggableStop)
  2853 							stop: ams.getFunctionByName(data.amsDraggableStop)
  2847 						};
  2854 						};
  2848 						var settings = $.extend({}, data_options, data.amsDraggableOptions);
  2855 						var settings = $.extend({}, dataOptions, data.amsDraggableOptions);
  2849 						settings = ams.executeFunctionByName(data.amsDraggableInitCallback, draggable, settings) || settings;
  2856 						settings = ams.executeFunctionByName(data.amsDraggableInitCallback, draggable, settings) || settings;
  2850 						var plugin = draggable.draggable(settings);
  2857 						var plugin = draggable.draggable(settings);
  2851 						draggable.disableSelection();
  2858 						draggable.disableSelection();
  2852 						ams.executeFunctionByName(data.amsDraggableAfterInitCallback, draggable, plugin, settings);
  2859 						ams.executeFunctionByName(data.amsDraggableAfterInitCallback, draggable, plugin, settings);
  2853 					});
  2860 					});
  2861 				var sortables = $('.sortable', element);
  2868 				var sortables = $('.sortable', element);
  2862 				if (sortables.length > 0) {
  2869 				if (sortables.length > 0) {
  2863 					sortables.each(function() {
  2870 					sortables.each(function() {
  2864 						var sortable = $(this);
  2871 						var sortable = $(this);
  2865 						var data = sortable.data();
  2872 						var data = sortable.data();
  2866 						var data_options = {
  2873 						var dataOptions = {
  2867 							items: data.amsSortableItems,
  2874 							items: data.amsSortableItems,
  2868 							handle: data.amsSortableHandle,
  2875 							handle: data.amsSortableHandle,
  2869 							connectWith: data.amsSortableConnectwith,
  2876 							connectWith: data.amsSortableConnectwith,
  2870 							start: ams.getFunctionByName(data.amsSortableStart),
  2877 							start: ams.getFunctionByName(data.amsSortableStart),
  2871 							over: ams.getFunctionByName(data.amsSortableOver),
  2878 							over: ams.getFunctionByName(data.amsSortableOver),
  2872 							containment: data.amsSortableContainment,
  2879 							containment: data.amsSortableContainment,
  2873 							placeholder: data.amsSortablePlaceholder,
  2880 							placeholder: data.amsSortablePlaceholder,
  2874 							stop: ams.getFunctionByName(data.amsSortableStop)
  2881 							stop: ams.getFunctionByName(data.amsSortableStop)
  2875 						};
  2882 						};
  2876 						var settings = $.extend({}, data_options, data.amsSortableOptions);
  2883 						var settings = $.extend({}, dataOptions, data.amsSortableOptions);
  2877 						settings = ams.executeFunctionByName(data.amsSortableInitCallback, sortable, settings) || settings;
  2884 						settings = ams.executeFunctionByName(data.amsSortableInitCallback, sortable, settings) || settings;
  2878 						var plugin = sortable.sortable(settings);
  2885 						var plugin = sortable.sortable(settings);
  2879 						sortable.disableSelection();
  2886 						sortable.disableSelection();
  2880 						ams.executeFunctionByName(data.amsSortableAfterInitCallback, sortable, plugin, settings);
  2887 						ams.executeFunctionByName(data.amsSortableAfterInitCallback, sortable, plugin, settings);
  2881 					});
  2888 					});
  2889 				var resizables = $('.resizable', element);
  2896 				var resizables = $('.resizable', element);
  2890 				if (resizables.length > 0) {
  2897 				if (resizables.length > 0) {
  2891 					resizables.each(function() {
  2898 					resizables.each(function() {
  2892 						var resizable = $(this);
  2899 						var resizable = $(this);
  2893 						var data = resizable.data();
  2900 						var data = resizable.data();
  2894 						var data_options = {
  2901 						var dataOptions = {
  2895 							autoHide: data.amsResizableAutohide === false ? true : data.amsResizableAutohide,
  2902 							autoHide: data.amsResizableAutohide === false ? true : data.amsResizableAutohide,
  2896 							containment: data.amsResizableContainment,
  2903 							containment: data.amsResizableContainment,
  2897 							grid: data.amsResizableGrid,
  2904 							grid: data.amsResizableGrid,
  2898 							handles: data.amsResizableHandles,
  2905 							handles: data.amsResizableHandles,
  2899 							start: ams.getFunctionByName(data.amsResizableStart),
  2906 							start: ams.getFunctionByName(data.amsResizableStart),
  2900 							stop: ams.getFunctionByName(data.amsResizableStop)
  2907 							stop: ams.getFunctionByName(data.amsResizableStop)
  2901 						};
  2908 						};
  2902 						var settings = $.extend({}, data_options, data.amsResizableOptions);
  2909 						var settings = $.extend({}, dataOptions, data.amsResizableOptions);
  2903 						settings = ams.executeFunctionByName(data.amsResizableInitCallback, resizable, settings) || settings;
  2910 						settings = ams.executeFunctionByName(data.amsResizableInitCallback, resizable, settings) || settings;
  2904 						var plugin = resizable.resizable(settings);
  2911 						var plugin = resizable.resizable(settings);
  2905 						resizable.disableSelection();
  2912 						resizable.disableSelection();
  2906 						ams.executeFunctionByName(data.amsResizableAfterInitCallback, resizable, plugin, settings);
  2913 						ams.executeFunctionByName(data.amsResizableAfterInitCallback, resizable, plugin, settings);
  2907 					});
  2914 					});
  2918 								   ams.baseURL + 'ext/jquery-typeahead' + ams.devext + '.js',
  2925 								   ams.baseURL + 'ext/jquery-typeahead' + ams.devext + '.js',
  2919 								   function() {
  2926 								   function() {
  2920 										typeaheads.each(function() {
  2927 										typeaheads.each(function() {
  2921 											var input = $(this);
  2928 											var input = $(this);
  2922 											var data = input.data();
  2929 											var data = input.data();
  2923 											var data_options = {};
  2930 											var dataOptions = {};
  2924 											var settings = $.extend({}, data_options, data.amsTypeaheadOptions);
  2931 											var settings = $.extend({}, dataOptions, data.amsTypeaheadOptions);
  2925 											settings = ams.executeFunctionByName(data.amsTypeaheadInitCallback, input, settings) || settings;
  2932 											settings = ams.executeFunctionByName(data.amsTypeaheadInitCallback, input, settings) || settings;
  2926 											var plugin = input.typeahead(settings);
  2933 											var plugin = input.typeahead(settings);
  2927 											ams.executeFunctionByName(data.amsTypeaheadAfterInitCallback, input, plugin, settings);
  2934 											ams.executeFunctionByName(data.amsTypeaheadAfterInitCallback, input, plugin, settings);
  2928 										});
  2935 										});
  2929 								   });
  2936 								   });
  2940 								   ams.baseURL + 'ext/jquery-select2-3.5.2' + ams.devext + '.js',
  2947 								   ams.baseURL + 'ext/jquery-select2-3.5.2' + ams.devext + '.js',
  2941 								   function() {
  2948 								   function() {
  2942 										selects.each(function() {
  2949 										selects.each(function() {
  2943 											var select = $(this);
  2950 											var select = $(this);
  2944 											var data = select.data();
  2951 											var data = select.data();
  2945 											var data_options = {
  2952 											var dataOptions = {
  2946 												placeholder: data.amsSelect2Placeholder,
  2953 												placeholder: data.amsSelect2Placeholder,
  2947 												multiple: data.amsSelect2Multiple,
  2954 												multiple: data.amsSelect2Multiple,
  2948 												minimumInputLength: data.amsSelect2MinimumInputLength || 0,
  2955 												minimumInputLength: data.amsSelect2MinimumInputLength || 0,
  2949 												maximumSelectionSize: data.amsSelect2MaximumSelectionSize,
  2956 												maximumSelectionSize: data.amsSelect2MaximumSelectionSize,
  2950 												openOnEnter: data.amsSelect2EnterOpen === undefined ? true : data.amsSelect2EnterOpen,
  2957 												openOnEnter: data.amsSelect2EnterOpen === undefined ? true : data.amsSelect2EnterOpen,
  3008 											};
  3015 											};
  3009 
  3016 
  3010 											switch (select.context.type) {
  3017 											switch (select.context.type) {
  3011 												case 'text':
  3018 												case 'text':
  3012 												case 'hidden':
  3019 												case 'hidden':
  3013 													if (!data_options.initSelection) {
  3020 													if (!dataOptions.initSelection) {
  3014 														var values_data = select.data('ams-select2-values');
  3021 														var valuesData = select.data('ams-select2-values');
  3015 														if (values_data) {
  3022 														if (valuesData) {
  3016 															data_options.initSelection = function(element, callback) {
  3023 															dataOptions.initSelection = function(element, callback) {
  3017 																var data = [];
  3024 																var data = [];
  3018 																$(element.val().split(data_options.separator)).each(function() {
  3025 																$(element.val().split(dataOptions.separator)).each(function() {
  3019 																	data.push({id: this,
  3026 																	data.push({id: this,
  3020 																			   text: values_data[this] || this});
  3027 																			   text: valuesData[this] || this});
  3021 																});
  3028 																});
  3022 																callback(data);
  3029 																callback(data);
  3023 															};
  3030 															};
  3024 														}
  3031 														}
  3025 													}
  3032 													}
  3028 													break;
  3035 													break;
  3029 											}
  3036 											}
  3030 
  3037 
  3031 											if (select.attr('readonly')) {
  3038 											if (select.attr('readonly')) {
  3032 												if (select.attr('type') === 'hidden') {
  3039 												if (select.attr('type') === 'hidden') {
  3033 													data_options.query = function () {
  3040 													dataOptions.query = function () {
  3034 														return [];
  3041 														return [];
  3035 													};
  3042 													};
  3036 												}
  3043 												}
  3037 											} else if (data.amsSelect2Query) {
  3044 											} else if (data.amsSelect2Query) {
  3038 												// Custom query method
  3045 												// Custom query method
  3039 												data_options.query = ams.getFunctionByName(data.amsSelect2Query);
  3046 												dataOptions.query = ams.getFunctionByName(data.amsSelect2Query);
  3040 												data_options.minimumInputLength = data.amsSelect2MinimumInputLength || 1;
  3047 												dataOptions.minimumInputLength = data.amsSelect2MinimumInputLength || 1;
  3041 											} else if (data.amsSelect2QueryUrl) {
  3048 											} else if (data.amsSelect2QueryUrl) {
  3042 												// AJAX query
  3049 												// AJAX query
  3043 												data_options.ajax = {
  3050 												dataOptions.ajax = {
  3044 													url: data.amsSelect2QueryUrl,
  3051 													url: data.amsSelect2QueryUrl,
  3045 													quietMillis: data.amsSelect2QuietMillis || 200,
  3052 													quietMillis: data.amsSelect2QuietMillis || 200,
  3046 													type: data.amsSelect2QueryType || 'POST',
  3053 													type: data.amsSelect2QueryType || 'POST',
  3047 													dataType: data.amsSelect2QueryDatatype || 'json',
  3054 													dataType: data.amsSelect2QueryDatatype || 'json',
  3048 													data: function(term, page, context) {
  3055 													data: function(term, page, context) {
  3052 														options[data.amsSelect2ContextParamName || 'context'] = context;
  3059 														options[data.amsSelect2ContextParamName || 'context'] = context;
  3053 														return $.extend({}, options, data.amsSelect2QueryOptions);
  3060 														return $.extend({}, options, data.amsSelect2QueryOptions);
  3054 													},
  3061 													},
  3055 													results: ams.helpers.select2QueryUrlResultsCallback
  3062 													results: ams.helpers.select2QueryUrlResultsCallback
  3056 												};
  3063 												};
  3057 												data_options.minimumInputLength = data.amsSelect2MinimumInputLength || 1;
  3064 												dataOptions.minimumInputLength = data.amsSelect2MinimumInputLength || 1;
  3058 											} else if (data.amsSelect2QueryMethod) {
  3065 											} else if (data.amsSelect2QueryMethod) {
  3059 												// JSON-RPC query
  3066 												// JSON-RPC query
  3060 												data_options.query = function(options) {
  3067 												dataOptions.query = function(options) {
  3061 													var settings = {
  3068 													var settings = {
  3062 														url: data.amsSelect2MethodTarget || ams.jsonrpc.getAddr(),
  3069 														url: data.amsSelect2MethodTarget || ams.jsonrpc.getAddr(),
  3063 														type: data.amsSelect2MethodType || 'POST',
  3070 														type: data.amsSelect2MethodType || 'POST',
  3064 														cache: false,
  3071 														cache: false,
  3065 														method: data.amsSelect2QueryMethod,
  3072 														method: data.amsSelect2QueryMethod,
  3073 													settings.params[data.amsSelect2PageParamName || 'page'] = options.page;
  3080 													settings.params[data.amsSelect2PageParamName || 'page'] = options.page;
  3074 													settings.params[data.amsSelect2ContextParamName || 'context'] = options.context;
  3081 													settings.params[data.amsSelect2ContextParamName || 'context'] = options.context;
  3075 													settings = $.extend({}, settings, data.amsSelect2QueryOptions);
  3082 													settings = $.extend({}, settings, data.amsSelect2QueryOptions);
  3076 													settings = ams.executeFunctionByName(data.amsSelect2QueryInitCallback, select, settings) || settings;
  3083 													settings = ams.executeFunctionByName(data.amsSelect2QueryInitCallback, select, settings) || settings;
  3077 													ams.ajax.check($.jsonRpc,
  3084 													ams.ajax.check($.jsonRpc,
  3078 																   ams.baseURL + 'ext/jquery-jsonrpc' + (ams.devmode ? '.js' : '.min.js'),
  3085 																   ams.baseURL + 'ext/jquery-jsonrpc' + ams.devext + '.js',
  3079 																   function() {
  3086 																   function() {
  3080 																		$.jsonRpc(settings);
  3087 																		$.jsonRpc(settings);
  3081 																   });
  3088 																   });
  3082 												};
  3089 												};
  3083 												data_options.minimumInputLength = data.amsSelect2MinimumInputLength || 1;
  3090 												dataOptions.minimumInputLength = data.amsSelect2MinimumInputLength || 1;
  3084 											} else if (data.amsSelect2Tags) {
  3091 											} else if (data.amsSelect2Tags) {
  3085 												// Tags mode
  3092 												// Tags mode
  3086 												data_options.tags = data.amsSelect2Tags;
  3093 												dataOptions.tags = data.amsSelect2Tags;
  3087 											} else if (data.amsSelect2Data) {
  3094 											} else if (data.amsSelect2Data) {
  3088 												// Provided data mode
  3095 												// Provided data mode
  3089 												data_options.data = data.amsSelect2Data;
  3096 												dataOptions.data = data.amsSelect2Data;
  3090 											}
  3097 											}
  3091 
  3098 
  3092 											if (data.amsSelect2EnableFreeTags) {
  3099 											if (data.amsSelect2EnableFreeTags) {
  3093 												data_options.createSearchChoice = function(term) {
  3100 												dataOptions.createSearchChoice = function(term) {
  3094 													return {id: term,
  3101 													return {id: term,
  3095 															text: (data.amsSelect2FreeTagsPrefix || ams.i18n.SELECT2_FREETAG_PREFIX) + term};
  3102 															text: (data.amsSelect2FreeTagsPrefix || ams.i18n.SELECT2_FREETAG_PREFIX) + term};
  3096 												};
  3103 												};
  3097 											}
  3104 											}
  3098 
  3105 
  3099 											var settings = $.extend({}, data_options, data.amsSelect2Options);
  3106 											var settings = $.extend({}, dataOptions, data.amsSelect2Options);
  3100 											settings = ams.executeFunctionByName(data.amsSelect2InitCallback, select, settings) || settings;
  3107 											settings = ams.executeFunctionByName(data.amsSelect2InitCallback, select, settings) || settings;
  3101 											var plugin = select.select2(settings);
  3108 											var plugin = select.select2(settings);
  3102 											ams.executeFunctionByName(data.amsSelect2AfterInitCallback, select, plugin, settings);
  3109 											ams.executeFunctionByName(data.amsSelect2AfterInitCallback, select, plugin, settings);
  3103 											if (select.hasClass('ordered')) {
  3110 											if (select.hasClass('ordered')) {
  3104 												ams.ajax.check($.fn.select2Sortable,
  3111 												ams.ajax.check($.fn.select2Sortable,
  3131 								   ams.baseURL + 'ext/jquery-maskedinput-1.4.1' + ams.devext + '.js',
  3138 								   ams.baseURL + 'ext/jquery-maskedinput-1.4.1' + ams.devext + '.js',
  3132 								   function() {
  3139 								   function() {
  3133 										masks.each(function() {
  3140 										masks.each(function() {
  3134 											var mask = $(this);
  3141 											var mask = $(this);
  3135 											var data = mask.data();
  3142 											var data = mask.data();
  3136 											var data_options = {
  3143 											var dataOptions = {
  3137 												placeholder: data.amsMaskeditPlaceholder === undefined ? 'X' : data.amsMaskeditPlaceholder,
  3144 												placeholder: data.amsMaskeditPlaceholder === undefined ? 'X' : data.amsMaskeditPlaceholder,
  3138 												complete: ams.getFunctionByName(data.amsMaskeditComplete)
  3145 												complete: ams.getFunctionByName(data.amsMaskeditComplete)
  3139 											};
  3146 											};
  3140 											var settings = $.extend({}, data_options, data.amsMaskeditOptions);
  3147 											var settings = $.extend({}, dataOptions, data.amsMaskeditOptions);
  3141 											settings = ams.executeFunctionByName(data.amsMaskeditInitCallback, mask, settings) || settings;
  3148 											settings = ams.executeFunctionByName(data.amsMaskeditInitCallback, mask, settings) || settings;
  3142 											var plugin = mask.mask(mask.attr('data-mask'), settings);
  3149 											var plugin = mask.mask(mask.attr('data-mask'), settings);
  3143 											ams.executeFunctionByName(data.amsMaskeditAfterInitCallback, mask, plugin, settings);
  3150 											ams.executeFunctionByName(data.amsMaskeditAfterInitCallback, mask, plugin, settings);
  3144 										});
  3151 										});
  3145 								   });
  3152 								   });
  3161 								   ams.baseURL + 'ext/jquery-inputmask-bundle-3.2.8' + ams.devext + '.js',
  3168 								   ams.baseURL + 'ext/jquery-inputmask-bundle-3.2.8' + ams.devext + '.js',
  3162 								   function() {
  3169 								   function() {
  3163 										masks.each(function() {
  3170 										masks.each(function() {
  3164 											var input = $(this);
  3171 											var input = $(this);
  3165 											var data = input.data();
  3172 											var data = input.data();
  3166 											var data_options;
  3173 											var dataOptions;
  3167 											if (typeof(data.inputMask) === 'object') {
  3174 											if (typeof(data.inputMask) === 'object') {
  3168 												data_options = data.inputMask;
  3175 												dataOptions = data.inputMask;
  3169 											} else {
  3176 											} else {
  3170 												data_options = {
  3177 												dataOptions = {
  3171 													mask: data.inputMask.toString()
  3178 													mask: data.inputMask.toString()
  3172 												};
  3179 												};
  3173 											}
  3180 											}
  3174 											var settings = $.extend({}, data_options, data.amsInputmaskOptions);
  3181 											var settings = $.extend({}, dataOptions, data.amsInputmaskOptions);
  3175 											settings = ams.executeFunctionByName(data.amsInputmaskInitCallback, input, settings) || settings;
  3182 											settings = ams.executeFunctionByName(data.amsInputmaskInitCallback, input, settings) || settings;
  3176 											var plugin = input.inputmask(settings);
  3183 											var plugin = input.inputmask(settings);
  3177 											ams.executeFunctionByName(data.amsInputmaskAfterInitCallback, input, plugin, settings);
  3184 											ams.executeFunctionByName(data.amsInputmaskAfterInitCallback, input, plugin, settings);
  3178 										});
  3185 										});
  3179 								   });
  3186 								   });
  3194 											ams.dialog.registerHideCallback(ams.helpers.datetimepickerDialogHiddenCallback);
  3201 											ams.dialog.registerHideCallback(ams.helpers.datetimepickerDialogHiddenCallback);
  3195 										}
  3202 										}
  3196 										datepickers.each(function() {
  3203 										datepickers.each(function() {
  3197 											var input = $(this);
  3204 											var input = $(this);
  3198 											var data = input.data();
  3205 											var data = input.data();
  3199 											var data_options = {
  3206 											var dataOptions = {
  3200 												lang: data.amsDatetimepickerLang || ams.lang,
  3207 												lang: data.amsDatetimepickerLang || ams.lang,
  3201 												format: data.amsDatetimepickerFormat || 'd/m/y',
  3208 												format: data.amsDatetimepickerFormat || 'd/m/y',
  3202 												datepicker: true,
  3209 												datepicker: true,
  3203 												dayOfWeekStart: 1,
  3210 												dayOfWeekStart: 1,
  3204 												timepicker: false
  3211 												timepicker: false
  3205 											};
  3212 											};
  3206 											var settings = $.extend({}, data_options, data.amsDatetimepickerOptions);
  3213 											var settings = $.extend({}, dataOptions, data.amsDatetimepickerOptions);
  3207 											settings = ams.executeFunctionByName(data.amsDatetimepickerInitCallback, input, settings) || settings;
  3214 											settings = ams.executeFunctionByName(data.amsDatetimepickerInitCallback, input, settings) || settings;
  3208 											var plugin = input.datetimepicker(settings);
  3215 											var plugin = input.datetimepicker(settings);
  3209 											ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings);
  3216 											ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings);
  3210 										});
  3217 										});
  3211 								   });
  3218 								   });
  3226 											ams.dialog.registerHideCallback(ams.helpers.datetimepickerDialogHiddenCallback);
  3233 											ams.dialog.registerHideCallback(ams.helpers.datetimepickerDialogHiddenCallback);
  3227 										}
  3234 										}
  3228 										datetimepickers.each(function() {
  3235 										datetimepickers.each(function() {
  3229 											var input = $(this);
  3236 											var input = $(this);
  3230 											var data = input.data();
  3237 											var data = input.data();
  3231 											var data_options = {
  3238 											var dataOptions = {
  3232 												lang: data.amsDatetimepickerLang || ams.lang,
  3239 												lang: data.amsDatetimepickerLang || ams.lang,
  3233 												format: data.amsDatetimepickerFormat || 'd/m/y H:i',
  3240 												format: data.amsDatetimepickerFormat || 'd/m/y H:i',
  3234 												datepicker: true,
  3241 												datepicker: true,
  3235 												dayOfWeekStart: 1,
  3242 												dayOfWeekStart: 1,
  3236 												timepicker: true
  3243 												timepicker: true
  3237 											};
  3244 											};
  3238 											var settings = $.extend({}, data_options, data.amsDatetimepickerOptions);
  3245 											var settings = $.extend({}, dataOptions, data.amsDatetimepickerOptions);
  3239 											settings = ams.executeFunctionByName(data.amsDatetimepickerInitCallback, input, settings) || settings;
  3246 											settings = ams.executeFunctionByName(data.amsDatetimepickerInitCallback, input, settings) || settings;
  3240 											var plugin = input.datetimepicker(settings);
  3247 											var plugin = input.datetimepicker(settings);
  3241 											ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings);
  3248 											ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings);
  3242 										});
  3249 										});
  3243 								   });
  3250 								   });
  3258 											ams.dialog.registerHideCallback(ams.helpers.datetimepickerDialogHiddenCallback);
  3265 											ams.dialog.registerHideCallback(ams.helpers.datetimepickerDialogHiddenCallback);
  3259 										}
  3266 										}
  3260 										timepickers.each(function() {
  3267 										timepickers.each(function() {
  3261 											var input = $(this);
  3268 											var input = $(this);
  3262 											var data = input.data();
  3269 											var data = input.data();
  3263 											var data_options = {
  3270 											var dataOptions = {
  3264 												lang: data.amsDatetimepickerLang || ams.lang,
  3271 												lang: data.amsDatetimepickerLang || ams.lang,
  3265 												format: data.amsDatetimepickerFormat || 'H:i',
  3272 												format: data.amsDatetimepickerFormat || 'H:i',
  3266 												datepicker: false,
  3273 												datepicker: false,
  3267 												timepicker: true
  3274 												timepicker: true
  3268 											};
  3275 											};
  3269 											var settings = $.extend({}, data_options, data.amsDatetimepickerOptions);
  3276 											var settings = $.extend({}, dataOptions, data.amsDatetimepickerOptions);
  3270 											settings = ams.executeFunctionByName(data.amsDatetimepickerInitCallback, input, settings) || settings;
  3277 											settings = ams.executeFunctionByName(data.amsDatetimepickerInitCallback, input, settings) || settings;
  3271 											var plugin = input.datetimepicker(settings);
  3278 											var plugin = input.datetimepicker(settings);
  3272 											ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings);
  3279 											ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings);
  3273 										});
  3280 										});
  3274 								   });
  3281 								   });
  3288 											ams.getCSS(ams.baseURL + '../css/ext/jquery-minicolors' + ams.devext + '.css', 'jquery-minicolors');
  3295 											ams.getCSS(ams.baseURL + '../css/ext/jquery-minicolors' + ams.devext + '.css', 'jquery-minicolors');
  3289 										}
  3296 										}
  3290 										colorpickers.each(function() {
  3297 										colorpickers.each(function() {
  3291 											var input = $(this);
  3298 											var input = $(this);
  3292 											var data = input.data();
  3299 											var data = input.data();
  3293 											var data_options = {
  3300 											var dataOptions = {
  3294 												position: data.amsColorpickerPosition || input.closest('label.input').data('ams-colorpicker-position') || 'bottom left'
  3301 												position: data.amsColorpickerPosition || input.closest('label.input').data('ams-colorpicker-position') || 'bottom left'
  3295 											};
  3302 											};
  3296 											var settings = $.extend({}, data_options, data.amsColorpickerOptions);
  3303 											var settings = $.extend({}, dataOptions, data.amsColorpickerOptions);
  3297 											settings = ams.executeFunctionByName(data.amsColorpickerInitCallback, input, settings) || settings;
  3304 											settings = ams.executeFunctionByName(data.amsColorpickerInitCallback, input, settings) || settings;
  3298 											var plugin = input.minicolors(settings);
  3305 											var plugin = input.minicolors(settings);
  3299 											ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings);
  3306 											ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings);
  3300 										});
  3307 										});
  3301 								   });
  3308 								   });
  3345 											}
  3352 											}
  3346 										}
  3353 										}
  3347 										forms.each(function() {
  3354 										forms.each(function() {
  3348 											var form = $(this);
  3355 											var form = $(this);
  3349 											var data = form.data();
  3356 											var data = form.data();
  3350 											var data_options = {
  3357 											var dataOptions = {
  3351 												ignore: null,
  3358 												ignore: null,
  3352 												submitHandler: form.attr('data-async') !== undefined ?
  3359 												submitHandler: form.attr('data-async') !== undefined ?
  3353 															   data.amsFormSubmitHandler === undefined ?
  3360 															   data.amsFormSubmitHandler === undefined ?
  3354 																	function() {
  3361 																	function() {
  3355 																		// JQuery-form plug-in must be loaded synchronously!!
  3362 																		// JQuery-form plug-in must be loaded synchronously!!
  3367 																data.amsFormInvalidHandler === undefined ?
  3374 																data.amsFormInvalidHandler === undefined ?
  3368 																	function(event, validator) {
  3375 																	function(event, validator) {
  3369 																		$('.state-error', form).removeClass('state-error');
  3376 																		$('.state-error', form).removeClass('state-error');
  3370 																		for (var index=0; index < validator.errorList.length; index++) {
  3377 																		for (var index=0; index < validator.errorList.length; index++) {
  3371 																			var error = validator.errorList[index];
  3378 																			var error = validator.errorList[index];
  3372 																			var tab_index = $(error.element).parents('.tab-pane').index() + 1;
  3379 																			var tabIndex = $(error.element).parents('.tab-pane').index() + 1;
  3373 																			if (tab_index > 0) {
  3380 																			if (tabIndex > 0) {
  3374 																				var nav_tabs = $('.nav-tabs', $(error.element).parents('.tabforms'));
  3381 																				var navTabs = $('.nav-tabs', $(error.element).parents('.tabforms'));
  3375 																				$('li:nth-child(' + tab_index + ')', nav_tabs)
  3382 																				$('li:nth-child(' + tabIndex + ')', navTabs)
  3376 																						.removeClassPrefix('state-')
  3383 																						.removeClassPrefix('state-')
  3377 																						.addClass('state-error');
  3384 																						.addClass('state-error');
  3378 																				$('li.state-error:first a', nav_tabs).click();
  3385 																				$('li.state-error:first a', navTabs).click();
  3379 																			}
  3386 																			}
  3380 																		}
  3387 																		}
  3381 																	}
  3388 																	}
  3382 																	: ams.getFunctionByName(data.amsFormInvalidHandler)
  3389 																	: ams.getFunctionByName(data.amsFormInvalidHandler)
  3383 																: undefined
  3390 																: undefined
  3384 											};
  3391 											};
  3385 											$('[data-ams-validate-rules]', form).each(function(index) {
  3392 											$('[data-ams-validate-rules]', form).each(function(index) {
  3386 												if (index === 0) {
  3393 												if (index === 0) {
  3387 													data_options.rules = {};
  3394 													dataOptions.rules = {};
  3388 												}
  3395 												}
  3389 												data_options.rules[$(this).attr('name')] = $(this).data('ams-validate-rules');
  3396 												dataOptions.rules[$(this).attr('name')] = $(this).data('ams-validate-rules');
  3390 											});
  3397 											});
  3391 											var settings = $.extend({}, data_options, data.amsValidateOptions);
  3398 											var settings = $.extend({}, dataOptions, data.amsValidateOptions);
  3392 											settings = ams.executeFunctionByName(data.amsValidateInitCallback, form, settings) || settings;
  3399 											settings = ams.executeFunctionByName(data.amsValidateInitCallback, form, settings) || settings;
  3393 											var plugin = form.validate(settings);
  3400 											var plugin = form.validate(settings);
  3394 											ams.executeFunctionByName(data.amsValidateAfterInitCallback, form, plugin, settings);
  3401 											ams.executeFunctionByName(data.amsValidateAfterInitCallback, form, plugin, settings);
  3395 										});
  3402 										});
  3396 								   });
  3403 								   });
  3433 											var sorting = data.amsDatatableSorting;
  3440 											var sorting = data.amsDatatableSorting;
  3434 											if (typeof(sorting) === 'string') {
  3441 											if (typeof(sorting) === 'string') {
  3435 												var sortings = sorting.split(';');
  3442 												var sortings = sorting.split(';');
  3436 												sorting = [];
  3443 												sorting = [];
  3437 												for (index=0; index < sortings.length; index++) {
  3444 												for (index=0; index < sortings.length; index++) {
  3438 													var col_sorting = sortings[index].split(',');
  3445 													var colSorting = sortings[index].split(',');
  3439 													col_sorting[0] = parseInt(col_sorting[0]);
  3446 													colSorting[0] = parseInt(colSorting[0]);
  3440 													sorting.push(col_sorting);
  3447 													sorting.push(colSorting);
       
  3448 												}
       
  3449 											}
       
  3450 											// Check columns sortings
       
  3451 											var columns = [];
       
  3452 											var column;
       
  3453 											var sortables = $('th', table).listattr('data-ams-datatable-sortable');
       
  3454 											for (index=0; index < sortables.length; index++) {
       
  3455 												var sortable = sortables[index];
       
  3456 												if (sortable !== undefined) {
       
  3457 													column = columns[index] || {};
       
  3458 													column.bSortable = sortable;
       
  3459 													columns[index] = column;
  3441 												}
  3460 												}
  3442 											}
  3461 											}
  3443 											// Check columns types
  3462 											// Check columns types
  3444 											var columns = [];
  3463 											var sortTypes = $('th', table).listattr('data-ams-datatable-stype');
  3445 											var sort_types = $('th', table).listattr('data-ams-datatable-stype');
  3464 											for (index=0; index < sortTypes.length; index++) {
  3446 											for (index=0; index < sort_types.length; index++) {
  3465 												var sortType = sortTypes[index];
  3447 												var sort_type = sort_types[index];
  3466 												if (sortType) {
  3448 												if (sort_type) {
  3467 													column = columns[index] || {};
  3449 													var column = columns[index] || {};
  3468 													column.sType = sortType;
  3450 													column.sType = sort_type;
       
  3451 													columns[index] = column;
  3469 													columns[index] = column;
  3452 												}
  3470 												}
  3453 											}
  3471 											}
  3454 											// Set options
  3472 											// Set options
  3455 											var data_options = {
  3473 											var dataOptions = {
  3456 												bJQueryUI: false,
  3474 												bJQueryUI: false,
  3457 												bFilter: data.amsDatatableGlobalFilter !== false || extensions.indexOf('columnfilter') >= 0,
  3475 												bFilter: data.amsDatatableGlobalFilter !== false || extensions.indexOf('columnfilter') >= 0,
  3458 												bPaginate: data.amsDatatablePagination !== false,
  3476 												bPaginate: data.amsDatatablePagination !== false,
  3459 												bInfo: data.amsDatatableInfo !== false,
  3477 												bInfo: data.amsDatatableInfo !== false,
  3460 												bSort: data.amsDatatableSort !== false,
  3478 												bSort: data.amsDatatableSort !== false,
  3466 												sPaginationType: data.amsDatatablePaginationType || 'bootstrap_full',
  3484 												sPaginationType: data.amsDatatablePaginationType || 'bootstrap_full',
  3467 												sDom: sDom,
  3485 												sDom: sDom,
  3468 												oLanguage: ams.plugins.i18n.datatables,
  3486 												oLanguage: ams.plugins.i18n.datatables,
  3469 												fnInitComplete: function(oSettings, json) {
  3487 												fnInitComplete: function(oSettings, json) {
  3470 													$('.ColVis_Button').addClass('btn btn-default btn-sm')
  3488 													$('.ColVis_Button').addClass('btn btn-default btn-sm')
  3471 																	   .html((ams.plugins.i18n.datatables.sColumns || "Columns") + ' <i class="fa fa-fw fa-caret-down"></i>');
  3489 																	   .html((ams.plugins.i18n.datatables.sColumns || "Columns") +
       
  3490 																			 ' <i class="fa fa-fw fa-caret-down"></i>');
  3472 												}
  3491 												}
  3473 											};
  3492 											};
  3474 											var settings = $.extend({}, data_options, data.amsDatatableOptions);
  3493 											var settings = $.extend({}, dataOptions, data.amsDatatableOptions);
  3475 											if (extensions.length > 0) {
  3494 											if (extensions.length > 0) {
  3476 												for (index=0; index < extensions.length; index++) {
  3495 												for (index=0; index < extensions.length; index++) {
  3477 													switch (extensions[index]) {
  3496 													switch (extensions[index]) {
  3478 														case 'autofill':
  3497 														case 'autofill':
  3479 															ams.ajax.check($.fn.dataTable.AutoFill,
  3498 															ams.ajax.check($.fn.dataTable.AutoFill,
  3492 																		   ams.baseURL + 'ext/jquery-dataTables-colReorderWithResize' + ams.devext + '.js');
  3511 																		   ams.baseURL + 'ext/jquery-dataTables-colReorderWithResize' + ams.devext + '.js');
  3493 															break;
  3512 															break;
  3494 														case 'colvis':
  3513 														case 'colvis':
  3495 															ams.ajax.check($.fn.dataTable.ColVis,
  3514 															ams.ajax.check($.fn.dataTable.ColVis,
  3496 																		   ams.baseURL + 'ext/jquery-dataTables-colVis' + ams.devext + '.js');
  3515 																		   ams.baseURL + 'ext/jquery-dataTables-colVis' + ams.devext + '.js');
  3497 															var cv_default = {
  3516 															var cvDefault = {
  3498 																activate: 'click',
  3517 																activate: 'click',
  3499 																sAlign: 'right'
  3518 																sAlign: 'right'
  3500 															};
  3519 															};
  3501 															settings.oColVis = $.extend({}, cv_default, data.amsDatatableColvisOptions);
  3520 															settings.oColVis = $.extend({}, cvDefault, data.amsDatatableColvisOptions);
  3502 															break;
  3521 															break;
  3503 														case 'editable':
  3522 														case 'editable':
  3504 															ams.ajax.check($.fn.editable,
  3523 															ams.ajax.check($.fn.editable,
  3505 																		   ams.baseURL + 'ext/jquery-jeditable' + ams.devext + '.js');
  3524 																		   ams.baseURL + 'ext/jquery-jeditable' + ams.devext + '.js');
  3506 															ams.ajax.check($.fn.makeEditable,
  3525 															ams.ajax.check($.fn.makeEditable,
  3541 												ams.executeFunctionByName(data.amsDatatableAfterInitCallback, table, plugin, settings);
  3560 												ams.executeFunctionByName(data.amsDatatableAfterInitCallback, table, plugin, settings);
  3542 												if (extensions.length > 0) {
  3561 												if (extensions.length > 0) {
  3543 													for (index=0; index < extensions.length; index++) {
  3562 													for (index=0; index < extensions.length; index++) {
  3544 														switch (extensions[index]) {
  3563 														switch (extensions[index]) {
  3545 															case 'autofill':
  3564 															case 'autofill':
  3546 																var af_settings = $.extend({}, data.amsDatatableAutofillOptions, settings.autofill);
  3565 																var afSettings = $.extend({}, data.amsDatatableAutofillOptions, settings.autofill);
  3547 																af_settings = ams.executeFunctionByName(data.amsDatatableAutofillInitCallback, table, af_settings) || af_settings;
  3566 																afSettings = ams.executeFunctionByName(data.amsDatatableAutofillInitCallback, table, afSettings) || afSettings;
  3548 																table.data('ams-autofill', data.amsDatatableAutofillConstructor === undefined ?
  3567 																table.data('ams-autofill', data.amsDatatableAutofillConstructor === undefined ?
  3549 																							new $.fn.dataTable.AutoFill(table, af_settings)
  3568 																							new $.fn.dataTable.AutoFill(table, afSettings)
  3550 																							: ams.executeFunctionByName(data.amsDatatableAutofillConstructor, table, plugin, af_settings));
  3569 																							: ams.executeFunctionByName(data.amsDatatableAutofillConstructor, table, plugin, afSettings));
  3551 																break;
  3570 																break;
  3552 															case 'columnfilter':
  3571 															case 'columnfilter':
  3553 																var cf_default = {
  3572 																var cfDefault = {
  3554 																	sPlaceHolder: 'head:after'
  3573 																	sPlaceHolder: 'head:after'
  3555 																};
  3574 																};
  3556 																var cf_settings = $.extend({}, cf_default, data.amsDatatableColumnfilterOptions, settings.columnfilter);
  3575 																var cfSettings = $.extend({}, cfDefault, data.amsDatatableColumnfilterOptions, settings.columnfilter);
  3557 																cf_settings = ams.executeFunctionByName(data.amsDatatableColumnfilterInitCallback, table, cf_settings) || cf_settings;
  3576 																cfSettings = ams.executeFunctionByName(data.amsDatatableColumnfilterInitCallback, table, cfSettings) || cfSettings;
  3558 																table.data('ams-columnfilter', data.amsDatatableColumnfilterConstructor === undefined ?
  3577 																table.data('ams-columnfilter', data.amsDatatableColumnfilterConstructor === undefined ?
  3559 																							plugin.columnFilter(cf_settings)
  3578 																							plugin.columnFilter(cfSettings)
  3560 																							: ams.executeFunctionByName(data.amsDatatableColumnfilterConstructor, table, plugin, cf_settings));
  3579 																							: ams.executeFunctionByName(data.amsDatatableColumnfilterConstructor, table, plugin, cfSettings));
  3561 																break;
  3580 																break;
  3562 															case 'editable':
  3581 															case 'editable':
  3563 																var ed_settings = $.extend({}, data.amsDatatableEditableOptions, settings.editable);
  3582 																var edSettings = $.extend({}, data.amsDatatableEditableOptions, settings.editable);
  3564 																ed_settings = ams.executeFunctionByName(data.amsDatatableEditableInitCallback, table, ed_settings) || ed_settings;
  3583 																edSettings = ams.executeFunctionByName(data.amsDatatableEditableInitCallback, table, edSettings) || edSettings;
  3565 																table.data('ams-editable', data.amsDatatableEditableConstructor === undefined ?
  3584 																table.data('ams-editable', data.amsDatatableEditableConstructor === undefined ?
  3566 																							table.makeEditable(ed_settings)
  3585 																							table.makeEditable(edSettings)
  3567 																							: ams.executeFunctionByName(data.amsDatatableEditableConstructor, table, plugin, ed_settings));
  3586 																							: ams.executeFunctionByName(data.amsDatatableEditableConstructor, table, plugin, edSettings));
  3568 																break;
  3587 																break;
  3569 															case 'fixedcolumns':
  3588 															case 'fixedcolumns':
  3570 																var fc_settings = $.extend({}, data.amsDatatableFixedcolumnsOptions, settings.fixedcolumns);
  3589 																var fcSettings = $.extend({}, data.amsDatatableFixedcolumnsOptions, settings.fixedcolumns);
  3571 																fc_settings = ams.executeFunctionByName(data.amsDatatableFixedcolumnsInitCallback, table, fc_settings) || fc_settings;
  3590 																fcSettings = ams.executeFunctionByName(data.amsDatatableFixedcolumnsInitCallback, table, fcSettings) || fcSettings;
  3572 																table.data('ams-fixedcolumns', data.amsDatatableFixedcolumnsConstructor === undefined ?
  3591 																table.data('ams-fixedcolumns', data.amsDatatableFixedcolumnsConstructor === undefined ?
  3573 																							new $.fn.dataTable.FixedColumns(table, fc_settings)
  3592 																							new $.fn.dataTable.FixedColumns(table, fcSettings)
  3574 																							: ams.executeFunctionByName(data.amsDatatableFixedcolumnsConstructor, table, plugin, fc_settings));
  3593 																							: ams.executeFunctionByName(data.amsDatatableFixedcolumnsConstructor, table, plugin, fcSettings));
  3575 																break;
  3594 																break;
  3576 															case 'fixedheader':
  3595 															case 'fixedheader':
  3577 																var fh_settings = $.extend({}, data.amsDatatableFixedheaderOptions, settings.fixedheader);
  3596 																var fhSettings = $.extend({}, data.amsDatatableFixedheaderOptions, settings.fixedheader);
  3578 																fh_settings = ams.executeFunctionByName(data.amsDatatableFixedheadeInitCallback, table, fh_settings) || fh_settings;
  3597 																fhSettings = ams.executeFunctionByName(data.amsDatatableFixedheadeInitCallback, table, fhSettings) || fhSettings;
  3579 																table.data('ams-fixedheader', data.amsDatatableFixedheaderConstructor === undefined ?
  3598 																table.data('ams-fixedheader', data.amsDatatableFixedheaderConstructor === undefined ?
  3580 																							new $.fn.dataTable.FixedHeader(table, fh_settings)
  3599 																							new $.fn.dataTable.FixedHeader(table, fhSettings)
  3581 																							: ams.executeFunctionByName(data.amsDatatableFixedheaderConstructor, table, plugin, fh_settings));
  3600 																							: ams.executeFunctionByName(data.amsDatatableFixedheaderConstructor, table, plugin, fhSettings));
  3582 																break;
  3601 																break;
  3583 															case 'keytable':
  3602 															case 'keytable':
  3584 																var kt_default = {
  3603 																var ktDefault = {
  3585 																	table: table.get(0),
  3604 																	table: table.get(0),
  3586 																	datatable: plugin
  3605 																	datatable: plugin
  3587 																};
  3606 																};
  3588 																var kt_settings = $.extend({}, kt_default, data.amsDatatableKeytableOptions, settings.keytable);
  3607 																var ktSettings = $.extend({}, ktDefault, data.amsDatatableKeytableOptions, settings.keytable);
  3589 																kt_settings = ams.executeFunctionByName(data.amsDatatableKeytableInitCallback, table, kt_settings) || kt_settings;
  3608 																ktSettings = ams.executeFunctionByName(data.amsDatatableKeytableInitCallback, table, ktSettings) || ktSettings;
  3590 																table.data('ams-keytable', data.amsDatatableKeytableConstructor === undefined ?
  3609 																table.data('ams-keytable', data.amsDatatableKeytableConstructor === undefined ?
  3591 																							new KeyTable(kt_settings)
  3610 																							new KeyTable(ktSettings)
  3592 																							: ams.executeFunctionByName(data.amsDatatableKeytableConstructor, table, plugin, kt_settings));
  3611 																							: ams.executeFunctionByName(data.amsDatatableKeytableConstructor, table, plugin, ktSettings));
  3593 																break;
  3612 																break;
  3594 															case 'rowgrouping':
  3613 															case 'rowgrouping':
  3595 																var rg_settings = $.extend({}, data.amsDatatableRowgroupingOptions, settings.rowgrouping);
  3614 																var rgSettings = $.extend({}, data.amsDatatableRowgroupingOptions, settings.rowgrouping);
  3596 																rg_settings = ams.executeFunctionByName(data.amsDatatableRowgroupingInitCallback, table, rg_settings) || rg_settings;
  3615 																rgSettings = ams.executeFunctionByName(data.amsDatatableRowgroupingInitCallback, table, rgSettings) || rgSettings;
  3597 																table.data('ams-rowgrouping', data.amsDatatableRowgroupingConstructor === undefined ?
  3616 																table.data('ams-rowgrouping', data.amsDatatableRowgroupingConstructor === undefined ?
  3598 																							table.rowGrouping(rg_settings)
  3617 																							table.rowGrouping(rgSettings)
  3599 																							: ams.executeFunctionByName(data.amsDatatableRowgroupingConstructor, table, plugin, rg_settings));
  3618 																							: ams.executeFunctionByName(data.amsDatatableRowgroupingConstructor, table, plugin, rgSettings));
  3600 																break;
  3619 																break;
  3601 															case 'rowreordering':
  3620 															case 'rowreordering':
  3602 																var rr_settings = $.extend({}, data.amsDatatableRowreorderingOptions, settings.rowreordering);
  3621 																var rrSettings = $.extend({}, data.amsDatatableRowreorderingOptions, settings.rowreordering);
  3603 																rr_settings = ams.executeFunctionByName(data.amsDatatableRowreorderingInitCallback, table, rr_settings) || rr_settings;
  3622 																rrSettings = ams.executeFunctionByName(data.amsDatatableRowreorderingInitCallback, table, rrSettings) || rrSettings;
  3604 																table.data('ams-rowreordering', data.amsDatatableRowreorderingConstructor === undefined ?
  3623 																table.data('ams-rowreordering', data.amsDatatableRowreorderingConstructor === undefined ?
  3605 																							table.rowReordering(rr_settings)
  3624 																							table.rowReordering(rrSettings)
  3606 																							: ams.executeFunctionByName(data.amsDatatableRowreorderingConstructor, table, plugin, rr_settings));
  3625 																							: ams.executeFunctionByName(data.amsDatatableRowreorderingConstructor, table, plugin, rrSettings));
  3607 																break;
  3626 																break;
  3608 															default:
  3627 															default:
  3609 																break;
  3628 																break;
  3610 														}
  3629 														}
  3611 													}
  3630 													}
  3642 													$(this.cells[0]).addClass('drag-handle');
  3661 													$(this.cells[0]).addClass('drag-handle');
  3643 												}).on('mouseout', 'tr', function () {
  3662 												}).on('mouseout', 'tr', function () {
  3644 													$(this.cells[0]).removeClass('drag-handle');
  3663 													$(this.cells[0]).removeClass('drag-handle');
  3645 												});
  3664 												});
  3646 											}
  3665 											}
  3647 											var data_options = {
  3666 											var dataOptions = {
  3648 												onDragClass: data.amsTabledndDragClass || 'dragging-row',
  3667 												onDragClass: data.amsTabledndDragClass || 'dragging-row',
  3649 												onDragStart: ams.getFunctionByName(data.amsTabledndDragStart),
  3668 												onDragStart: ams.getFunctionByName(data.amsTabledndDragStart),
  3650 												dragHandle: data.amsTabledndDragHandle,
  3669 												dragHandle: data.amsTabledndDragHandle,
  3651 												scrollAmount: data.amsTabledndScrollAmount,
  3670 												scrollAmount: data.amsTabledndScrollAmount,
  3652 												onAllowDrop: data.amsTabledndAllowDrop,
  3671 												onAllowDrop: data.amsTabledndAllowDrop,
  3655 													if (target) {
  3674 													if (target) {
  3656 														// Disable row click handler
  3675 														// Disable row click handler
  3657 														$(row).data('ams-disabled-handlers', 'click');
  3676 														$(row).data('ams-disabled-handlers', 'click');
  3658 														var rows = [];
  3677 														var rows = [];
  3659 														$(dnd_table.rows).each(function() {
  3678 														$(dnd_table.rows).each(function() {
  3660 															var row_id = $(this).data('ams-element-name');
  3679 															var rowId = $(this).data('ams-element-name');
  3661 															if (row_id) {
  3680 															if (rowId) {
  3662 																rows.push(row_id);
  3681 																rows.push(rowId);
  3663 															}
  3682 															}
  3664 														});
  3683 														});
  3665 														var local_target = ams.getFunctionByName(target);
  3684 														var localTarget = ams.getFunctionByName(target);
  3666 														if (typeof(local_target) === 'function') {
  3685 														if (typeof(localTarget) === 'function') {
  3667 															local_target.call(table, dnd_table, rows);
  3686 															localTarget.call(table, dnd_table, rows);
  3668 														} else {
  3687 														} else {
  3669 															ams.ajax.post(target, {names: JSON.stringify(rows)});
  3688 															ams.ajax.post(target, {names: JSON.stringify(rows)});
  3670 														}
  3689 														}
  3671 														// Restore row click handler
  3690 														// Restore row click handler
  3672 														setTimeout(function() {
  3691 														setTimeout(function() {
  3674 														}, 50);
  3693 														}, 50);
  3675 													}
  3694 													}
  3676 													return false;
  3695 													return false;
  3677 												}
  3696 												}
  3678 											};
  3697 											};
  3679 											var settings = $.extend({}, data_options, data.amsTabledndOptions);
  3698 											var settings = $.extend({}, dataOptions, data.amsTabledndOptions);
  3680 											settings = ams.executeFunctionByName(data.amsTabledndInitCallback, table, settings) || settings;
  3699 											settings = ams.executeFunctionByName(data.amsTabledndInitCallback, table, settings) || settings;
  3681 											var plugin = table.tableDnD(settings);
  3700 											var plugin = table.tableDnD(settings);
  3682 											ams.executeFunctionByName(data.amsTabledndAfterInitCallback, table, plugin, settings);
  3701 											ams.executeFunctionByName(data.amsTabledndAfterInitCallback, table, plugin, settings);
  3683 										});
  3702 										});
  3684 								   });
  3703 								   });
  3699 									   }
  3718 									   }
  3700 									   images.each(function() {
  3719 									   images.each(function() {
  3701 										   var image = $(this);
  3720 										   var image = $(this);
  3702 										   var data = image.data();
  3721 										   var data = image.data();
  3703 										   var parent = data.amsImgareaselectParent ? image.parents(data.amsImgareaselectParent) : 'body';
  3722 										   var parent = data.amsImgareaselectParent ? image.parents(data.amsImgareaselectParent) : 'body';
  3704 										   var data_options = {
  3723 										   var dataOptions = {
  3705 											   instance: true,
  3724 											   instance: true,
  3706 											   handles: true,
  3725 											   handles: true,
  3707 											   parent: parent,
  3726 											   parent: parent,
  3708 											   x1: data.amsImgareaselectX1 || 0,
  3727 											   x1: data.amsImgareaselectX1 || 0,
  3709 											   y1: data.amsImgareaselectY1 || 0,
  3728 											   y1: data.amsImgareaselectY1 || 0,
  3720 												   $('input[name="' + target + 'y1"]', parent).val(selection.y1);
  3739 												   $('input[name="' + target + 'y1"]', parent).val(selection.y1);
  3721 												   $('input[name="' + target + 'x2"]', parent).val(selection.x2);
  3740 												   $('input[name="' + target + 'x2"]', parent).val(selection.x2);
  3722 												   $('input[name="' + target + 'y2"]', parent).val(selection.y2);
  3741 												   $('input[name="' + target + 'y2"]', parent).val(selection.y2);
  3723 											   }
  3742 											   }
  3724 										   };
  3743 										   };
  3725 										   var settings = $.extend({}, data_options, data.amsImgareaselectOptions);
  3744 										   var settings = $.extend({}, dataOptions, data.amsImgareaselectOptions);
  3726 										   settings = ams.executeFunctionByName(data.amsImgareaselectInitCallback, image, settings) || settings;
  3745 										   settings = ams.executeFunctionByName(data.amsImgareaselectInitCallback, image, settings) || settings;
  3727 										   var plugin = image.imgAreaSelect(settings);
  3746 										   var plugin = image.imgAreaSelect(settings);
  3728 										   ams.executeFunctionByName(data.amsImgareaselectAfterInitCallback, image, plugin, settings);
  3747 										   ams.executeFunctionByName(data.amsImgareaselectAfterInitCallback, image, plugin, settings);
  3729 										   // Add update timeout when plug-in is displayed into a modal dialog
  3748 										   // Add update timeout when plug-in is displayed into a modal dialog
  3730 										   setTimeout(function() {
  3749 										   setTimeout(function() {
  3770 														default:
  3789 														default:
  3771 															break;
  3790 															break;
  3772 													}
  3791 													}
  3773 												}
  3792 												}
  3774 											}
  3793 											}
  3775 											var data_options = {
  3794 											var dataOptions = {
  3776 												type: data.amsFancyboxType,
  3795 												type: data.amsFancyboxType,
  3777 												padding: data.amsFancyboxPadding || 10,
  3796 												padding: data.amsFancyboxPadding || 10,
  3778 												margin: data.amsFancyboxMargin || 10,
  3797 												margin: data.amsFancyboxMargin || 10,
  3779 												beforeLoad: ams.getFunctionByName(data.amsFancyboxBeforeLoad) || function() {
  3798 												beforeLoad: ams.getFunctionByName(data.amsFancyboxBeforeLoad) || function() {
  3780 													this.title = ams.executeFunctionByName(data.amsFancyboxTitleGetter, this) || $(this.element).attr('original-title') || $(this.element).attr('title');
  3799 													this.title = ams.executeFunctionByName(data.amsFancyboxTitleGetter, this) || $(this.element).attr('original-title') || $(this.element).attr('title');
  3783 													title: {
  3802 													title: {
  3784 														type: 'inside'
  3803 														type: 'inside'
  3785 													}
  3804 													}
  3786 												}
  3805 												}
  3787 											};
  3806 											};
  3788 											var settings = $.extend({}, data_options, data.amsFancyboxOptions);
  3807 											var settings = $.extend({}, dataOptions, data.amsFancyboxOptions);
  3789 											settings = ams.executeFunctionByName(data.amsFancyboxInitCallback, fancybox, settings) || settings;
  3808 											settings = ams.executeFunctionByName(data.amsFancyboxInitCallback, fancybox, settings) || settings;
  3790 											var plugin = fancybox.fancybox(settings);
  3809 											var plugin = fancybox.fancybox(settings);
  3791 											ams.executeFunctionByName(data.amsFancyboxAfterInitCallback, fancybox, plugin, settings);
  3810 											ams.executeFunctionByName(data.amsFancyboxAfterInitCallback, fancybox, plugin, settings);
  3792 										});
  3811 										});
  3793 								   });
  3812 								   });
  3825 																		   'jquery-mCustomScrollbar');
  3844 																		   'jquery-mCustomScrollbar');
  3826 															}
  3845 															}
  3827 															scrollbars.each(function() {
  3846 															scrollbars.each(function() {
  3828 																var scrollbar = $(this);
  3847 																var scrollbar = $(this);
  3829 																var data = scrollbar.data();
  3848 																var data = scrollbar.data();
  3830 																var data_options = {
  3849 																var dataOptions = {
  3831 																	theme: data.amsScrollbarTheme || 'light'
  3850 																	theme: data.amsScrollbarTheme || 'light'
  3832 																};
  3851 																};
  3833 																var settings = $.extend({}, data_options, data.amsScrollbarOptions);
  3852 																var settings = $.extend({}, dataOptions, data.amsScrollbarOptions);
  3834 																settings = ams.executeFunctionByName(data.amsScrollbarInitCallback, scrollbar, settings) || settings;
  3853 																settings = ams.executeFunctionByName(data.amsScrollbarInitCallback, scrollbar, settings) || settings;
  3835 																var plugin = scrollbar.mCustomScrollbar(settings);
  3854 																var plugin = scrollbar.mCustomScrollbar(settings);
  3836 																ams.executeFunctionByName(data.amsScrollbarAfterInitCallback, scrollbar, plugin, settings);
  3855 																ams.executeFunctionByName(data.amsScrollbarAfterInitCallback, scrollbar, plugin, settings);
  3837 															});
  3856 															});
  3838 													   });
  3857 													   });
  3918 		 *   of milliseconds
  3937 		 *   of milliseconds
  3919 		 * - data-ams-messagebox-callback: a callback's name, which will be called when message box is closed
  3938 		 * - data-ams-messagebox-callback: a callback's name, which will be called when message box is closed
  3920 		 */
  3939 		 */
  3921 		messageBox: function(options) {
  3940 		messageBox: function(options) {
  3922 			var data = $(this).data();
  3941 			var data = $(this).data();
  3923 			var data_options = $.extend({}, options, data.amsMessageboxOptions);
  3942 			var dataOptions = $.extend({}, options, data.amsMessageboxOptions);
  3924 			var settings = $.extend({}, data_options, {
  3943 			var settings = $.extend({}, dataOptions, {
  3925 				title: data.amsMessageboxTitle || data_options.title || '',
  3944 				title: data.amsMessageboxTitle || dataOptions.title || '',
  3926 				content: data.amsMessageboxContent || data_options.content || '',
  3945 				content: data.amsMessageboxContent || dataOptions.content || '',
  3927 				icon: data.amsMessageboxIcon || data_options.icon,
  3946 				icon: data.amsMessageboxIcon || dataOptions.icon,
  3928 				number: data.amsMessageboxNumber || data_options.number,
  3947 				number: data.amsMessageboxNumber || dataOptions.number,
  3929 				timeout: data.amsMessageboxTimeout || data_options.timeout
  3948 				timeout: data.amsMessageboxTimeout || dataOptions.timeout
  3930 			});
  3949 			});
  3931 			var status = data.amsMessageboxStatus || data_options.status || 'info';
  3950 			var status = data.amsMessageboxStatus || dataOptions.status || 'info';
  3932 			var callback = ams.getFunctionByName(data.amsMessageboxCallback || data_options.callback);
  3951 			var callback = ams.getFunctionByName(data.amsMessageboxCallback || dataOptions.callback);
  3933 			ams.skin.messageBox(status, settings, callback);
  3952 			ams.skin.messageBox(status, settings, callback);
  3934 		},
  3953 		},
  3935 
  3954 
  3936 		/**
  3955 		/**
  3937 		 * Standard small box callback
  3956 		 * Standard small box callback
  3947 		 *   of milliseconds
  3966 		 *   of milliseconds
  3948 		 * - data-ams-smallbox-callback: a callback's name, which will be called when message box is closed
  3967 		 * - data-ams-smallbox-callback: a callback's name, which will be called when message box is closed
  3949 		 */
  3968 		 */
  3950 		smallBox: function(options) {
  3969 		smallBox: function(options) {
  3951 			var data = $(this).data();
  3970 			var data = $(this).data();
  3952 			var data_options = $.extend({}, options, data.amsSmallboxOptions);
  3971 			var dataOptions = $.extend({}, options, data.amsSmallboxOptions);
  3953 			var settings = $.extend({}, data_options, {
  3972 			var settings = $.extend({}, dataOptions, {
  3954 				title: data.amsSmallboxTitle || data_options.title || '',
  3973 				title: data.amsSmallboxTitle || dataOptions.title || '',
  3955 				content: data.amsSmallboxContent || data_options.content || '',
  3974 				content: data.amsSmallboxContent || dataOptions.content || '',
  3956 				icon: data.amsSmallboxIcon || data_options.icon,
  3975 				icon: data.amsSmallboxIcon || dataOptions.icon,
  3957 				iconSmall: data.amsSmallboxIconSmall || data_options.iconSmall,
  3976 				iconSmall: data.amsSmallboxIconSmall || dataOptions.iconSmall,
  3958 				timeout: data.amsSmallboxTimeout || data_options.timeout
  3977 				timeout: data.amsSmallboxTimeout || dataOptions.timeout
  3959 			});
  3978 			});
  3960 			var status = data.amsSmallboxStatus || data_options.status || 'info';
  3979 			var status = data.amsSmallboxStatus || dataOptions.status || 'info';
  3961 			var callback = ams.getFunctionByName(data.amsSmallboxCallback || data_options.callback);
  3980 			var callback = ams.getFunctionByName(data.amsSmallboxCallback || dataOptions.callback);
  3962 			ams.skin.smallBox(status, settings, callback);
  3981 			ams.skin.smallBox(status, settings, callback);
  3963 		}
  3982 		}
  3964 	};
  3983 	};
  3965 
  3984 
  3966 
  3985 
  4027 				}, function(button) {
  4046 				}, function(button) {
  4028 					if (button === ams.i18n.BTN_OK) {
  4047 					if (button === ams.i18n.BTN_OK) {
  4029 						var table = link.parents('table');
  4048 						var table = link.parents('table');
  4030 						var location = table.data('ams-location') || '';
  4049 						var location = table.data('ams-location') || '';
  4031 						var tr = link.parents('tr');
  4050 						var tr = link.parents('tr');
  4032 						var delete_target = tr.data('ams-delete-target') || table.data('ams-delete-target') || 'delete-element.json';
  4051 						var deleteTarget = tr.data('ams-delete-target') || table.data('ams-delete-target') || 'delete-element.json';
  4033 						var object_name = tr.data('ams-element-name');
  4052 						var objectName = tr.data('ams-element-name');
  4034 						MyAMS.ajax.post(location + '/' + delete_target, {'object_name': object_name}, function(result, status) {
  4053 						MyAMS.ajax.post(location + '/' + deleteTarget, {'object_name': objectName}, function(result, status) {
  4035 							if (result.status === 'success') {
  4054 							if (result.status === 'success') {
  4036 								if (table.hasClass('datatable')) {
  4055 								if (table.hasClass('datatable')) {
  4037 									table.dataTable().fnDeleteRow(tr[0]);
  4056 									table.dataTable().fnDeleteRow(tr[0]);
  4038 								} else {
  4057 								} else {
  4039 									tr.remove();
  4058 									tr.remove();
  4054 
  4073 
  4055 		/**
  4074 		/**
  4056 		 * Compute navigation page height
  4075 		 * Compute navigation page height
  4057 		 */
  4076 		 */
  4058 		_setPageHeight: function() {
  4077 		_setPageHeight: function() {
  4059 			var main_height = $('#main').height();
  4078 			var mainHeight = $('#main').height();
  4060 			var menu_height = ams.left_panel.height();
  4079 			var menuHeight = ams.leftPanel.height();
  4061 			var window_height = $(window).height() - ams.navbar_height;
  4080 			var windowHeight = $(window).height() - ams.navbarHeight;
  4062 			if (main_height > window_height) {
  4081 			if (mainHeight > windowHeight) {
  4063 				ams.left_panel.css('min-height', main_height);
  4082 				ams.leftPanel.css('min-height', mainHeight);
  4064 				ams.root.css('min-height', main_height + ams.navbar_height);
  4083 				ams.root.css('min-height', mainHeight + ams.navbarHeight);
  4065 			} else {
  4084 			} else {
  4066 				ams.left_panel.css('min-height', window_height);
  4085 				ams.leftPanel.css('min-height', windowHeight);
  4067 				ams.root.css('min-height', window_height);
  4086 				ams.root.css('min-height', windowHeight);
  4068 			}
  4087 			}
  4069 		},
  4088 		},
  4070 
  4089 
  4071 		/**
  4090 		/**
  4072 		 * Check width for mobile devices
  4091 		 * Check width for mobile devices
  4121 
  4140 
  4122 		/**
  4141 		/**
  4123 		 * Initialize desktop and mobile widgets
  4142 		 * Initialize desktop and mobile widgets
  4124 		 */
  4143 		 */
  4125 		_initDesktopWidgets: function(element) {
  4144 		_initDesktopWidgets: function(element) {
  4126 			if (ams.enable_widgets) {
  4145 			if (ams.enableWidgets) {
  4127 				var widgets = $('.ams-widget', element);
  4146 				var widgets = $('.ams-widget', element);
  4128 				if (widgets.length > 0) {
  4147 				if (widgets.length > 0) {
  4129 					ams.ajax.check($.fn.MyAMSWidget,
  4148 					ams.ajax.check($.fn.MyAMSWidget,
  4130 								   ams.baseURL + 'myams-widgets' + ams.devext + '.js',
  4149 								   ams.baseURL + 'myams-widgets' + ams.devext + '.js',
  4131 								   function () {
  4150 								   function () {
  4132 									   widgets.each(function () {
  4151 									   widgets.each(function () {
  4133 										   var widget = $(this);
  4152 										   var widget = $(this);
  4134 										   var data = widget.data();
  4153 										   var data = widget.data();
  4135 										   var data_options = {
  4154 										   var dataOptions = {
  4136 											   deleteSettingsKey: '#deletesettingskey-options',
  4155 											   deleteSettingsKey: '#deletesettingskey-options',
  4137 											   deletePositionKey: '#deletepositionkey-options'
  4156 											   deletePositionKey: '#deletepositionkey-options'
  4138 										   };
  4157 										   };
  4139 										   var settings = $.extend({}, data_options, data.amsWidgetOptions);
  4158 										   var settings = $.extend({}, dataOptions, data.amsWidgetOptions);
  4140 										   settings = ams.executeFunctionByName(data.amsWidgetInitcallback, widget, settings) || settings;
  4159 										   settings = ams.executeFunctionByName(data.amsWidgetInitcallback, widget, settings) || settings;
  4141 										   widget.MyAMSWidget(settings);
  4160 										   widget.MyAMSWidget(settings);
  4142 									   });
  4161 									   });
  4143 									   globals.MyAMSWidget.initWidgetsGrid($('.ams-widget-grid', element));
  4162 									   globals.MyAMSWidget.initWidgetsGrid($('.ams-widget-grid', element));
  4144 								   });
  4163 								   });
  4145 				}
  4164 				}
  4146 			}
  4165 			}
  4147 		},
  4166 		},
  4148 
  4167 
  4149 		_initMobileWidgets: function(element) {
  4168 		_initMobileWidgets: function(element) {
  4150 			if (ams.enable_mobile && ams.enable_widgets) {
  4169 			if (ams.enableMobile && ams.enableWidgets) {
  4151 				ams.skin._initDesktopWidgets(element);
  4170 				ams.skin._initDesktopWidgets(element);
  4152 			}
  4171 			}
  4153 		},
  4172 		},
  4154 
  4173 
  4155 		/**
  4174 		/**
  4329 				document.title = (prefix ? prefix + ' > ' : '') +
  4348 				document.title = (prefix ? prefix + ' > ' : '') +
  4330 								 ($('[data-ams-page-title]:first', container).data('ams-page-title') ||
  4349 								 ($('[data-ams-page-title]:first', container).data('ams-page-title') ||
  4331 								  menu.attr('title') ||
  4350 								  menu.attr('title') ||
  4332 								  document.title);
  4351 								  document.title);
  4333 			} else {
  4352 			} else {
  4334 				var active_url = $('[data-ams-active-menu]').data('ams-active-menu');
  4353 				var activeUrl = $('[data-ams-active-menu]').data('ams-active-menu');
  4335 				if (active_url) {
  4354 				if (activeUrl) {
  4336 					menu = $('A[href="' + active_url + '"]', nav);
  4355 					menu = $('A[href="' + activeUrl + '"]', nav);
  4337 				} else {
  4356 				} else {
  4338 					menu = $('>UL >LI >A[href!="#"]', nav).first();
  4357 					menu = $('>UL >LI >A[href!="#"]', nav).first();
  4339 				}
  4358 				}
  4340 				if (menu.exists()) {
  4359 				if (menu.exists()) {
  4341 					updateActiveMenus(menu);
  4360 					updateActiveMenus(menu);
  4342 					if (active_url) {
  4361 					if (activeUrl) {
  4343 						ams.skin._drawBreadCrumb();
  4362 						ams.skin._drawBreadCrumb();
  4344 					} else {
  4363 					} else {
  4345 						window.location.hash = menu.attr('href');
  4364 						window.location.hash = menu.attr('href');
  4346 					}
  4365 					}
  4347 				}
  4366 				}
  4417 				},
  4436 				},
  4418 				success: function(data, status, request) {
  4437 				success: function(data, status, request) {
  4419 					if (callback) {
  4438 					if (callback) {
  4420 						ams.executeFunctionByName(callback, this, data, status, request, options);
  4439 						ams.executeFunctionByName(callback, this, data, status, request, options);
  4421 					} else {
  4440 					} else {
  4422 						var request_data = ams.ajax.getResponse(request);
  4441 						var response = ams.ajax.getResponse(request);
  4423 						var data_type = request_data.content_type;
  4442 						var dataType = response.contentType;
  4424 						var result = request_data.data;
  4443 						var result = response.data;
  4425 						$('.loading', container).remove();
  4444 						$('.loading', container).remove();
  4426 						switch (data_type) {
  4445 						switch (dataType) {
  4427 							case 'json':
  4446 							case 'json':
  4428 								ams.ajax.handleJSON(result, container);
  4447 								ams.ajax.handleJSON(result, container);
  4429 								break;
  4448 								break;
  4430 							case 'script':
  4449 							case 'script':
  4431 								break;
  4450 								break;
  4467 		/**
  4486 		/**
  4468 		 * Change user language
  4487 		 * Change user language
  4469 		 */
  4488 		 */
  4470 		setLanguage: function(options) {
  4489 		setLanguage: function(options) {
  4471 			var lang = options.lang;
  4490 			var lang = options.lang;
  4472 			var handler_type = options.handler_type || 'json';
  4491 			var handlerType = options.handler_type || 'json';
  4473 			switch (handler_type) {
  4492 			switch (handlerType) {
  4474 				case 'json':
  4493 				case 'json':
  4475 					var method = options.method || 'setUserLanguage';
  4494 					var method = options.method || 'setUserLanguage';
  4476 					ams.jsonrpc.post(method, {lang: lang}, function() {
  4495 					ams.jsonrpc.post(method, {lang: lang}, function() {
  4477 						window.location.reload(true);
  4496 						window.location.reload(true);
  4478 					});
  4497 					});
  4540 
  4559 
  4541 		var body = $('body');
  4560 		var body = $('body');
  4542 
  4561 
  4543 		/* Init main components */
  4562 		/* Init main components */
  4544 		ams.root = body;
  4563 		ams.root = body;
  4545 		ams.left_panel = $('#left-panel');
  4564 		ams.leftPanel = $('#left-panel');
  4546 		ams.shortcuts = $('#shortcut');
  4565 		ams.shortcuts = $('#shortcut');
  4547 		ams.plugins.initData(body);
  4566 		ams.plugins.initData(body);
  4548 
  4567 
  4549 		// Init main AJAX events
  4568 		// Init main AJAX events
  4550 		var jquery_xhr = $.ajaxSettings.xhr;
  4569 		var xhr = $.ajaxSettings.xhr;
  4551 		$.ajaxSetup({
  4570 		$.ajaxSetup({
  4552 			progress: ams.ajax.progress,
  4571 			progress: ams.ajax.progress,
  4553 			progressUpload: ams.ajax.progress,
  4572 			progressUpload: ams.ajax.progress,
  4554 			xhr: function() {
  4573 			xhr: function() {
  4555 				var request = jquery_xhr();
  4574 				var request = xhr();
  4556 				if (request && (typeof(request.addEventListener) === "function")) {
  4575 				if (request && (typeof(request.addEventListener) === "function")) {
  4557 					var that = this;
  4576 					var that = this;
  4558 					request.addEventListener("progress", function(evt) {
  4577 					request.addEventListener("progress", function(evt) {
  4559 						that.progress(evt);
  4578 						that.progress(evt);
  4560 					}, false);
  4579 					}, false);
  4571 			ams.root.addClass('desktop-detected');
  4590 			ams.root.addClass('desktop-detected');
  4572 			ams.device = 'desktop';
  4591 			ams.device = 'desktop';
  4573 		} else {
  4592 		} else {
  4574 			ams.root.addClass('mobile-detected');
  4593 			ams.root.addClass('mobile-detected');
  4575 			ams.device = 'mobile';
  4594 			ams.device = 'mobile';
  4576 			if (ams.enable_fastclick) {
  4595 			if (ams.enableFastclick) {
  4577 				ams.ajax.check($.fn.noClickDelay,
  4596 				ams.ajax.check($.fn.noClickDelay,
  4578 							   ams.baseURL + '/ext/jquery-smartclick' + ams.devext + '.js',
  4597 							   ams.baseURL + '/ext/jquery-smartclick' + ams.devext + '.js',
  4579 							   function() {
  4598 							   function() {
  4580 								   $('NAV UL A').noClickDelay();
  4599 								   $('NAV UL A').noClickDelay();
  4581 								   $('A', '#hide-menu').noClickDelay();
  4600 								   $('A', '#hide-menu').noClickDelay();
  4646 		$('input[name="activity"]').change(function(e) {
  4665 		$('input[name="activity"]').change(function(e) {
  4647 			var href = $(this).data('ams-url');
  4666 			var href = $(this).data('ams-url');
  4648 			if (href) {
  4667 			if (href) {
  4649 				e.preventDefault();
  4668 				e.preventDefault();
  4650 				e.stopPropagation();
  4669 				e.stopPropagation();
  4651 				var href_getter = ams.getFunctionByName(href);
  4670 				var hrefGetter = ams.getFunctionByName(href);
  4652 				if (typeof(href_getter) === 'function') {
  4671 				if (typeof(hrefGetter) === 'function') {
  4653 					href = href_getter.call(this);
  4672 					href = hrefGetter.call(this);
  4654 				}
  4673 				}
  4655 				if (typeof(href) === 'function') {
  4674 				if (typeof(href) === 'function') {
  4656 					// Javascript function call
  4675 					// Javascript function call
  4657 					href.call(this);
  4676 					href.call(this);
  4658 				} else {
  4677 				} else {
  4684 
  4703 
  4685 		// Initialize left nav
  4704 		// Initialize left nav
  4686 		var nav = $('nav');
  4705 		var nav = $('nav');
  4687 		$('UL', nav).myams_menu({
  4706 		$('UL', nav).myams_menu({
  4688 			accordion : nav.data('ams-menu-accordion') !== false,
  4707 			accordion : nav.data('ams-menu-accordion') !== false,
  4689 			speed : ams.menu_speed
  4708 			speed : ams.menuSpeed
  4690 		});
  4709 		});
  4691 
  4710 
  4692 		// Left navigation collapser
  4711 		// Left navigation collapser
  4693 		$('.minifyme').click(function(e) {
  4712 		$('.minifyme').click(function(e) {
  4694 			$('BODY').toggleClass("minified");
  4713 			$('BODY').toggleClass("minified");
  4733 							   ams.skin._setPageHeight();
  4752 							   ams.skin._setPageHeight();
  4734 						   });
  4753 						   });
  4735 					   });
  4754 					   });
  4736 
  4755 
  4737 		// Init AJAX navigation
  4756 		// Init AJAX navigation
  4738 		if (ams.ajax_nav) {
  4757 		if (ams.ajaxNav) {
  4739 			$(document).on('click', 'a[href="#"]', function(e) {
  4758 			$(document).on('click', 'a[href="#"]', function(e) {
  4740 				e.preventDefault();
  4759 				e.preventDefault();
  4741 			});
  4760 			});
  4742 			$(document).on('click', 'a[href!="#"]:not([data-toggle]), [data-ams-url]:not([data-toggle])', function(e) {
  4761 			$(document).on('click', 'a[href!="#"]:not([data-toggle]), [data-ams-url]:not([data-toggle])', function(e) {
  4743 				var link = $(e.currentTarget);
  4762 				var link = $(e.currentTarget);
  4749 				if (!href || href.startsWith('javascript') || link.attr('target') || (link.data('ams-context-menu') === true)) {
  4768 				if (!href || href.startsWith('javascript') || link.attr('target') || (link.data('ams-context-menu') === true)) {
  4750 					return;
  4769 					return;
  4751 				}
  4770 				}
  4752 				e.preventDefault();
  4771 				e.preventDefault();
  4753 				e.stopPropagation();
  4772 				e.stopPropagation();
  4754 				var href_getter = ams.getFunctionByName(href);
  4773 				var hrefGetter = ams.getFunctionByName(href);
  4755 				if (typeof(href_getter) === 'function') {
  4774 				if (typeof(hrefGetter) === 'function') {
  4756 					href = href_getter.call(link);
  4775 					href = hrefGetter.call(link);
  4757 				}
  4776 				}
  4758 				if (typeof(href) === 'function') {
  4777 				if (typeof(href) === 'function') {
  4759 					// Javascript function call
  4778 					// Javascript function call
  4760 					href.call(link);
  4779 					href.call(link);
  4761 				} else {
  4780 				} else {
  4963 			});
  4982 			});
  4964 		});
  4983 		});
  4965 
  4984 
  4966 		// Init page content
  4985 		// Init page content
  4967 		ams.initContent(document);
  4986 		ams.initContent(document);
  4968 		if (ams.ajax_nav && nav.exists()) {
  4987 		if (ams.ajaxNav && nav.exists()) {
  4969 			ams.skin.checkURL();
  4988 			ams.skin.checkURL();
  4970 		}
  4989 		}
  4971 		ams.form.setFocus(document);
  4990 		ams.form.setFocus(document);
  4972 
  4991 
  4973 		// Add unload event listener to check for modified forms
  4992 		// Add unload event listener to check for modified forms