src/ztfy/myams/resources/js/myams.js
changeset 136 3ea42c4b9938
parent 135 f7b7e3f21da6
child 142 0201f1422bd7
equal deleted inserted replaced
135:f7b7e3f21da6 136:3ea42c4b9938
   105 		/*
   105 		/*
   106 		 * Check if current object is empty or not
   106 		 * Check if current object is empty or not
   107 		 */
   107 		 */
   108 		exists: function() {
   108 		exists: function() {
   109 			return $(this).length > 0;
   109 			return $(this).length > 0;
       
   110 		},
       
   111 
       
   112 		/*
       
   113 		 * Get object if it supports given CSS class,
       
   114 		 * otherwise looks for parents
       
   115 		 */
       
   116 		objectOrParentWithClass: function(klass) {
       
   117 			if (this.hasClass(klass))
       
   118 				return this;
       
   119 			else
       
   120 				return this.parents('.' + klass);
   110 		},
   121 		},
   111 
   122 
   112 		/*
   123 		/*
   113 		 * Build an array of attributes of the given selection
   124 		 * Build an array of attributes of the given selection
   114 		 */
   125 		 */
   218 		 * Main menus manager
   229 		 * Main menus manager
   219 		 */
   230 		 */
   220 		myams_menu: function(options) {
   231 		myams_menu: function(options) {
   221 			// Extend our default options with those provided
   232 			// Extend our default options with those provided
   222 			var defaults = {
   233 			var defaults = {
   223 				accordion : 'true',
   234 				accordion : true,
   224 				speed : 200,
   235 				speed : 200,
   225 				closedSign : '<em class="fa fa-angle-down"></em>',
   236 				closedSign : '<em class="fa fa-angle-down"></em>',
   226 				openedSign : '<em class="fa fa-angle-up"></em>'
   237 				openedSign : '<em class="fa fa-angle-up"></em>'
   227 			};
   238 			};
   228 			var settings = $.extend({}, defaults, options);
   239 			var settings = $.extend({}, defaults, options);
   582 					msg = 0;
   593 					msg = 0;
   583 				else
   594 				else
   584 					msg = 1;
   595 					msg = 1;
   585 			}
   596 			}
   586 			return msg;
   597 			return msg;
       
   598 		},
       
   599 
       
   600 		copyToClipboard: function() {
       
   601 			return function() {
       
   602 				var source = $(this);
       
   603 				source.parents('.btn-group').removeClass('open');
       
   604 				window.prompt(MyAMS.i18n.CLIPBOARD_COPY, source.text());
       
   605 			}
   587 		}
   606 		}
   588 	};
   607 	};
   589 
   608 
   590 
   609 
   591 	/**
   610 	/**
   860 						ams.dialog.close(form);
   879 						ams.dialog.close(form);
   861 					url = result.location || window.location.href;
   880 					url = result.location || window.location.href;
   862 					if (result.window) {
   881 					if (result.window) {
   863 						window.open(url, result.window, result.options);
   882 						window.open(url, result.window, result.options);
   864 					} else {
   883 					} else {
   865 						window.location.href = url;
   884 						if (window.location.href == url) {
       
   885 							window.location.reload(true);
       
   886 						} else {
       
   887 							window.location.href = url;
       
   888 						}
   866 					}
   889 					}
   867 					break;
   890 					break;
   868 				default:
   891 				default:
   869 					console.log("Unhandled status: " + status);
   892 					console.log("Unhandled status: " + status);
   870 					break;
   893 					break;
  1668 	 * Modal dialogs helper functions
  1691 	 * Modal dialogs helper functions
  1669 	 */
  1692 	 */
  1670 	MyAMS.dialog = {
  1693 	MyAMS.dialog = {
  1671 
  1694 
  1672 		/**
  1695 		/**
       
  1696 		 * List of registered 'shown' callbacks
       
  1697 		 */
       
  1698 		_shown_callbacks: [],
       
  1699 
       
  1700 		/**
       
  1701 		 * Register a callback which should be called when a dialog is shown
       
  1702 		 */
       
  1703 		registerShownCallback: function(callback, element) {
       
  1704 			var dialog;
       
  1705 			if (element) {
       
  1706 				dialog = element.objectOrParentWithClass('modal-dialog');
       
  1707 			}
       
  1708 			if (dialog && dialog.exists()) {
       
  1709 				var callbacks = dialog.data('shown-callbacks');
       
  1710 				if (callbacks === undefined) {
       
  1711 					callbacks = [];
       
  1712 					dialog.data('shown-callbacks', callbacks);
       
  1713 				}
       
  1714 			} else {
       
  1715 				callbacks = ams.dialog._shown_callbacks;
       
  1716 			}
       
  1717 			if (callbacks.indexOf(callback) < 0)
       
  1718 				callbacks.push(callback);
       
  1719 		},
       
  1720 
       
  1721 		/**
  1673 		 * List of registered 'hide' callbacks
  1722 		 * List of registered 'hide' callbacks
  1674 		 */
  1723 		 */
  1675 		_hide_callbacks: [],
  1724 		_hide_callbacks: [],
  1676 
  1725 
  1677 		/**
  1726 		/**
  1678 		 * Register a callback which should be called when a dialog is closed
  1727 		 * Register a callback which should be called when a dialog is closed
  1679 		 */
  1728 		 */
  1680 		registerHideCallback: function(callback) {
  1729 		registerHideCallback: function(callback, element) {
  1681 			var callbacks = ams.dialog._hide_callbacks;
  1730 			var dialog;
       
  1731 			if (element) {
       
  1732 				dialog = element.objectOrParentWithClass('modal-dialog');
       
  1733 			}
       
  1734 			if (dialog && dialog.exists()) {
       
  1735 				var callbacks = dialog.data('hide-callbacks');
       
  1736 				if (callbacks === undefined) {
       
  1737 					callbacks = [];
       
  1738 					dialog.data('hide-callbacks', callbacks);
       
  1739 				}
       
  1740 			} else {
       
  1741 				callbacks = ams.dialog._hide_callbacks;
       
  1742 			}
  1682 			if (callbacks.indexOf(callback) < 0)
  1743 			if (callbacks.indexOf(callback) < 0)
  1683 				callbacks.push(callback);
  1744 				callbacks.push(callback);
  1684 		},
  1745 		},
  1685 
  1746 
  1686 		/**
  1747 		/**
  1791 					bottom.show();
  1852 					bottom.show();
  1792 			}
  1853 			}
  1793 
  1854 
  1794 			var modal = e.target;
  1855 			var modal = e.target;
  1795 			var viewport = $('.modal-viewport', modal);
  1856 			var viewport = $('.modal-viewport', modal);
  1796 			if (viewport.length == 0)
  1857 			if (viewport.exists()) {
  1797 				return;
  1858 				var maxHeight = parseInt(viewport.css('max-height'));
  1798 			var maxHeight = parseInt(viewport.css('max-height'));
  1859 				var barWidth = $.scrollbarWidth();
  1799 			var barWidth = $.scrollbarWidth();
  1860 				if (viewport.height() == maxHeight) {
  1800 			if (viewport.height() == maxHeight) {
  1861 					$('<div></div>').addClass('scrollmarker')
  1801 				$('<div></div>').addClass('scrollmarker')
  1862 						.addClass('top')
  1802 								.addClass('top')
  1863 						.css('top', 0)
  1803 								.css('top', 0)
  1864 						.css('width', viewport.width() - barWidth)
  1804 								.css('width', viewport.width() - barWidth)
  1865 						.hide()
  1805 								.hide()
  1866 						.appendTo(viewport);
  1806 								.appendTo(viewport);
  1867 					$('<div></div>').addClass('scrollmarker')
  1807 				$('<div></div>').addClass('scrollmarker')
  1868 						.addClass('bottom')
  1808 								.addClass('bottom')
  1869 						.css('top', maxHeight - 20)
  1809 								.css('top', maxHeight - 20)
  1870 						.css('width', viewport.width() - barWidth)
  1810 								.css('width', viewport.width() - barWidth)
  1871 						.appendTo(viewport);
  1811 								.appendTo(viewport);
  1872 					viewport.scroll(resetViewport);
  1812 				viewport.scroll(resetViewport);
  1873 					viewport.off('resize')
  1813 				viewport.off('resize')
       
  1814 						.on('resize', resetViewport);
  1874 						.on('resize', resetViewport);
  1815 			} else {
  1875 				} else {
  1816 				$('.scrollmarker', viewport).remove();
  1876 					$('.scrollmarker', viewport).remove();
       
  1877 				}
       
  1878 			}
       
  1879 
       
  1880 			// Call shown callbacks registered for this dialog
       
  1881 			var callbacks = $('.modal-dialog', modal).data('shown-callbacks');
       
  1882 			if (callbacks) {
       
  1883 				for (var index in callbacks) {
       
  1884 					callbacks[index].call(modal);
       
  1885 				}
       
  1886 			}
       
  1887 			// Call globally registered shown callbacks
       
  1888 			callbacks = ams.dialog._shown_callbacks;
       
  1889 			for (index in callbacks) {
       
  1890 				callbacks[index].call(modal);
  1817 			}
  1891 			}
  1818 		},
  1892 		},
  1819 
  1893 
  1820 		/**
  1894 		/**
  1821 		 * Close modal dialog associated with given context
  1895 		 * Close modal dialog associated with given context
  1835 		 */
  1909 		 */
  1836 		hidden: function(e) {
  1910 		hidden: function(e) {
  1837 			var modal = e.target;
  1911 			var modal = e.target;
  1838 			// Call registered cleaning callbacks
  1912 			// Call registered cleaning callbacks
  1839 			ams.skin.cleanContainer(modal);
  1913 			ams.skin.cleanContainer(modal);
  1840 			// Call registered hide callbacks
  1914 			// Call hide callbacks registered for this dialog
  1841 			var callbacks = ams.dialog._hide_callbacks;
  1915 			var callbacks = $('.modal-dialog', modal).data('hide-callbacks');
  1842 			for (var index in callbacks) {
  1916 			if (callbacks) {
       
  1917 				for (var index in callbacks) {
       
  1918 					callbacks[index].call(modal);
       
  1919 				}
       
  1920 			}
       
  1921 			// Call globally registered hide callbacks
       
  1922 			callbacks = ams.dialog._hide_callbacks;
       
  1923 			for (index in callbacks) {
  1843 				callbacks[index].call(modal);
  1924 				callbacks[index].call(modal);
  1844 			}
  1925 			}
  1845 		}
  1926 		}
  1846 	};
  1927 	};
  1847 
  1928 
  2184 											settings = ams.executeFunctionByName(data.amsHintInitCallback, hint, settings) || settings;
  2265 											settings = ams.executeFunctionByName(data.amsHintInitCallback, hint, settings) || settings;
  2185 											var plugin = hint.tipsy(settings);
  2266 											var plugin = hint.tipsy(settings);
  2186 											ams.executeFunctionByName(data.amsHintAfterInitCallback, hint, plugin, settings);
  2267 											ams.executeFunctionByName(data.amsHintAfterInitCallback, hint, plugin, settings);
  2187 										});
  2268 										});
  2188 								   });
  2269 								   });
       
  2270 			},
       
  2271 
       
  2272 			/**
       
  2273 			 * Context menu plug-in
       
  2274 			 */
       
  2275 			contextMenu: function(element) {
       
  2276 				var menus = $('.context-menu', element);
       
  2277 				if (menus.length > 0) {
       
  2278 					menus.each(function() {
       
  2279 						var menu = $(this);
       
  2280 						var data = menu.data();
       
  2281 						var data_options = {
       
  2282 							menuSelector: data.amsContextmenuSelector,
       
  2283 							menuSelected: ams.helpers.contextMenuHandler
       
  2284 						};
       
  2285 						var settings = $.extend({}, data_options, data.amsContextmenuOptions);
       
  2286 						settings = ams.executeFunctionByName(data.amsContextmenuInitCallback, menu, settings) || settings;
       
  2287 						var plugin = menu.contextMenu(settings);
       
  2288 						ams.executeFunctionByName(data.amsContextmenuAfterInitCallback, menu, plugin, settings);
       
  2289 					});
       
  2290 				}
  2189 			},
  2291 			},
  2190 
  2292 
  2191 			/**
  2293 			/**
  2192 			 * Fieldset legend switcher
  2294 			 * Fieldset legend switcher
  2193 			 */
  2295 			 */
  2275 								var veto = {};
  2377 								var veto = {};
  2276 								var isChecked = $(this).is(':checked');
  2378 								var isChecked = $(this).is(':checked');
  2277 								legend.trigger('ams.checker.before-switch', [legend, veto]);
  2379 								legend.trigger('ams.checker.before-switch', [legend, veto]);
  2278 								if (veto.veto) {
  2380 								if (veto.veto) {
  2279 									// reset checked status because event is fired after change...
  2381 									// reset checked status because event is fired after change...
  2280 									$(this).attr('checked', !isChecked);
  2382 									$(this).prop('checked', !isChecked);
  2281 									return;
  2383 									return;
  2282 								}
  2384 								}
  2283 								ams.executeFunctionByName(data.amsCheckerChangeHandler, legend, isChecked);
  2385 								ams.executeFunctionByName(data.amsCheckerChangeHandler, legend, isChecked);
  2284 								if (!data.amsCheckerCancelDefault) {
  2386 								if (!data.amsCheckerCancelDefault) {
  2285 									var hidden = input.data('ams-checker-hidden-input');
  2387 									var hidden = input.data('ams-checker-hidden-input');
  2292 											hidden.val(checkedValue);
  2394 											hidden.val(checkedValue);
  2293 										$('[data-required]', fieldset).attr('required', 'required');
  2395 										$('[data-required]', fieldset).attr('required', 'required');
  2294 										legend.trigger('ams.checker.opened', [legend]);
  2396 										legend.trigger('ams.checker.opened', [legend]);
  2295 									} else {
  2397 									} else {
  2296 										if (data.amsCheckerMode == 'disable')
  2398 										if (data.amsCheckerMode == 'disable')
  2297 											fieldset.attr('disabled', 'disabled');
  2399 											fieldset.prop('disabled', 'disabled');
  2298 										else
  2400 										else
  2299 											fieldset.addClass('switched');
  2401 											fieldset.addClass('switched');
  2300 										if (hidden)
  2402 										if (hidden)
  2301 											hidden.val(uncheckedValue);
  2403 											hidden.val(uncheckedValue);
  2302 										$('[data-required]', fieldset).removeAttr('required');
  2404 										$('[data-required]', fieldset).removeAttr('required');
  2424 					});
  2526 					});
  2425 				}
  2527 				}
  2426 			},
  2528 			},
  2427 
  2529 
  2428 			/**
  2530 			/**
  2429 			 * Context menu plug-in
  2531 			 * JQuery typeahead plug-in
  2430 			 */
  2532 			 */
  2431 			contextMenu: function(element) {
  2533 			typeahead: function(element) {
  2432 				var menus = $('.context-menu', element);
  2534 				var typeaheads = $('.typeahead', element);
  2433 				if (menus.length > 0) {
  2535 				if (typeaheads.length > 0) {
  2434 					menus.each(function() {
  2536 					ams.ajax.check($.fn.typeahead,
  2435 						var menu = $(this);
  2537 								   ams.baseURL + 'ext/jquery-typeahead' + ams.devext + '.js',
  2436 						var data = menu.data();
  2538 								   function() {
  2437 						var data_options = {
  2539 										typeaheads.each(function() {
  2438 							menuSelector: data.amsContextmenuSelector,
  2540 											var input = $(this);
  2439 							menuSelected: ams.helpers.contextMenuHandler
  2541 											var data = input.data();
  2440 						};
  2542 											var data_options = {};
  2441 						var settings = $.extend({}, data_options, data.amsContextmenuOptions);
  2543 											var settings = $.extend({}, data_options, data.amsTypeaheadOptions);
  2442 						settings = ams.executeFunctionByName(data.amsContextmenuInitCallback, menu, settings) || settings;
  2544 											settings = ams.executeFunctionByName(data.amsTypeaheadInitCallback, input, settings) || settings;
  2443 						var plugin = menu.contextMenu(settings);
  2545 											var plugin = input.typeahead(settings);
  2444 						ams.executeFunctionByName(data.amsContextmenuAfterInitCallback, menu, plugin, settings);
  2546 											ams.executeFunctionByName(data.amsTypeaheadAfterInitCallback, input, plugin, settings);
  2445 					});
  2547 										});
       
  2548 								   });
  2446 				}
  2549 				}
  2447 			},
  2550 			},
  2448 
  2551 
  2449 			/**
  2552 			/**
  2450 			 * Select2 plug-in
  2553 			 * Select2 plug-in
  2774 											};
  2877 											};
  2775 											var settings = $.extend({}, data_options, data.amsColorpickerOptions);
  2878 											var settings = $.extend({}, data_options, data.amsColorpickerOptions);
  2776 											settings = ams.executeFunctionByName(data.amsColorpickerInitCallback, input, settings) || settings;
  2879 											settings = ams.executeFunctionByName(data.amsColorpickerInitCallback, input, settings) || settings;
  2777 											var plugin = input.minicolors(settings);
  2880 											var plugin = input.minicolors(settings);
  2778 											ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings);
  2881 											ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings);
  2779 										});
       
  2780 								   });
       
  2781 				}
       
  2782 			},
       
  2783 
       
  2784 			/**
       
  2785 			 * JQuery typeahead plug-in
       
  2786 			 */
       
  2787 			typeahead: function(element) {
       
  2788 				var typeaheads = $('.typeahead', element);
       
  2789 				if (typeaheads.length > 0) {
       
  2790 					ams.ajax.check($.fn.typeahead,
       
  2791 								   ams.baseURL + 'ext/jquery-typeahead' + ams.devext + '.js',
       
  2792 								   function() {
       
  2793 										typeaheads.each(function() {
       
  2794 											var input = $(this);
       
  2795 											var data = input.data();
       
  2796 											var data_options = {};
       
  2797 											var settings = $.extend({}, data_options, data.amsTypeaheadOptions);
       
  2798 											settings = ams.executeFunctionByName(data.amsTypeaheadInitCallback, input, settings) || settings;
       
  2799 											var plugin = input.typeahead(settings);
       
  2800 											ams.executeFunctionByName(data.amsTypeaheadAfterInitCallback, input, plugin, settings);
       
  2801 										});
  2882 										});
  2802 								   });
  2883 								   });
  2803 				}
  2884 				}
  2804 			},
  2885 			},
  2805 
  2886 
  2894 				var tables = $('.datatable', element);
  2975 				var tables = $('.datatable', element);
  2895 				if (tables.length > 0) {
  2976 				if (tables.length > 0) {
  2896 					ams.ajax.check($.fn.dataTable,
  2977 					ams.ajax.check($.fn.dataTable,
  2897 								   ams.baseURL + 'ext/jquery-dataTables-1.9.4' + ams.devext + '.js',
  2978 								   ams.baseURL + 'ext/jquery-dataTables-1.9.4' + ams.devext + '.js',
  2898 								   function(first_load) {
  2979 								   function(first_load) {
  2899 										if (first_load) {
       
  2900 											$.fn.dataTableExt.oSort['numeric-comma-asc']  = function(a, b) {
       
  2901 												var x = a.replace(/,/, ".").replace(/ /g, '');
       
  2902 												var y = b.replace(/,/, ".").replace(/ /g, '');
       
  2903 												x = parseFloat(x);
       
  2904 												y = parseFloat(y);
       
  2905 												return ((x < y) ? -1 : ((x > y) ?  1 : 0));
       
  2906 											};
       
  2907 											$.fn.dataTableExt.oSort['numeric-comma-desc'] = function(a, b) {
       
  2908 												var x = a.replace(/,/, ".").replace(/ /g, '');
       
  2909 												var y = b.replace(/,/, ".").replace(/ /g, '');
       
  2910 												x = parseFloat(x);
       
  2911 												y = parseFloat(y);
       
  2912 												return ((x < y) ?  1 : ((x > y) ? -1 : 0));
       
  2913 											};
       
  2914 										}
       
  2915 										$(tables).each(function() {
  2980 										$(tables).each(function() {
  2916 											ams.ajax.check($.fn.dataTableExt.oPagination['bootstrap_full'],
  2981 											ams.ajax.check($.fn.dataTableExt.oPagination['bootstrap_full'],
  2917 														   ams.baseURL + 'myams-dataTables' + ams.devext + '.js');
  2982 														   ams.baseURL + 'myams-dataTables' + ams.devext + '.js');
  2918 											var table = $(this);
  2983 											var table = $(this);
  2919 											var data = table.data();
  2984 											var data = table.data();
  2920 											var extensions = (data.amsDatatableExtensions || '').split(/\s+/);
  2985 											var extensions = (data.amsDatatableExtensions || '').split(/\s+/);
       
  2986 											// Check DOM elements
  2921 											var sDom = data.amsDatatableSdom ||
  2987 											var sDom = data.amsDatatableSdom ||
  2922 												"W" +
  2988 												"W" +
  2923 												((extensions.indexOf('colreorder') >= 0 ||
  2989 												((extensions.indexOf('colreorder') >= 0 ||
  2924 												  extensions.indexOf('colreorderwithresize') >= 0) ? 'R' : '') +
  2990 												  extensions.indexOf('colreorderwithresize') >= 0) ? 'R' : '') +
  2925 												"<'dt-top-row'" +
  2991 												"<'dt-top-row'" +
  2930 												">r<'dt-wrapper't" +
  2996 												">r<'dt-wrapper't" +
  2931 												(extensions.indexOf('scroller') >= 0 ? 'S' : '') +
  2997 												(extensions.indexOf('scroller') >= 0 ? 'S' : '') +
  2932 												"><'dt-row dt-bottom-row'<'row'<'col-sm-6'" +
  2998 												"><'dt-row dt-bottom-row'<'row'<'col-sm-6'" +
  2933 												(data.amsDatatableInformation === false ? '': 'i') +
  2999 												(data.amsDatatableInformation === false ? '': 'i') +
  2934 												"><'col-sm-6 text-right'p>>";
  3000 												"><'col-sm-6 text-right'p>>";
       
  3001 											var index;
       
  3002 											// Check initial sorting
       
  3003 											var sorting = data.amsDatatableSorting;
       
  3004 											if (typeof(sorting) === 'string') {
       
  3005 												var sortings = sorting.split(';');
       
  3006 												sorting = [];
       
  3007 												for (index in sortings) {
       
  3008 													var col_sorting = sortings[index].split(',');
       
  3009 													col_sorting[0] = parseInt(col_sorting[0]);
       
  3010 													sorting.push(col_sorting);
       
  3011 												}
       
  3012 											}
       
  3013 											// Check columns types
       
  3014 											var columns = [];
       
  3015 											var sort_types = $('th', table).listattr('data-ams-datatable-stype');
       
  3016 											for (index in sort_types) {
       
  3017 												var sort_type = sort_types[index];
       
  3018 												if (sort_type) {
       
  3019 													var column = columns[index] || {};
       
  3020 													column.sType = sort_type;
       
  3021 													columns[index] = column;
       
  3022 												}
       
  3023 											}
       
  3024 											// Set options
  2935 											var data_options = {
  3025 											var data_options = {
  2936 												bJQueryUI: false,
  3026 												bJQueryUI: false,
  2937 												bFilter: data.amsDatatableGlobalFilter !== false,
  3027 												bFilter: data.amsDatatableGlobalFilter !== false,
  2938 												bPaginate: data.amsDatatablePagination !== false,
  3028 												bPaginate: data.amsDatatablePagination !== false,
  2939 												bInfo: data.amsDatatableInfo !== false,
  3029 												bInfo: data.amsDatatableInfo !== false,
  2940 												bSort: data.amsDatatableSort !== false,
  3030 												bSort: data.amsDatatableSort !== false,
  2941 												aaSorting: data.amsDatatableSorting,
  3031 												aaSorting: sorting,
       
  3032 												aoColumns: columns.length > 0 ? columns : undefined,
  2942 												bDeferRender: true,
  3033 												bDeferRender: true,
  2943 												bAutoWidth: false,
  3034 												bAutoWidth: false,
  2944 												iDisplayLength: data.amsDatatableDisplayLength || 25,
  3035 												iDisplayLength: data.amsDatatableDisplayLength || 25,
  2945 												sPaginationType: data.amsDatatablePaginationType || 'bootstrap_full',
  3036 												sPaginationType: data.amsDatatablePaginationType || 'bootstrap_full',
  2946 												sDom: sDom,
  3037 												sDom: sDom,
  2949 													$('.ColVis_Button').addClass('btn btn-default btn-sm')
  3040 													$('.ColVis_Button').addClass('btn btn-default btn-sm')
  2950 																	   .html((ams.plugins.i18n.datatables.sColumns || "Columns") + ' <i class="fa fa-fw fa-caret-down"></i>');
  3041 																	   .html((ams.plugins.i18n.datatables.sColumns || "Columns") + ' <i class="fa fa-fw fa-caret-down"></i>');
  2951 												}
  3042 												}
  2952 											};
  3043 											};
  2953 											var settings = $.extend({}, data_options, data.amsDatatableOptions);
  3044 											var settings = $.extend({}, data_options, data.amsDatatableOptions);
  2954 											var index;
       
  2955 											if (extensions.length > 0) {
  3045 											if (extensions.length > 0) {
  2956 												for (index in extensions) {
  3046 												for (index in extensions) {
  2957 													switch (extensions[index]) {
  3047 													switch (extensions[index]) {
  2958 														case 'autofill':
  3048 														case 'autofill':
  2959 															ams.ajax.check($.fn.dataTable.AutoFill,
  3049 															ams.ajax.check($.fn.dataTable.AutoFill,
  3014 															break;
  3104 															break;
  3015 													}
  3105 													}
  3016 												}
  3106 												}
  3017 											}
  3107 											}
  3018 											settings = ams.executeFunctionByName(data.amsDatatableInitCallback, table, settings) || settings;
  3108 											settings = ams.executeFunctionByName(data.amsDatatableInitCallback, table, settings) || settings;
  3019 											var plugin = table.dataTable(settings);
  3109 											try {  // Some settings can easilly generate DataTables exceptions...
  3020 											ams.executeFunctionByName(data.amsDatatableAfterInitCallback, table, plugin, settings);
  3110 												var plugin = table.dataTable(settings);
  3021 											if (extensions.length > 0) {
  3111 												ams.executeFunctionByName(data.amsDatatableAfterInitCallback, table, plugin, settings);
  3022 												for (index in extensions) {
  3112 												if (extensions.length > 0) {
  3023 													switch (extensions[index]) {
  3113 													for (index in extensions) {
  3024 														case 'autofill':
  3114 														switch (extensions[index]) {
  3025 															var af_settings = $.extend({}, data.amsDatatableAutofillOptions, settings.autofill);
  3115 															case 'autofill':
  3026 															af_settings = ams.executeFunctionByName(data.amsDatatableAutofillInitCallback, table, af_settings) || af_settings;
  3116 																var af_settings = $.extend({}, data.amsDatatableAutofillOptions, settings.autofill);
  3027 															table.data('ams-autofill', data.amsDatatableAutofillConstructor === undefined
  3117 																af_settings = ams.executeFunctionByName(data.amsDatatableAutofillInitCallback, table, af_settings) || af_settings;
  3028 																						? new $.fn.dataTable.AutoFill(table, af_settings)
  3118 																table.data('ams-autofill', data.amsDatatableAutofillConstructor === undefined
  3029 																						: ams.executeFunctionByName(data.amsDatatableAutofillConstructor, table, plugin, af_settings));
  3119 																							? new $.fn.dataTable.AutoFill(table, af_settings)
  3030 															break;
  3120 																							: ams.executeFunctionByName(data.amsDatatableAutofillConstructor, table, plugin, af_settings));
  3031 														case 'columnfilter':
  3121 																break;
  3032 															var cf_default = {
  3122 															case 'columnfilter':
  3033 																sPlaceHolder: 'head:after'
  3123 																var cf_default = {
  3034 															};
  3124 																	sPlaceHolder: 'head:after'
  3035 															var cf_settings = $.extend({}, cf_default, data.amsDatatableColumnfilterOptions, settings.columnfilter);
  3125 																};
  3036 															cf_settings = ams.executeFunctionByName(data.amsDatatableColumnfilterInitCallback, table, cf_settings) || cf_settings;
  3126 																var cf_settings = $.extend({}, cf_default, data.amsDatatableColumnfilterOptions, settings.columnfilter);
  3037 															table.data('ams-columnfilter', data.amsDatatableColumnfilterConstructor === undefined
  3127 																cf_settings = ams.executeFunctionByName(data.amsDatatableColumnfilterInitCallback, table, cf_settings) || cf_settings;
  3038 																						? plugin.columnFilter(cf_settings)
  3128 																table.data('ams-columnfilter', data.amsDatatableColumnfilterConstructor === undefined
  3039 																						: ams.executeFunctionByName(data.amsDatatableColumnfilterConstructor, table, plugin, cf_settings));
  3129 																							? plugin.columnFilter(cf_settings)
  3040 															break;
  3130 																							: ams.executeFunctionByName(data.amsDatatableColumnfilterConstructor, table, plugin, cf_settings));
  3041 														case 'editable':
  3131 																break;
  3042 															var ed_settings = $.extend({}, data.amsDatatableEditableOptions, settings.editable);
  3132 															case 'editable':
  3043 															ed_settings = ams.executeFunctionByName(data.amsDatatableEditableInitCallback, table, ed_settings) || ed_settings;
  3133 																var ed_settings = $.extend({}, data.amsDatatableEditableOptions, settings.editable);
  3044 															table.data('ams-editable', data.amsDatatableEditableConstructor === undefined
  3134 																ed_settings = ams.executeFunctionByName(data.amsDatatableEditableInitCallback, table, ed_settings) || ed_settings;
  3045 																						? table.makeEditable(ed_settings)
  3135 																table.data('ams-editable', data.amsDatatableEditableConstructor === undefined
  3046 																						: ams.executeFunctionByName(data.amsDatatableEditableConstructor, table, plugin, ed_settings));
  3136 																							? table.makeEditable(ed_settings)
  3047 															break;
  3137 																							: ams.executeFunctionByName(data.amsDatatableEditableConstructor, table, plugin, ed_settings));
  3048 														case 'fixedcolumns':
  3138 																break;
  3049 															var fc_settings = $.extend({}, data.amsDatatableFixedcolumnsOptions, settings.fixedcolumns);
  3139 															case 'fixedcolumns':
  3050 															fc_settings = ams.executeFunctionByName(data.amsDatatableFixedcolumnsInitCallback, table, fc_settings) || fc_settings;
  3140 																var fc_settings = $.extend({}, data.amsDatatableFixedcolumnsOptions, settings.fixedcolumns);
  3051 															table.data('ams-fixedcolumns', data.amsDatatableFixedcolumnsConstructor === undefined
  3141 																fc_settings = ams.executeFunctionByName(data.amsDatatableFixedcolumnsInitCallback, table, fc_settings) || fc_settings;
  3052 																						? new $.fn.dataTable.FixedColumns(table, fc_settings)
  3142 																table.data('ams-fixedcolumns', data.amsDatatableFixedcolumnsConstructor === undefined
  3053 																						: ams.executeFunctionByName(data.amsDatatableFixedcolumnsConstructor, table, plugin, fc_settings));
  3143 																							? new $.fn.dataTable.FixedColumns(table, fc_settings)
  3054 															break;
  3144 																							: ams.executeFunctionByName(data.amsDatatableFixedcolumnsConstructor, table, plugin, fc_settings));
  3055 														case 'fixedheader':
  3145 																break;
  3056 															var fh_settings = $.extend({}, data.amsDatatableFixedheaderOptions, settings.fixedheader);
  3146 															case 'fixedheader':
  3057 															fh_settings = ams.executeFunctionByName(data.amsDatatableFixedheadeInitCallback, table, fh_settings) || fh_settings;
  3147 																var fh_settings = $.extend({}, data.amsDatatableFixedheaderOptions, settings.fixedheader);
  3058 															table.data('ams-fixedheader', data.amsDatatableFixedheaderConstructor === undefined
  3148 																fh_settings = ams.executeFunctionByName(data.amsDatatableFixedheadeInitCallback, table, fh_settings) || fh_settings;
  3059 																						? new $.fn.dataTable.FixedHeader(table, fh_settings)
  3149 																table.data('ams-fixedheader', data.amsDatatableFixedheaderConstructor === undefined
  3060 																						: ams.executeFunctionByName(data.amsDatatableFixedheaderConstructor, table, plugin, fh_settings));
  3150 																							? new $.fn.dataTable.FixedHeader(table, fh_settings)
  3061 															break;
  3151 																							: ams.executeFunctionByName(data.amsDatatableFixedheaderConstructor, table, plugin, fh_settings));
  3062 														case 'keytable':
  3152 																break;
  3063 															var kt_default = {
  3153 															case 'keytable':
  3064 																table: table.get(0),
  3154 																var kt_default = {
  3065 																datatable: plugin
  3155 																	table: table.get(0),
  3066 															};
  3156 																	datatable: plugin
  3067 															var kt_settings = $.extend({}, kt_default, data.amsDatatableKeytableOptions, settings.keytable);
  3157 																};
  3068 															kt_settings = ams.executeFunctionByName(data.amsDatatableKeytableInitCallback, table, kt_settings) || kt_settings;
  3158 																var kt_settings = $.extend({}, kt_default, data.amsDatatableKeytableOptions, settings.keytable);
  3069 															table.data('ams-keytable', data.amsDatatableKeytableConstructor === undefined
  3159 																kt_settings = ams.executeFunctionByName(data.amsDatatableKeytableInitCallback, table, kt_settings) || kt_settings;
  3070 																						? new KeyTable(kt_settings)
  3160 																table.data('ams-keytable', data.amsDatatableKeytableConstructor === undefined
  3071 																						: ams.executeFunctionByName(data.amsDatatableKeytableConstructor, table, plugin, kt_settings));
  3161 																							? new KeyTable(kt_settings)
  3072 															break;
  3162 																							: ams.executeFunctionByName(data.amsDatatableKeytableConstructor, table, plugin, kt_settings));
  3073 														case 'rowgrouping':
  3163 																break;
  3074 															var rg_settings = $.extend({}, data.amsDatatableRowgroupingOptions, settings.rowgrouping);
  3164 															case 'rowgrouping':
  3075 															rg_settings = ams.executeFunctionByName(data.amsDatatableRowgroupingInitCallback, table, rg_settings) || rg_settings;
  3165 																var rg_settings = $.extend({}, data.amsDatatableRowgroupingOptions, settings.rowgrouping);
  3076 															table.data('ams-rowgrouping', data.amsDatatableRowgroupingConstructor === undefined
  3166 																rg_settings = ams.executeFunctionByName(data.amsDatatableRowgroupingInitCallback, table, rg_settings) || rg_settings;
  3077 																						? table.rowGrouping(rg_settings)
  3167 																table.data('ams-rowgrouping', data.amsDatatableRowgroupingConstructor === undefined
  3078 																						: ams.executeFunctionByName(data.amsDatatableRowgroupingConstructor, table, plugin, rg_settings));
  3168 																							? table.rowGrouping(rg_settings)
  3079 															break;
  3169 																							: ams.executeFunctionByName(data.amsDatatableRowgroupingConstructor, table, plugin, rg_settings));
  3080 														case 'rowreordering':
  3170 																break;
  3081 															var rr_settings = $.extend({}, data.amsDatatableRowreorderingOptions, settings.rowreordering);
  3171 															case 'rowreordering':
  3082 															rr_settings = ams.executeFunctionByName(data.amsDatatableRowreorderingInitCallback, table, rr_settings) || rr_settings;
  3172 																var rr_settings = $.extend({}, data.amsDatatableRowreorderingOptions, settings.rowreordering);
  3083 															table.data('ams-rowreordering', data.amsDatatableRowreorderingConstructor === undefined
  3173 																rr_settings = ams.executeFunctionByName(data.amsDatatableRowreorderingInitCallback, table, rr_settings) || rr_settings;
  3084 																						? table.rowReordering(rr_settings)
  3174 																table.data('ams-rowreordering', data.amsDatatableRowreorderingConstructor === undefined
  3085 																						: ams.executeFunctionByName(data.amsDatatableRowreorderingConstructor, table, plugin, rr_settings));
  3175 																							? table.rowReordering(rr_settings)
  3086 															break;
  3176 																							: ams.executeFunctionByName(data.amsDatatableRowreorderingConstructor, table, plugin, rr_settings));
  3087 														default:
  3177 																break;
  3088 															break;
  3178 															default:
       
  3179 																break;
       
  3180 														}
       
  3181 													}
       
  3182 												}
       
  3183 												var finalizers = (data.amsDatatableFinalizeCallback || '').split(/\s+/);
       
  3184 												if (finalizers.length > 0) {
       
  3185 													for (index in finalizers) {
       
  3186 														ams.executeFunctionByName(finalizers[index], table, plugin, settings);
  3089 													}
  3187 													}
  3090 												}
  3188 												}
  3091 											}
  3189 											}
  3092 											var finalizers = (data.amsDatatableFinalizeCallback || '').split(/\s+/);
  3190 											catch (e) {}
  3093 											if (finalizers.length > 0) {
       
  3094 												for (index in finalizers) {
       
  3095 													ams.executeFunctionByName(finalizers[index], table, plugin, settings);
       
  3096 												}
       
  3097 											}
       
  3098 										});
  3191 										});
  3099 								   });
  3192 								   });
  3100 				}
  3193 				}
  3101 			},
  3194 			},
  3102 
  3195 
  3159 				if (images.length > 0) {
  3252 				if (images.length > 0) {
  3160 					ams.ajax.check($.fn.imgAreaSelect,
  3253 					ams.ajax.check($.fn.imgAreaSelect,
  3161 								   ams.baseURL + 'ext/jquery-imgareaselect-0.9.10' + ams.devext + '.js',
  3254 								   ams.baseURL + 'ext/jquery-imgareaselect-0.9.10' + ams.devext + '.js',
  3162 								   function(first_load) {
  3255 								   function(first_load) {
  3163 									   if (first_load)
  3256 									   if (first_load)
  3164 										   ams.getCSS(ams.baseURL + '../css/ext/jquery-imgareaselect' + ams.devext + '.csss');
  3257 										   ams.getCSS(ams.baseURL + '../css/ext/jquery-imgareaselect' + ams.devext + '.css');
  3165 									   images.each(function() {
  3258 									   images.each(function() {
  3166 										   var image = $(this);
  3259 										   var image = $(this);
  3167 										   var data = image.data();
  3260 										   var data = image.data();
  3168 										   var parent = data.amsImgareaselectParent ? image.parents(data.amsImgareaselectParent) : 'body';
  3261 										   var parent = data.amsImgareaselectParent ? image.parents(data.amsImgareaselectParent) : 'body';
  3169 										   var data_options = {
  3262 										   var data_options = {
  3976 			} else {
  4069 			} else {
  3977 				ams.skin._showShortcutButtons();
  4070 				ams.skin._showShortcutButtons();
  3978 			}
  4071 			}
  3979 			e.preventDefault();
  4072 			e.preventDefault();
  3980 		});
  4073 		});
       
  4074 		ams.shortcuts.click(function(e) {
       
  4075 			ams.skin._hideShortcutButtons();
       
  4076 		});
  3981 
  4077 
  3982 		$(document).mouseup(function(e) {
  4078 		$(document).mouseup(function(e) {
  3983 			if (!ams.shortcuts.is(e.target)
  4079 			if (!ams.shortcuts.is(e.target)
  3984 				&& ams.shortcuts.has(e.target).length === 0) {
  4080 				&& ams.shortcuts.has(e.target).length === 0) {
  3985 				ams.skin._hideShortcutButtons();
  4081 				ams.skin._hideShortcutButtons();
  4121 					href = href.replace(/\%23/, '#');
  4217 					href = href.replace(/\%23/, '#');
  4122 					var target = link.data('ams-target');
  4218 					var target = link.data('ams-target');
  4123 					if (target) {
  4219 					if (target) {
  4124 						ams.form.confirmChangedForm(target, function () {
  4220 						ams.form.confirmChangedForm(target, function () {
  4125 							ams.skin.loadURL(href, target, link.data('ams-link-options'), link.data('ams-link-callback'));
  4221 							ams.skin.loadURL(href, target, link.data('ams-link-options'), link.data('ams-link-callback'));
  4126 							e.stopPropagation();
       
  4127 						});
  4222 						});
  4128 					} else {
  4223 					} else {
  4129 						ams.form.confirmChangedForm(function () {
  4224 						ams.form.confirmChangedForm(function () {
  4130 							if (href.startsWith('#')) {
  4225 							if (href.startsWith('#')) {
  4131 								if (href != location.hash) {
  4226 								if (href != location.hash) {
  4132 									if (ams.root.hasClass('mobile-view-activated')) {
  4227 									if (ams.root.hasClass('mobile-view-activated')) {
  4133 										ams.root.removeClass('hidden-menu');
  4228 										ams.root.removeClass('hidden-menu');
  4134 										window.setTimeout(function () {
  4229 										window.setTimeout(function () {
  4135 											window.location.hash = href;
  4230 											window.location.hash = href;
  4136 										}, 150);
  4231 										}, 50);
  4137 									} else
  4232 									} else
  4138 										window.location.hash = href;
  4233 										window.location.hash = href;
  4139 								}
  4234 								}
  4140 							} else
  4235 							} else
  4141 								window.location = href;
  4236 								window.location = href;
  4204 				if (callback !== undefined)
  4299 				if (callback !== undefined)
  4205 					callback.call(source, data.amsChangeHandlerOptions);
  4300 					callback.call(source, data.amsChangeHandlerOptions);
  4206 			}
  4301 			}
  4207 		});
  4302 		});
  4208 
  4303 
       
  4304 		// Notify reset to update Select2 widgets
       
  4305 		$(document).on('reset', 'form', function(e) {
       
  4306 			var form = $(this);
       
  4307 			setTimeout(function() {
       
  4308 				form.find('.select2').trigger('change');
       
  4309 			}, 10);
       
  4310 		});
       
  4311 
  4209 		// Initialize custom reset handlers
  4312 		// Initialize custom reset handlers
  4210 		$(document).on('reset', '[data-ams-reset-handler]', function(e) {
  4313 		$(document).on('reset', '[data-ams-reset-handler]', function(e) {
  4211 			var form = $(this);
  4314 			var form = $(this);
  4212 			var data = form.data();
  4315 			var data = form.data();
  4213 			if (data.amsResetHandler) {
  4316 			if (data.amsResetHandler) {
  4249 			var link = $(e.target);
  4352 			var link = $(e.target);
  4250 			var data = link.data();
  4353 			var data = link.data();
  4251 			if (data.amsUrl) {
  4354 			if (data.amsUrl) {
  4252 				if (data.amsTabLoaded)
  4355 				if (data.amsTabLoaded)
  4253 					return;
  4356 					return;
  4254 				ams.skin.loadURL(data.amsUrl, link.attr('href'));
  4357 				try {
  4255 				if (data.amsTabLoadOnce)
  4358 					link.append('<i class="fa fa-spin fa-cog margin-left-5"></i>');
  4256 					link.data('ams-tab-loaded', true);
  4359 					ams.skin.loadURL(data.amsUrl, link.attr('href'));
       
  4360 					if (data.amsTabLoadOnce)
       
  4361 						link.data('ams-tab-loaded', true);
       
  4362 				}
       
  4363 				finally {
       
  4364 					$('i', link).remove();
       
  4365 				}
  4257 			}
  4366 			}
  4258 		});
  4367 		});
  4259 
  4368 
  4260 		// Init page content
  4369 		// Init page content
  4261 		ams.initContent(document);
  4370 		ams.initContent(document);
  4262 		if (ams.ajax_nav && ($('nav').length > 0))
  4371 		if (ams.ajax_nav && $('nav').exists())
  4263 			ams.skin.checkURL();
  4372 			ams.skin.checkURL();
  4264 
  4373 
  4265 		// Add unload event listener to check for modified forms
  4374 		// Add unload event listener to check for modified forms
  4266 		$(window).on('beforeunload', ams.form.checkBeforeUnload);
  4375 		$(window).on('beforeunload', ams.form.checkBeforeUnload);
  4267 
  4376 
  4332 		BTN_CANCEL: "Cancel",
  4441 		BTN_CANCEL: "Cancel",
  4333 		BTN_OK_CANCEL: "[OK][Cancel]",
  4442 		BTN_OK_CANCEL: "[OK][Cancel]",
  4334 		BTN_YES: "Yes",
  4443 		BTN_YES: "Yes",
  4335 		BTN_NO: "No",
  4444 		BTN_NO: "No",
  4336 		BTN_YES_NO: "[Yes][No]",
  4445 		BTN_YES_NO: "[Yes][No]",
       
  4446 
       
  4447 		CLIPBOARD_COPY: "Copy to clipboard with Ctrl+C, and Enter",
  4337 
  4448 
  4338 		FORM_CHANGED_WARNING: "Some changes were not saved. These updates will be lost if you leave this page.",
  4449 		FORM_CHANGED_WARNING: "Some changes were not saved. These updates will be lost if you leave this page.",
  4339 		DELETE_WARNING: "This change can't be undone. Are you sure that you want to delete this element?",
  4450 		DELETE_WARNING: "This change can't be undone. Are you sure that you want to delete this element?",
  4340 		NO_UPDATE: "No changes were applied.",
  4451 		NO_UPDATE: "No changes were applied.",
  4341 		DATA_UPDATED: "Data successfully updated.",
  4452 		DATA_UPDATED: "Data successfully updated.",