src/ztfy/myams/resources/js/myams.js
changeset 171 d1a43750fea2
parent 167 bf78f1c35edd
child 174 8d81f90f1d08
equal deleted inserted replaced
170:448072405613 171:d1a43750fea2
   461 	};
   461 	};
   462 
   462 
   463 
   463 
   464 	/**
   464 	/**
   465 	 * Generate a random ID
   465 	 * Generate a random ID
   466 	 *
       
   467 	 * @param length
       
   468 	 */
   466 	 */
   469 	MyAMS.generateId = function() {
   467 	MyAMS.generateId = function() {
   470 		function s4() {
   468 		function s4() {
   471 			return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
   469 			return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
   472 		}
   470 		}
   473 		return s4() + s4() + s4() + s4();
   471 		return s4() + s4() + s4() + s4();
       
   472 	};
       
   473 
       
   474 
       
   475 	/**
       
   476 	 * Generate a random UUID
       
   477 	 */
       
   478 	MyAMS.generateUUID = function () {
       
   479 		var d = new Date().getTime();
       
   480 		var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
       
   481 			var r = (d + Math.random() * 16) % 16 | 0;
       
   482 			d = Math.floor(d / 16);
       
   483 			return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
       
   484 		});
       
   485 		return uuid;
   474 	};
   486 	};
   475 
   487 
   476 
   488 
   477 	/**
   489 	/**
   478 	 * Get and execute a function given by name
   490 	 * Get and execute a function given by name
   520 			return ams.getFunctionByName(match.substr(1, match.length-2));
   532 			return ams.getFunctionByName(match.substr(1, match.length-2));
   521 		});
   533 		});
   522 	};
   534 	};
   523 
   535 
   524 	MyAMS.getScript = function(url, callback, options) {
   536 	MyAMS.getScript = function(url, callback, options) {
       
   537 		if (typeof(callback) === 'object') {
       
   538 			options = callback;
       
   539 			callback = null;
       
   540 		}
       
   541 		if (options === undefined) {
       
   542 			options = {};
       
   543 		}
   525 		var defaults = {
   544 		var defaults = {
   526 			dataType: 'script',
   545 			dataType: 'script',
   527 			url: ams.getSource(url),
   546 			url: ams.getSource(url),
   528 			success: callback,
   547 			success: callback,
   529 			error: ams.error.show,
   548 			error: ams.error.show,
   530 			cache: !ams.devmode,
   549 			cache: !ams.devmode,
   531 			async: typeof(callback) === 'function'
   550 			async: options.async === undefined ? typeof(callback) === 'function' : options.async
   532 		};
   551 		};
   533 		var settings = $.extend({}, defaults, options);
   552 		var settings = $.extend({}, defaults, options);
   534 		return $.ajax(settings);
   553 		return $.ajax(settings);
   535 	};
   554 	};
   536 
   555 
   885 				case 'error':
   904 				case 'error':
   886 					ams.form.showErrors(form, result);
   905 					ams.form.showErrors(form, result);
   887 					break;
   906 					break;
   888 				case 'info':
   907 				case 'info':
   889 				case 'success':
   908 				case 'success':
       
   909 					ams.form.resetChanged(form);
   890 					if (result.close_form !== false) {
   910 					if (result.close_form !== false) {
   891 						ams.dialog.close(form);
   911 						ams.dialog.close(form);
   892 					}
   912 					}
   893 					break;
   913 					break;
   894 				case 'message':
   914 				case 'message':
   895 				case 'messagebox':
   915 				case 'messagebox':
   896 					break;
   916 					break;
   897 				case 'notify':
   917 				case 'notify':
   898 				case 'callback':
   918 				case 'callback':
   899 				case 'callbacks':
   919 				case 'callbacks':
       
   920 					ams.form.resetChanged(form);
   900 					if (result.close_form !== false) {
   921 					if (result.close_form !== false) {
   901 						ams.dialog.close(form);
   922 						ams.dialog.close(form);
   902 					}
   923 					}
   903 					break;
   924 					break;
   904 				case 'modal':
   925 				case 'modal':
   905 					ams.dialog.open(result.location);
   926 					ams.dialog.open(result.location);
   906 					break;
   927 					break;
   907 				case 'reload':
   928 				case 'reload':
       
   929 					ams.form.resetChanged(form);
   908 					if (result.close_form !== false) {
   930 					if (result.close_form !== false) {
   909 						ams.dialog.close(form);
   931 						ams.dialog.close(form);
   910 					}
   932 					}
   911 					url = result.location || window.location.hash;
   933 					url = result.location || window.location.hash;
   912 					if (url.startsWith('#')) {
   934 					if (url.startsWith('#')) {
   913 						url = url.substr(1);
   935 						url = url.substr(1);
   914 					}
   936 					}
   915 					ams.skin.loadURL(url, result.target || target || '#content');
   937 					ams.skin.loadURL(url, result.target || target || '#content');
   916 					break;
   938 					break;
   917 				case 'redirect':
   939 				case 'redirect':
       
   940 					ams.form.resetChanged(form);
   918 					if (result.close_form === true) {
   941 					if (result.close_form === true) {
   919 						ams.dialog.close(form);
   942 						ams.dialog.close(form);
   920 					}
   943 					}
   921 					url = result.location || window.location.href;
   944 					url = result.location || window.location.href;
   922 					if (result.window) {
   945 					if (result.window) {
  1240 				  '[data-ams-changed-event]', form).each(function() {
  1263 				  '[data-ams-changed-event]', form).each(function() {
  1241 						var source = $(this);
  1264 						var source = $(this);
  1242 						if (source.data('ams-ignore-change') !== true) {
  1265 						if (source.data('ams-ignore-change') !== true) {
  1243 							var event = source.data('ams-changed-event') || 'change';
  1266 							var event = source.data('ams-changed-event') || 'change';
  1244 							source.on(event, function () {
  1267 							source.on(event, function () {
  1245 								$(this).parents('FORM').attr('data-ams-form-changed', true);
  1268 								ams.form.setChanged($(this).parents('FORM'));
  1246 							});
  1269 							});
  1247 						}
  1270 						}
  1248 				});
  1271 				});
  1249 				form.on('reset', function() {
  1272 				form.on('reset', function() {
  1250 					$(this).removeAttr('data-ams-form-changed');
  1273 					ams.form.resetChanged($(this));
  1251 				});
  1274 				});
  1252 			});
  1275 			});
  1253 		},
  1276 		},
  1254 
  1277 
  1255 		/**
  1278 		/**
  1288 		},
  1311 		},
  1289 
  1312 
  1290 		/**
  1313 		/**
  1291 		 * Check for modified forms before loading new inner content
  1314 		 * Check for modified forms before loading new inner content
  1292 		 */
  1315 		 */
  1293 		confirmChangedForm: function(element, callback) {
  1316 		confirmChangedForm: function(element, callback, cancelCallback) {
  1294 			if (typeof(element) === 'function') {
  1317 			if (typeof(element) === 'function') {
  1295 				callback = element;
  1318 				callback = element;
  1296 				element = undefined;
  1319 				element = undefined;
  1297 			}
  1320 			}
  1298 			var forms = $('FORM[data-ams-form-changed="true"]', element);
  1321 			var forms = $('FORM[data-ams-form-changed="true"]', element);
  1299 			if (forms.exists()) {
  1322 			if (forms.exists()) {
  1300 				ams.skin.bigBox({
  1323 				if (cancelCallback) {
  1301 					title: ams.i18n.WARNING,
  1324 					if (globals.confirm(ams.i18n.FORM_CHANGED_WARNING, ams.i18n.WARNING)) {
  1302 					content: '<i class="text-danger fa fa-2x fa-bell shake animated"></i>&nbsp; ' + ams.i18n.FORM_CHANGED_WARNING,
       
  1303 					buttons: ams.i18n.BTN_OK_CANCEL
       
  1304 				}, function(button) {
       
  1305 					if (button === ams.i18n.BTN_OK) {
       
  1306 						callback.call(element);
  1325 						callback.call(element);
       
  1326 					} else {
       
  1327 						cancelCallback.call(element);
  1307 					}
  1328 					}
  1308 				});
  1329 				} else {
       
  1330 					ams.skin.bigBox({
       
  1331 						title: ams.i18n.WARNING,
       
  1332 						content: '<i class="text-danger fa fa-2x fa-bell shake animated"></i>&nbsp; ' + ams.i18n.FORM_CHANGED_WARNING,
       
  1333 						buttons: ams.i18n.BTN_OK_CANCEL
       
  1334 					}, function(button) {
       
  1335 						if (button === ams.i18n.BTN_OK) {
       
  1336 							callback.call(element);
       
  1337 						}
       
  1338 					});
       
  1339 				}
  1309 			} else {
  1340 			} else {
  1310 				callback.call(element);
  1341 				callback.call(element);
  1311 			}
  1342 			}
       
  1343 		},
       
  1344 
       
  1345 		/**
       
  1346 		 * Update form "chenged" status flag
       
  1347 		 */
       
  1348 		setChanged: function(form) {
       
  1349 			form.attr('data-ams-form-changed', true);
       
  1350 		},
       
  1351 
       
  1352 		/**
       
  1353 		 * Reset form changed flag
       
  1354 		 */
       
  1355 		resetChanged: function(form) {
       
  1356 			form.removeAttr('data-ams-form-changed');
  1312 		},
  1357 		},
  1313 
  1358 
  1314 		/**
  1359 		/**
  1315 		 * Submit given form
  1360 		 * Submit given form
  1316 		 */
  1361 		 */
  1352 						   ams.baseURL + 'ext/jquery-form-3.49' + ams.devext + '.js',
  1397 						   ams.baseURL + 'ext/jquery-form-3.49' + ams.devext + '.js',
  1353 						   function() {
  1398 						   function() {
  1354 
  1399 
  1355 								function _submitAjaxForm(form, options) {
  1400 								function _submitAjaxForm(form, options) {
  1356 
  1401 
  1357 									var button;
  1402 									var button,
       
  1403 										button_data;
  1358 									var data = form.data();
  1404 									var data = form.data();
  1359 									var form_options = data.amsFormOptions;
  1405 									var form_options = data.amsFormOptions;
  1360 									var form_data;
  1406 									var form_data;
  1361 									var form_data_callback;
  1407 									var form_data_callback;
  1362 
  1408 
       
  1409 									var progress_handler;
       
  1410 									var progress_interval;
       
  1411 									var progress_callback;
       
  1412 									var progress_end_callback;
       
  1413 
       
  1414 									// Inner progress status handler
       
  1415 									function _getProgress(handler, progress_id) {
       
  1416 
       
  1417 										var interval;
       
  1418 
       
  1419 										function _clearProgressStatus() {
       
  1420 											button.button('reset');
       
  1421 											clearInterval(interval);
       
  1422 											ams.executeFunctionByName(progress_end_callback, form, button);
       
  1423 										}
       
  1424 
       
  1425 										function _getProgressStatus() {
       
  1426 											ams.ajax.post(handler,
       
  1427 														  {progress_id: progress_id},
       
  1428 														  {error: _clearProgressStatus},
       
  1429 														  ams.getFunctionByName(progress_callback) || function(result, status) {
       
  1430 															if (status == 'success') {
       
  1431 																if (result.status === 'running') {
       
  1432 																	if (result.message) {
       
  1433 																		button.text(result.message);
       
  1434 																	} else {
       
  1435 																		button.text(button.data('ams-progress-text') +
       
  1436 																					' ' + result.current + ' / ' + result.length);
       
  1437 																	}
       
  1438 																} else if (result.status === 'finished') {
       
  1439 																	_clearProgressStatus();
       
  1440 																}
       
  1441 															} else {
       
  1442 																_clearProgressStatus();
       
  1443 															}
       
  1444 														  });
       
  1445 										}
       
  1446 
       
  1447 										button.button('loading');
       
  1448 										interval = setInterval(_getProgressStatus, progress_interval);
       
  1449 									}
       
  1450 
       
  1451 									// Initialize form data
  1363 									if (submit_options) {
  1452 									if (submit_options) {
  1364 										form_data_callback = submit_options.formDataInitCallback;
  1453 										form_data_callback = submit_options.formDataInitCallback;
  1365 									}
  1454 									}
  1366 									if (form_data_callback) {
  1455 									if (form_data_callback) {
  1367 										delete submit_options.formDataInitCallback;
  1456 										delete submit_options.formDataInitCallback;
  1385 										}
  1474 										}
  1386 									} else {
  1475 									} else {
  1387 										form_data = data.amsFormData || {};
  1476 										form_data = data.amsFormData || {};
  1388 									}
  1477 									}
  1389 
  1478 
       
  1479 									// Check submit button for custom action handler and target
  1390 									button = $(form.data('ams-submit-button'));
  1480 									button = $(form.data('ams-submit-button'));
  1391 									var buttonHandler,
  1481 									if (button && button.exists()) {
  1392 										buttonTarget;
  1482 										button_data = button.data();
  1393 									if (button) {
  1483 									} else {
  1394 										buttonHandler = button.data('ams-form-handler');
  1484 										button_data = {};
  1395 										buttonTarget = button.data('ams-form-submit-target');
       
  1396 									}
  1485 									}
  1397 
  1486 
       
  1487 									// Check action URL
  1398 									var url;
  1488 									var url;
  1399 									var form_handler = handler || buttonHandler || data.amsFormHandler || '';
  1489 									var form_handler = handler || button_data.amsFormHandler || data.amsFormHandler || '';
  1400 									if (form_handler.startsWith(window.location.protocol)) {
  1490 									if (form_handler.startsWith(window.location.protocol)) {
  1401 										url = form_handler;
  1491 										url = form_handler;
  1402 									} else {
  1492 									} else {
  1403 										var action = form.attr('action').replace(/#/, '');
  1493 										var action = button_data.amsFormAction || form.attr('action').replace(/#/, '');
  1404 										if (action.startsWith(window.location.protocol)) {
  1494 										if (action.startsWith(window.location.protocol)) {
  1405 											url = action;
  1495 											url = action;
  1406 										} else {
  1496 										} else {
  1407 											url = ams.ajax.getAddr() + action;
  1497 											url = ams.ajax.getAddr() + action;
  1408 										}
  1498 										}
  1409 										url += form_handler;
  1499 										url += form_handler;
  1410 									}
  1500 									}
  1411 
  1501 									progress_handler = button_data.amsProgressHandler || data.amsProgressHandler || '';
       
  1502 									progress_interval = button_data.amsProgressInterval || data.amsProgressInterval || 1000;
       
  1503 									progress_callback = button_data.amsProgressCallback || data.amsProgressCallback;
       
  1504 									progress_end_callback = button_data.amsProgressEndCallback || data.amsProgressEndCallback;
       
  1505 
       
  1506 									// Initialize submit target with AJAX indicator
  1412 									var target = null;
  1507 									var target = null;
  1413 									if (submit_options && submit_options.initSubmitTarget) {
  1508 									if (submit_options && submit_options.initSubmitTarget) {
  1414 										ams.executeFunctionByName(submit_options.initSubmitTarget);
  1509 										ams.executeFunctionByName(submit_options.initSubmitTarget, form);
  1415 									} else {
  1510 									} else {
  1416 										if (data.amsFormInitSubmitTarget) {
  1511 										if (data.amsFormInitSubmitTarget) {
  1417 											target = $(buttonTarget || data.amsFormSubmitTarget || '#content');
  1512 											target = $(buttonTarget || data.amsFormSubmitTarget || '#content');
  1418 											ams.executeFunctionByName(data.amsFormInitSubmit || 'MyAMS.form.initSubmit', form, target);
  1513 											ams.executeFunctionByName(data.amsFormInitSubmit || 'MyAMS.form.initSubmit', form, target);
  1419 										} else if (!data.amsFormHideSubmitFooter) {
  1514 										} else if (!data.amsFormHideSubmitFooter) {
  1420 											ams.executeFunctionByName(data.amsFormInitSubmit || 'MyAMS.form.initSubmitFooter', form);
  1515 											ams.executeFunctionByName(data.amsFormInitSubmit || 'MyAMS.form.initSubmitFooter', form);
  1421 										}
  1516 										}
  1422 									}
  1517 									}
  1423 
  1518 
  1424 									var hasUpload = typeof(options.uuid) !== 'undefined';
  1519 									// Complete form data
  1425 									if (hasUpload) {
       
  1426 										if (url.indexOf('X-Progress-ID') < 0) {
       
  1427 											url += "?X-Progress-ID=" + options.uuid;
       
  1428 										}
       
  1429 										delete options.uuid;
       
  1430 									}
       
  1431 
       
  1432 									if (submit_options) {
  1520 									if (submit_options) {
  1433 										form_data = $.extend({}, form_data, submit_options.form_data);
  1521 										form_data = $.extend({}, form_data, submit_options.form_data);
  1434 									}
  1522 									}
       
  1523 
       
  1524 									// Check progress handler
       
  1525 									if (progress_handler) {
       
  1526 										form_data.progress_id = ams.generateUUID();
       
  1527 									} else {
       
  1528 										// Check progress meter via Apache progress module
       
  1529 										var hasUpload = typeof(options.uuid) !== 'undefined';
       
  1530 										if (hasUpload) {
       
  1531 											if (url.indexOf('X-Progress-ID') < 0) {
       
  1532 												url += "?X-Progress-ID=" + options.uuid;
       
  1533 											}
       
  1534 											delete options.uuid;
       
  1535 										}
       
  1536 									}
       
  1537 
       
  1538 									// Initialize default AJAX settings
  1435 									var defaults = {
  1539 									var defaults = {
  1436 										url: url,
  1540 										url: url,
  1437 										type: 'post',
  1541 										type: 'post',
  1438 										cache: false,
  1542 										cache: false,
  1439 										data: form_data,
  1543 										data: form_data,
  1460 											form.data('submitted', false);
  1564 											form.data('submitted', false);
  1461 											form.removeData('ams-submit-button');
  1565 											form.removeData('ams-submit-button');
  1462 										},
  1566 										},
  1463 										iframe: hasUpload
  1567 										iframe: hasUpload
  1464 									};
  1568 									};
       
  1569 
       
  1570 									// Initialize IFrame for custom download target
  1465 									var download_target = (submit_options && submit_options.downloadTarget) || data.amsFormDownloadTarget;
  1571 									var download_target = (submit_options && submit_options.downloadTarget) || data.amsFormDownloadTarget;
  1466 									if (download_target) {
  1572 									if (download_target) {
  1467 										var iframe = $('iframe[name="' + download_target + '"]');
  1573 										var iframe = $('iframe[name="' + download_target + '"]');
  1468 										if (!iframe.exists()) {
  1574 										if (!iframe.exists()) {
  1469 											iframe = $('<iframe></iframe>').hide()
  1575 											iframe = $('<iframe></iframe>').hide()
  1470 																		   .attr('name', download_target)
  1576 																		   .attr('name', download_target)
  1471 																		   .appendTo(form);
  1577 																		   .appendTo($('body'));
  1472 										}
  1578 										}
  1473 										defaults = $.extend({}, defaults, {
  1579 										defaults = $.extend({}, defaults, {
  1474 											iframe: true,
  1580 											iframe: true,
  1475 											iframeTarget: iframe,
  1581 											iframeTarget: iframe,
  1476 											success: function(result, status, request, form) {
  1582 											success: function(result, status, request, form) {
  1484 														callback = button.data('ams-form-submit-callback');
  1590 														callback = button.data('ams-form-submit-callback');
  1485 													}
  1591 													}
  1486 													if (!callback) {
  1592 													if (!callback) {
  1487 														callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback;
  1593 														callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback;
  1488 													}
  1594 													}
  1489 													callback.call(form, result, status, request, form);
  1595 													try {
  1490 													if (form.is(':visible') && button) {
  1596 														callback.call(form, result, status, request, form);
  1491 														button.button('reset');
  1597 													} finally {
       
  1598 														if (form.is(':visible') && button) {
       
  1599 															button.button('reset');
       
  1600 														}
       
  1601 														form.data('submitted', false);
       
  1602 														form.removeData('ams-submit-button');
       
  1603 														ams.form.resetChanged(form);
  1492 													}
  1604 													}
  1493 													form.data('submitted', false);
       
  1494 													form.removeData('ams-submit-button');
       
  1495 													form.removeAttr('data-ams-form-changed');
       
  1496 												}
  1605 												}
  1497 											}
  1606 											}
  1498 										});
  1607 										});
  1499 									} else {
  1608 									} else {
  1500 										defaults = $.extend({}, defaults, {
  1609 										defaults = $.extend({}, defaults, {
  1519 													callback = button.data('ams-form-submit-callback');
  1628 													callback = button.data('ams-form-submit-callback');
  1520 												}
  1629 												}
  1521 												if (!callback) {
  1630 												if (!callback) {
  1522 													callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback;
  1631 													callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback;
  1523 												}
  1632 												}
  1524 												callback.call(form, result, status, request, form);
  1633 												try {
  1525 												if (form.is(':visible') && button) {
  1634 													callback.call(form, result, status, request, form);
  1526 													button.button('reset');
  1635 												} finally {
       
  1636 													if (form.is(':visible') && button) {
       
  1637 														button.button('reset');
       
  1638 													}
       
  1639 													form.data('submitted', false);
       
  1640 													form.removeData('ams-submit-button');
       
  1641 													ams.form.resetChanged(form);
  1527 												}
  1642 												}
  1528 												form.data('submitted', false);
       
  1529 												form.removeData('ams-submit-button');
       
  1530 												form.removeAttr('data-ams-form-changed');
       
  1531 											},
  1643 											},
  1532 											iframe: hasUpload
  1644 											iframe: hasUpload
  1533 										});
  1645 										});
  1534 									}
  1646 									}
  1535 									var settings = $.extend({}, defaults, options, form_options, submit_options);
  1647 									var settings = $.extend({}, defaults, options, form_options, submit_options);
       
  1648 
       
  1649 									// Initialize progress handler
       
  1650 									if (progress_handler) {
       
  1651 										_getProgress(progress_handler, form_data.progress_id);
       
  1652 									}
       
  1653 
       
  1654 									// Submit form
  1536 									$(form).ajaxSubmit(settings);
  1655 									$(form).ajaxSubmit(settings);
  1537 
  1656 
       
  1657 									// If external download target is specified, reset form submit button and footer
  1538 									if (download_target) {
  1658 									if (download_target) {
  1539 										var modal = $(form).parents('.modal-dialog');
  1659 										var modal = $(form).parents('.modal-dialog');
  1540 										if (modal.exists()) {
  1660 										var keep_modal = modal.exists() && button && button.data('ams-keep-modal');
       
  1661 										if (keep_modal !== true) {
  1541 											ams.dialog.close(form);
  1662 											ams.dialog.close(form);
  1542 										} else {
  1663 										} else {
  1543 											ams.form.finalizeSubmitFooter.call(form);
  1664 											setTimeout(function() {
  1544 											if (button) {
  1665 												ams.form.finalizeSubmitFooter.call(form);
  1545 												button.button('reset');
  1666 												if (button) {
  1546 											}
  1667 													button.button('reset');
  1547 											form.data('submitted', false);
  1668 												}
  1548 											form.removeData('ams-submit-button');
  1669 												form.data('submitted', false);
  1549 											form.removeAttr('data-ams-form-changed');
  1670 												form.removeData('ams-submit-button');
       
  1671 												ams.form.resetChanged(form);
       
  1672 											}, button.data('ams-form-reset-timeout') || 2000);
  1550 										}
  1673 										}
  1551 									}
  1674 									}
  1552 								}
  1675 								}
  1553 
  1676 
  1554 								var hasUpload = $('INPUT[type="file"]', form).length > 0;
  1677 								var hasUpload = (form.data('ams-form-ignore-uploads') !== true) &&
       
  1678 												($('INPUT[type="file"]', form).length > 0);
  1555 								if (hasUpload) {
  1679 								if (hasUpload) {
  1556 									// JQuery-progressbar plug-in must be loaded synchronously!!
  1680 									// JQuery-progressbar plug-in must be loaded synchronously!!
  1557 									// Otherwise, hidden input fields created by jquery-validate plug-in
  1681 									// Otherwise, hidden input fields created by jquery-validate plug-in
  1558 									// and matching named buttons will be deleted (on first form submit)
  1682 									// and matching named buttons will be deleted (on first form submit)
  1559 									// before JQuery-form plug-in can get them when submitting the form...
  1683 									// before JQuery-form plug-in can get them when submitting the form...
  2283 			// Scan new element for plug-ins
  2407 			// Scan new element for plug-ins
  2284 			var plugins = {};
  2408 			var plugins = {};
  2285 			var plugin;
  2409 			var plugin;
  2286 			var name;
  2410 			var name;
  2287 
  2411 
       
  2412 			// Inner plug-in register function
       
  2413 			function _registerPlugin(name, new_plugin) {
       
  2414 				if (plugins.hasOwnProperty(name)) {
       
  2415 					var plugin = plugins[name];
       
  2416 					plugin.css = plugin.css || new_plugin.css;
       
  2417 					if (new_plugin.callback) {
       
  2418 						plugin.callbacks.push(new_plugin.callback);
       
  2419 					}
       
  2420 					if (new_plugin.register) {
       
  2421 						plugin.register = true;
       
  2422 					}
       
  2423 					if (new_plugin.async === false) {
       
  2424 						plugin.async = false;
       
  2425 					}
       
  2426 				} else {
       
  2427 					plugins[name] = {
       
  2428 						src: new_plugin.src,
       
  2429 						css: new_plugin.css,
       
  2430 						callbacks: new_plugin.callback ? [new_plugin.callback] : [],
       
  2431 						register: new_plugin.register,
       
  2432 						async: new_plugin.async
       
  2433 					};
       
  2434 				}
       
  2435 				if (new_plugin.css) {
       
  2436 					ams.getCSS(new_plugin.css, name + '_css');
       
  2437 				}
       
  2438 			}
       
  2439 
  2288 			$('[data-ams-plugins]', element).each(function() {
  2440 			$('[data-ams-plugins]', element).each(function() {
  2289 
       
  2290 				function registerPlugin(name, new_plugin) {
       
  2291 					if (plugins.hasOwnProperty(name)) {
       
  2292 						var plugin = plugins[name];
       
  2293 						plugin.css = plugin.css || new_plugin.css;
       
  2294 						if (new_plugin.callback) {
       
  2295 							plugin.callbacks.push(new_plugin.callback);
       
  2296 						}
       
  2297 						if (new_plugin.register) {
       
  2298 							plugin.register = true;
       
  2299 						}
       
  2300 						if (new_plugin.async === false) {
       
  2301 							plugin.async = false;
       
  2302 						}
       
  2303 					} else {
       
  2304 						plugins[name] = {
       
  2305 							src: new_plugin.src,
       
  2306 							css: new_plugin.css,
       
  2307 							callbacks: new_plugin.callback ? [new_plugin.callback] : [],
       
  2308 							register: new_plugin.register,
       
  2309 							async: new_plugin.async
       
  2310 						};
       
  2311 					}
       
  2312 				}
       
  2313 
  2441 
  2314 				var source = $(this);
  2442 				var source = $(this);
  2315 				var ams_plugins = source.data('ams-plugins');
  2443 				var ams_plugins = source.data('ams-plugins');
  2316 				if (typeof(ams_plugins) === 'string') {
  2444 				if (typeof(ams_plugins) === 'string') {
  2317 					var names = source.data('ams-plugins').split(/\s+/);
  2445 					var names = source.data('ams-plugins').split(/\s+/);
  2322 							css: source.data('ams-plugin-' + name + '-css'),
  2450 							css: source.data('ams-plugin-' + name + '-css'),
  2323 							callback: source.data('ams-plugin-' + name + '-callback'),
  2451 							callback: source.data('ams-plugin-' + name + '-callback'),
  2324 							register: source.data('ams-plugin-' + name + '-register'),
  2452 							register: source.data('ams-plugin-' + name + '-register'),
  2325 							async: source.data('ams-plugin-' + name + '-async')
  2453 							async: source.data('ams-plugin-' + name + '-async')
  2326 						};
  2454 						};
  2327 						registerPlugin(name, new_plugin);
  2455 						_registerPlugin(name, new_plugin);
  2328 					}
  2456 					}
  2329 				} else {
  2457 				} else {
  2330 					for (name in ams_plugins) {
  2458 					for (name in ams_plugins) {
  2331 						if (!ams_plugins.hasOwnProperty(name)) {
  2459 						if (!ams_plugins.hasOwnProperty(name)) {
  2332 							continue;
  2460 							continue;
  2333 						}
  2461 						}
  2334 						registerPlugin(name, ams_plugins[name]);
  2462 						_registerPlugin(name, ams_plugins[name]);
  2335 					}
  2463 					}
  2336 				}
  2464 				}
  2337 			});
  2465 			});
  2338 
  2466 
  2339 			// Load new plug-ins and execute async ones
       
  2340 			for (name in plugins) {
  2467 			for (name in plugins) {
  2341 				if (ams.plugins.enabled[name] === undefined) {
  2468 				if (ams.plugins.enabled[name] === undefined) {
  2342 					plugin = plugins[name];
  2469 					plugin = plugins[name];
  2343 					ams.getScript(plugin.src, function() {
  2470 					ams.getScript(plugin.src, function() {
  2344 						var index;
  2471 						var index;
  2345 						var callbacks = plugin.callbacks;
  2472 						var callbacks = plugin.callbacks;
  2346 						if (callbacks) {
  2473 						if (callbacks && callbacks.length) {
  2347 							for (index=0; index < callbacks.length; index++) {
  2474 							for (index=0; index < callbacks.length; index++) {
  2348 								var called = ams.getFunctionByName(callbacks[index]);
  2475 								var called = ams.getFunctionByName(callbacks[index]);
  2349 								if (plugin.register !== false) {
  2476 								if (plugin.register !== false) {
  2350 									var enabled = ams.plugins.enabled;
  2477 									var enabled = ams.plugins.enabled;
  2351 									if (enabled.hasOwnProperty(name)) {
  2478 									if (enabled.hasOwnProperty(name)) {
  2358 						} else {
  2485 						} else {
  2359 							if (plugin.register !== false) {
  2486 							if (plugin.register !== false) {
  2360 								ams.plugins.enabled[name] = null;
  2487 								ams.plugins.enabled[name] = null;
  2361 							}
  2488 							}
  2362 						}
  2489 						}
  2363 						var css = plugin.css;
       
  2364 						if (css) {
       
  2365 							ams.getCSS(css, name + '_css');
       
  2366 						}
       
  2367 						// If running in async mode, registered plug-ins are run
  2490 						// If running in async mode, registered plug-ins are run
  2368 						// before callback is called so we call plug-in manually
  2491 						// before callback is called so we call plug-in manually
  2369 						if (callbacks && (plugin.async !== false)) {
  2492 						if (callbacks && callbacks.length && (plugin.async !== false)) {
  2370 							for (index=0; index < callbacks.length; index++) {
  2493 							for (index=0; index < callbacks.length; index++) {
  2371 								callbacks[index](element);
  2494 								ams.getFunctionByName(callbacks[index])(element);
  2372 							}
  2495 							}
  2373 						}
  2496 						}
  2374 					}, {
  2497 					}, {
  2375 						async: plugin.async === undefined ? true : plugin.async
  2498 						async: plugin.async === undefined ? true : plugin.async
  2376 					});
  2499 					});
  2384 				}
  2507 				}
  2385 				if (disabled.indexOf(index) >= 0) {
  2508 				if (disabled.indexOf(index) >= 0) {
  2386 					continue;
  2509 					continue;
  2387 				}
  2510 				}
  2388 				var callbacks = ams.plugins.enabled[index];
  2511 				var callbacks = ams.plugins.enabled[index];
  2389 				switch (typeof(callbacks)) {
  2512 				if (callbacks) {
  2390 					case 'function':
  2513 					switch (typeof(callbacks)) {
  2391 						callbacks(element);
  2514 						case 'function':
  2392 						break;
  2515 							callbacks(element);
  2393 					default:
  2516 							break;
  2394 						for (var cb_index = 0; cb_index < callbacks.length; cb_index++) {
  2517 						default:
  2395 							var callback = callbacks[cb_index];
  2518 							for (var cb_index = 0; cb_index < callbacks.length; cb_index++) {
  2396 							if (typeof(callback) === 'function') {
  2519 								var callback = callbacks[cb_index];
  2397 								callback(element);
  2520 								if (typeof(callback) === 'function') {
       
  2521 									callback(element);
       
  2522 								}
  2398 							}
  2523 							}
  2399 						}
  2524 					}
  2400 				}
  2525 				}
  2401 			}
  2526 			}
  2402 		},
  2527 		},
  2403 
  2528 
  2404 		/**
  2529 		/**
  2407 		 * This way of defining data attributes can be used with HTML templates engines which don't allow you
  2532 		 * This way of defining data attributes can be used with HTML templates engines which don't allow you
  2408 		 * to create dynamic attributes easily.
  2533 		 * to create dynamic attributes easily.
  2409 		 */
  2534 		 */
  2410 		initData: function(element) {
  2535 		initData: function(element) {
  2411 			$('[data-ams-data]', element).each(function() {
  2536 			$('[data-ams-data]', element).each(function() {
  2412 				var handler = $(this);
  2537 				var data_element = $(this);
  2413 				var data = handler.data('ams-data');
  2538 				var data = data_element.data('ams-data');
  2414 				if (data) {
  2539 				if (data) {
  2415 					for (var name in data) {
  2540 					for (var name in data) {
  2416 						if (data.hasOwnProperty(name)) {
  2541 						if (data.hasOwnProperty(name)) {
  2417 							handler.attr('data-' + name, data[name]);
  2542 							data_element.attr('data-' + name, data[name]);
  2418 						}
  2543 						}
  2419 					}
  2544 					}
  2420 				}
  2545 				}
  2421 			});
  2546 			});
  2422 		},
  2547 		},
  3331 												}
  3456 												}
  3332 											}
  3457 											}
  3333 											// Set options
  3458 											// Set options
  3334 											var data_options = {
  3459 											var data_options = {
  3335 												bJQueryUI: false,
  3460 												bJQueryUI: false,
  3336 												bFilter: data.amsDatatableGlobalFilter !== false,
  3461 												bFilter: data.amsDatatableGlobalFilter !== false || extensions.indexOf('columnfilter') >= 0,
  3337 												bPaginate: data.amsDatatablePagination !== false,
  3462 												bPaginate: data.amsDatatablePagination !== false,
  3338 												bInfo: data.amsDatatableInfo !== false,
  3463 												bInfo: data.amsDatatableInfo !== false,
  3339 												bSort: data.amsDatatableSort !== false,
  3464 												bSort: data.amsDatatableSort !== false,
  3340 												aaSorting: sorting,
  3465 												aaSorting: sorting,
  3341 												aoColumns: columns.length > 0 ? columns : undefined,
  3466 												aoColumns: columns.length > 0 ? columns : undefined,
  3413 															break;
  3538 															break;
  3414 													}
  3539 													}
  3415 												}
  3540 												}
  3416 											}
  3541 											}
  3417 											settings = ams.executeFunctionByName(data.amsDatatableInitCallback, table, settings) || settings;
  3542 											settings = ams.executeFunctionByName(data.amsDatatableInitCallback, table, settings) || settings;
  3418 											try {  // Some settings can easilly generate DataTables exceptions...
  3543 											try {  // Some settings can easily generate DataTables exceptions...
  3419 												var plugin = table.dataTable(settings);
  3544 												var plugin = table.dataTable(settings);
  3420 												ams.executeFunctionByName(data.amsDatatableAfterInitCallback, table, plugin, settings);
  3545 												ams.executeFunctionByName(data.amsDatatableAfterInitCallback, table, plugin, settings);
  3421 												if (extensions.length > 0) {
  3546 												if (extensions.length > 0) {
  3422 													for (index=0; index < extensions.length; index++) {
  3547 													for (index=0; index < extensions.length; index++) {
  3423 														switch (extensions[index]) {
  3548 														switch (extensions[index]) {
  3987 				badge.addClass("hidden")
  4112 				badge.addClass("hidden")
  3988 					 .removeClass("bg-color-red bounceIn animated");
  4113 					 .removeClass("bg-color-red bounceIn animated");
  3989 			}
  4114 			}
  3990 		},
  4115 		},
  3991 
  4116 
       
  4117 		refreshNotificationsPanel: function(e) {
       
  4118 			var button = $(this);
       
  4119 			button.addClass('disabled');
       
  4120 			$('i', button).addClass('fa-spin');
       
  4121 			$('input[name="activity"]:checked', '#user-activity').change();
       
  4122 			$('i', button).removeClass('fa-spin');
       
  4123 			button.removeClass('disabled');
       
  4124 		},
       
  4125 
  3992 		/**
  4126 		/**
  3993 		 * Initialize desktop and mobile widgets
  4127 		 * Initialize desktop and mobile widgets
  3994 		 */
  4128 		 */
  3995 		_initDesktopWidgets: function(element) {
  4129 		_initDesktopWidgets: function(element) {
  3996 			if (ams.enable_widgets) {
  4130 			if (ams.enable_widgets) {
  4141 
  4275 
  4142 		/**
  4276 		/**
  4143 		 * Initialize breadcrumbs based on active menu position
  4277 		 * Initialize breadcrumbs based on active menu position
  4144 		 */
  4278 		 */
  4145 		_drawBreadCrumb: function() {
  4279 		_drawBreadCrumb: function() {
  4146 			var crumb = $('#ribbon OL.breadcrumb');
  4280 			var crumb = $('OL.breadcrumb', '#ribbon');
  4147 			$('li', crumb).not('.parent').remove();
  4281 			$('li', crumb).not('.parent').remove();
  4148 			if (!$('li', crumb).exists()) {
  4282 			if (!$('li', crumb).exists()) {
  4149 				crumb.append($('<li></li>').append($('<a></a>').text(ams.i18n.HOME)
  4283 				crumb.append($('<li></li>').append($('<a></a>').text(ams.i18n.HOME)
  4150 															   .addClass('padding-right-5')
  4284 															   .addClass('padding-right-5')
  4151 															   .attr('href', $('nav a[href!="#"]:first').attr('href'))));
  4285 															   .attr('href', $('nav a[href!="#"]:first').attr('href'))));
  4152 			}
  4286 			}
  4153 			$('nav LI.active >A').each(function() {
  4287 			$('LI.active >A', 'nav').each(function() {
  4154 				var menu = $(this);
  4288 				var menu = $(this);
  4155 				var body = $.trim(menu.clone()
  4289 				var body = $.trim(menu.clone()
  4156 									  .children(".badge")
  4290 									  .children(".badge")
  4157 									  .remove()
  4291 									  .remove()
  4158 									  .end()
  4292 									  .end()
  4193 				menu = $('A[href="' + hash + '"]', nav);
  4327 				menu = $('A[href="' + hash + '"]', nav);
  4194 				if (menu.exists()) {
  4328 				if (menu.exists()) {
  4195 					updateActiveMenus(menu);
  4329 					updateActiveMenus(menu);
  4196 				}
  4330 				}
  4197 				ams.skin.loadURL(url, container);
  4331 				ams.skin.loadURL(url, container);
  4198 				document.title = $('[data-ams-page-title]:first', container).data('ams-page-title') ||
  4332 				var prefix = $('html head title').data('ams-title-prefix');
  4199 								 menu.attr('title') ||
  4333 				document.title = (prefix ? prefix + ' > ' : '') +
  4200 								 document.title;
  4334 								 ($('[data-ams-page-title]:first', container).data('ams-page-title') ||
       
  4335 								  menu.attr('title') ||
       
  4336 								  document.title);
  4201 			} else {
  4337 			} else {
  4202 				var active_url = $('[data-ams-active-menu]').data('ams-active-menu');
  4338 				var active_url = $('[data-ams-active-menu]').data('ams-active-menu');
  4203 				if (active_url) {
  4339 				if (active_url) {
  4204 					menu = $('A[href="' + active_url + '"]', nav);
  4340 					menu = $('A[href="' + active_url + '"]', nav);
  4205 				} else {
  4341 				} else {
  4228 		 */
  4364 		 */
  4229 		registerCleanCallback: function(callback) {
  4365 		registerCleanCallback: function(callback) {
  4230 			var callbacks = ams.skin._clean_callbacks;
  4366 			var callbacks = ams.skin._clean_callbacks;
  4231 			if (callbacks.indexOf(callback) < 0) {
  4367 			if (callbacks.indexOf(callback) < 0) {
  4232 				callbacks.push(callback);
  4368 				callbacks.push(callback);
       
  4369 			}
       
  4370 		},
       
  4371 
       
  4372 		/**
       
  4373 		 * Remove given callback from registry
       
  4374 		 */
       
  4375 		unregisterCleanCallback: function(callback) {
       
  4376 			var callbacks = ams.skin._clean_callbacks;
       
  4377 			var index = callbacks.indexOf(callback);
       
  4378 			if (index >= 0) {
       
  4379 				callbacks.splice(index, 1);
  4233 			}
  4380 			}
  4234 		},
  4381 		},
  4235 
  4382 
  4236 		/**
  4383 		/**
  4237 		 * Call registered cleaning callbacks on given container
  4384 		 * Call registered cleaning callbacks on given container
  4263 				beforeSend: function() {
  4410 				beforeSend: function() {
  4264 					ams.skin.cleanContainer(container);
  4411 					ams.skin.cleanContainer(container);
  4265 					container.html('<h1 class="loading"><i class="fa fa-cog fa-spin"></i> Loading... </h1>');
  4412 					container.html('<h1 class="loading"><i class="fa fa-cog fa-spin"></i> Loading... </h1>');
  4266 					if (container[0] === $('#content')[0]) {
  4413 					if (container[0] === $('#content')[0]) {
  4267 						ams.skin._drawBreadCrumb();
  4414 						ams.skin._drawBreadCrumb();
  4268 						document.title = $('.breadcrumb LI:last-child').text();
  4415 						var prefix = $('html head title').data('ams-title-prefix');
       
  4416 						document.title = (prefix ? prefix + ' > ' : '') + $('.breadcrumb LI:last-child').text();
  4269 						$('html, body').animate({scrollTop: 0}, 'fast');
  4417 						$('html, body').animate({scrollTop: 0}, 'fast');
  4270 					} else {
  4418 					} else {
  4271 						container.animate({scrollTop: 0}, 'fast');
  4419 						container.animate({scrollTop: 0}, 'fast');
  4272 					}
  4420 					}
  4273 				},
  4421 				},
  4485 				dropdown.fadeOut(150)
  4633 				dropdown.fadeOut(150)
  4486 						.prev().removeClass("active");
  4634 						.prev().removeClass("active");
  4487 			}
  4635 			}
  4488 		});
  4636 		});
  4489 
  4637 
  4490 		$('input[name="activity"]').change(function() {
  4638 		$('input[name="activity"]').change(function(e) {
  4491 			var url = $(this).data('ams-url');
  4639 			var href = $(this).data('ams-url');
  4492 			var container = $('.ajax-notifications');
  4640 			if (href) {
  4493 			ams.skin.loadURL(url, container);
  4641 				e.preventDefault();
       
  4642 				e.stopPropagation();
       
  4643 				var href_getter = ams.getFunctionByName(href);
       
  4644 				if (typeof(href_getter) === 'function') {
       
  4645 					href = href_getter.call(this);
       
  4646 				}
       
  4647 				if (typeof(href) === 'function') {
       
  4648 					// Javascript function call
       
  4649 					href.call(this);
       
  4650 				} else {
       
  4651 					var container = $('.ajax-notifications');
       
  4652 					ams.skin.loadURL(href, container);
       
  4653 				}
       
  4654 			}
  4494 		});
  4655 		});
  4495 
  4656 
  4496 		// Logout button
  4657 		// Logout button
  4497 		$('#logout a').click(function(e) {
  4658 		$('a', '#logout').click(function(e) {
  4498 			e.preventDefault();
  4659 			e.preventDefault();
  4499 			e.stopPropagation();
  4660 			e.stopPropagation();
  4500 			//get the link
  4661 			//get the link
  4501 			ams.loginURL = $(this).attr('href');
  4662 			ams.loginURL = $(this).attr('href');
  4502 			// ask verification
  4663 			// ask verification
  4658 		$(document).on('click', 'button[type="submit"], button.submit', function() {
  4819 		$(document).on('click', 'button[type="submit"], button.submit', function() {
  4659 			var button = $(this);
  4820 			var button = $(this);
  4660 			$(button.get(0).form).data('ams-submit-button', button);
  4821 			$(button.get(0).form).data('ams-submit-button', button);
  4661 		});
  4822 		});
  4662 
  4823 
       
  4824 		// Cancel clicks on readonly checkbox
       
  4825 		$(document).on('click', 'input[type="checkbox"][readonly]', function() {
       
  4826 			return false;
       
  4827 		});
       
  4828 
  4663 		// Initialize custom click handlers
  4829 		// Initialize custom click handlers
  4664 		$(document).on('click', '[data-ams-click-handler]', function(e) {
  4830 		$(document).on('click', '[data-ams-click-handler]', function(e) {
  4665 			var source = $(this);
  4831 			var source = $(this);
  4666 			var handlers = source.data('ams-disabled-handlers');
  4832 			var handlers = source.data('ams-disabled-handlers');
  4667 			if ((handlers === true) || (handlers === 'click') || (handlers === 'all')) {
  4833 			if ((handlers === true) || (handlers === 'click') || (handlers === 'all')) {
  4767 				}
  4933 				}
  4768 				finally {
  4934 				finally {
  4769 					$('i', link).remove();
  4935 					$('i', link).remove();
  4770 				}
  4936 				}
  4771 			}
  4937 			}
       
  4938 		});
       
  4939 
       
  4940 		// Check modal form dialogs on close
       
  4941 		$(document).on('hide.bs.modal', function(e) {
       
  4942 			var modal = $(e.target);
       
  4943 			ams.form.confirmChangedForm(modal, function() {
       
  4944 				// Confirm closing if OK
       
  4945 				modal.data('modal').isShown = true;
       
  4946 				return true;
       
  4947 			}, function() {
       
  4948 				// Prevent closing if cancelled
       
  4949 				e.preventDefault();
       
  4950 				return false;
       
  4951 			});
  4772 		});
  4952 		});
  4773 
  4953 
  4774 		// Init page content
  4954 		// Init page content
  4775 		ams.initContent(document);
  4955 		ams.initContent(document);
  4776 		if (ams.ajax_nav && nav.exists()) {
  4956 		if (ams.ajax_nav && nav.exists()) {