440 var defaults = { |
440 var defaults = { |
441 dataType: 'script', |
441 dataType: 'script', |
442 url: ams.getSource(url), |
442 url: ams.getSource(url), |
443 success: callback, |
443 success: callback, |
444 error: ams.error.show, |
444 error: ams.error.show, |
445 cache: true, |
445 cache: !ams.devmode, |
446 async: true |
446 async: typeof(callback) == 'function' |
447 }; |
447 }; |
448 var settings = $.extend({}, defaults, options); |
448 var settings = $.extend({}, defaults, options); |
449 return $.ajax(settings); |
449 return $.ajax(settings); |
450 }; |
450 }; |
451 |
451 |
452 MyAMS.getCSS = function(url, id) { |
452 MyAMS.getCSS = function(url, id) { |
453 var head = $('HEAD'); |
453 var head = $('HEAD'); |
454 var css = $('link[data-ams-id="' + id + '"]', head); |
454 var css = $('link[data-ams-id="' + id + '"]', head); |
455 if (css.length == 0) { |
455 if (css.length == 0) { |
|
456 var source = ams.getSource(url); |
|
457 if (ams.devmode) |
|
458 source += '?_=' + new Date().getTime(); |
456 $('<link />').attr({rel: 'stylesheet', |
459 $('<link />').attr({rel: 'stylesheet', |
457 type: 'text/css', |
460 type: 'text/css', |
458 href: ams.getSource(url), |
461 href: source, |
459 'data-ams-id': id}) |
462 'data-ams-id': id}) |
460 .appendTo(head); |
463 .appendTo(head); |
461 } |
464 } |
462 }; |
465 }; |
463 |
466 |
946 /** |
949 /** |
947 * Execute given JSON-RPC post on given method |
950 * Execute given JSON-RPC post on given method |
948 * |
951 * |
949 * Parameters: |
952 * Parameters: |
950 * - @method: name of JSON-RPC procedure to call |
953 * - @method: name of JSON-RPC procedure to call |
951 * - @options: additional JSON-RPC procedure parameters |
954 * - @options: additional JSON-RPC method call parameters |
952 * - @callback: name of a callback which will be called on server response |
955 * - @callback: name of a callback which will be called on server response |
953 */ |
956 */ |
954 post: function(method, data, options, callback) { |
957 post: function(method, data, options, callback) { |
955 ams.ajax.check($.jsonRpc, |
958 ams.ajax.check($.jsonRpc, |
956 ams.baseURL + 'ext/jquery-jsonrpc' + (ams.devmode ? '.js' : '.min.js'), |
959 ams.baseURL + 'ext/jquery-jsonrpc' + (ams.devmode ? '.js' : '.min.js'), |
980 }, |
983 }, |
981 error: ams.error.show |
984 error: ams.error.show |
982 }; |
985 }; |
983 var settings = $.extend({}, defaults, options); |
986 var settings = $.extend({}, defaults, options); |
984 $.jsonRpc(settings); |
987 $.jsonRpc(settings); |
|
988 return result; |
|
989 }); |
|
990 } |
|
991 }; |
|
992 |
|
993 |
|
994 /** |
|
995 * XML-RPC helper functions |
|
996 */ |
|
997 MyAMS.xmlrpc = { |
|
998 |
|
999 /** |
|
1000 * Get address relative to current page |
|
1001 */ |
|
1002 getAddr: function(addr) { |
|
1003 var href = addr || $('HTML HEAD BASE').attr('href') || window.location.href; |
|
1004 var target = href.replace(/\+\+skin\+\+\w+\//, ''); |
|
1005 return target.substr(0, target.lastIndexOf("/") + 1); |
|
1006 }, |
|
1007 |
|
1008 /** |
|
1009 * Execute given XML-RPC post on given method |
|
1010 * |
|
1011 * Parameters: |
|
1012 * - @url: base method URL |
|
1013 * - @method: name of JSON-RPC procedure to call |
|
1014 * - @options: additional JSON-RPC procedure parameters |
|
1015 * - @callback: name of a callback which will be called on server response |
|
1016 */ |
|
1017 post: function(url, method, data, options, callback) { |
|
1018 ams.ajax.check($.xmlrpc, |
|
1019 ams.baseURL + 'ext/jquery-xmlrpc' + (ams.devmode ? '.js' : '.min.js'), |
|
1020 function() { |
|
1021 var result; |
|
1022 if (typeof(options) == 'function') { |
|
1023 callback = options; |
|
1024 options = {}; |
|
1025 } |
|
1026 else if (!options) |
|
1027 options = {}; |
|
1028 if (typeof(callback) == 'undefined') |
|
1029 callback = options.callback; |
|
1030 if (typeof(callback) == 'string') |
|
1031 callback = ams.getFunctionByName(callback); |
|
1032 delete options.callback; |
|
1033 |
|
1034 var defaults = { |
|
1035 url: ams.xmlrpc.getAddr(url), |
|
1036 methodName: method, |
|
1037 params: data, |
|
1038 success: callback || function(response /*, status, xhr*/) { |
|
1039 result = response; |
|
1040 }, |
|
1041 error: ams.error.show |
|
1042 }; |
|
1043 var settings = $.extend({}, defaults, options); |
|
1044 $.xmlrpc(settings); |
985 return result; |
1045 return result; |
986 }); |
1046 }); |
987 } |
1047 } |
988 }; |
1048 }; |
989 |
1049 |
1183 ams.form.finalizeSubmitFooter.call(form); |
1243 ams.form.finalizeSubmitFooter.call(form); |
1184 } |
1244 } |
1185 form.data('submitted', false); |
1245 form.data('submitted', false); |
1186 form.removeData('ams-submit-button'); |
1246 form.removeData('ams-submit-button'); |
1187 }, |
1247 }, |
1188 success: function(result, status, request, form) { |
1248 iframe: hasUpload |
1189 var callback; |
1249 } |
1190 var button = form.data('ams-submit-button'); |
1250 var download_target = data.amsFormDownloadTarget; |
|
1251 if (download_target) { |
|
1252 var iframe = $('iframe[name="' + download_target + '"]'); |
|
1253 if (!iframe.exists()) |
|
1254 iframe = $('<iframe></iframe>').hide() |
|
1255 .attr('name', download_target) |
|
1256 .appendTo(form); |
|
1257 defaults = $.extend({}, defaults, { |
|
1258 iframe: true, |
|
1259 iframeTarget: iframe, |
|
1260 success: function(result, status, request, form) { |
|
1261 var modal = $(form).parents('.modal-dialog'); |
|
1262 if (modal.exists()) { |
|
1263 ams.dialog.close(form); |
|
1264 } else { |
|
1265 var callback; |
|
1266 var button = form.data('ams-submit-button'); |
|
1267 if (button) |
|
1268 callback = button.data('ams-form-submit-callback'); |
|
1269 if (!callback) |
|
1270 callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback; |
|
1271 callback.call(form, result, status, request, form); |
|
1272 if (form.is(':visible') && button) |
|
1273 button.button('reset'); |
|
1274 form.data('submitted', false); |
|
1275 form.removeData('ams-submit-button'); |
|
1276 form.removeAttr('data-ams-form-changed'); |
|
1277 } |
|
1278 } |
|
1279 }); |
|
1280 } else { |
|
1281 defaults = $.extend({}, defaults, { |
|
1282 error: function(request, status, error, form) { |
|
1283 if (target) |
|
1284 ams.executeFunctionByName(data.amsFormSubmitError || 'MyAMS.form.finalizeSubmitOnError', form, target); |
|
1285 if (form.is(':visible')) { |
|
1286 var button = form.data('ams-submit-button'); |
|
1287 if (button) |
|
1288 button.button('reset'); |
|
1289 ams.form.finalizeSubmitFooter.call(form); |
|
1290 } |
|
1291 form.data('submitted', false); |
|
1292 form.removeData('ams-submit-button'); |
|
1293 }, |
|
1294 success: function(result, status, request, form) { |
|
1295 var callback; |
|
1296 var button = form.data('ams-submit-button'); |
|
1297 if (button) |
|
1298 callback = button.data('ams-form-submit-callback'); |
|
1299 if (!callback) |
|
1300 callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback; |
|
1301 callback.call(form, result, status, request, form); |
|
1302 if (form.is(':visible') && button) |
|
1303 button.button('reset'); |
|
1304 form.data('submitted', false); |
|
1305 form.removeData('ams-submit-button'); |
|
1306 form.removeAttr('data-ams-form-changed'); |
|
1307 }, |
|
1308 iframe: hasUpload |
|
1309 }); |
|
1310 } |
|
1311 var settings = $.extend({}, defaults, options, form_options, submit_options); |
|
1312 $(form).ajaxSubmit(settings); |
|
1313 |
|
1314 if (download_target) { |
|
1315 var modal = $(form).parents('.modal-dialog'); |
|
1316 if (modal.exists()) { |
|
1317 ams.dialog.close(form); |
|
1318 } else { |
|
1319 ams.form.finalizeSubmitFooter.call(form); |
1191 if (button) |
1320 if (button) |
1192 callback = button.data('ams-form-submit-callback'); |
|
1193 if (!callback) |
|
1194 callback = ams.getFunctionByName(data.amsFormSubmitCallback) || ams.form._submitCallback; |
|
1195 callback.call(form, result, status, request, form); |
|
1196 if (form.is(':visible') && button) |
|
1197 button.button('reset'); |
1321 button.button('reset'); |
1198 form.data('submitted', false); |
1322 form.data('submitted', false); |
1199 form.removeData('ams-submit-button'); |
1323 form.removeData('ams-submit-button'); |
1200 form.removeAttr('data-ams-form-changed'); |
1324 form.removeAttr('data-ams-form-changed'); |
1201 }, |
1325 } |
1202 iframe: hasUpload |
|
1203 } |
1326 } |
1204 var settings = $.extend({}, defaults, options, form_options, submit_options); |
|
1205 $(form).ajaxSubmit(settings); |
|
1206 } |
1327 } |
1207 |
1328 |
1208 var hasUpload = $('INPUT[type="file"]', form).length > 0; |
1329 var hasUpload = $('INPUT[type="file"]', form).length > 0; |
1209 if (hasUpload) { |
1330 if (hasUpload) { |
1210 // JQuery-progressbar plug-in must be loaded synchronously!! |
1331 // JQuery-progressbar plug-in must be loaded synchronously!! |
1809 } |
1963 } |
1810 }); |
1964 }); |
1811 }, |
1965 }, |
1812 |
1966 |
1813 /** |
1967 /** |
|
1968 * Register a new plug-in through Javascript instead of HTML data attributes |
|
1969 * |
|
1970 * @plugin: plugin function caller or object containing plug-in properties |
|
1971 * @name: if @plugin is a function, defines plug-in name |
|
1972 * @callback: a callback function which can be called after plug-in registry |
|
1973 */ |
|
1974 register: function(plugin, name, callback) { |
|
1975 if (typeof(name) == 'function') { |
|
1976 callback = name; |
|
1977 name = null; |
|
1978 } |
|
1979 name = name || plugin.name; |
|
1980 if (ams.plugins.enabled.indexOf(name) >= 0) { |
|
1981 if (window.console) |
|
1982 console.warn("Plugin "+name+" is already registered!"); |
|
1983 return; |
|
1984 } |
|
1985 if (typeof(plugin) == 'object') { |
|
1986 var src = plugin.src; |
|
1987 if (src) { |
|
1988 ams.ajax.check(plugin.callback, src, function(first_load) { |
|
1989 if (first_load) { |
|
1990 ams.plugins.enabled[name] = ams.getFunctionByName(plugin.callback); |
|
1991 if (plugin.css) { |
|
1992 ams.getCSS(plugin.css, name + '_css'); |
|
1993 } |
|
1994 if (callback) { |
|
1995 ams.executeFunctionByName(callback); |
|
1996 } |
|
1997 } |
|
1998 }) |
|
1999 } else { |
|
2000 ams.plugins.enabled[name] = ams.getFunctionByName(plugin.callback); |
|
2001 if (plugin.css) { |
|
2002 ams.getCSS(plugin.css, name + '_css'); |
|
2003 } |
|
2004 if (callback) { |
|
2005 ams.executeFunctionByName(callback); |
|
2006 } |
|
2007 } |
|
2008 } else if (typeof(plugin) == 'function') { |
|
2009 ams.plugins.enabled[name] = plugin; |
|
2010 if (callback) { |
|
2011 ams.executeFunctionByName(callback); |
|
2012 } |
|
2013 } |
|
2014 }, |
|
2015 |
|
2016 /** |
1814 * Map of enabled plug-ins |
2017 * Map of enabled plug-ins |
1815 * This map can be extended by external plug-ins. |
2018 * This map can be extended by external plug-ins. |
1816 * |
2019 * |
1817 * Standard MyAMS plug-ins management method generally includes: |
2020 * Standard MyAMS plug-ins management method generally includes: |
1818 * - applying a class matching plug-in name on a set of HTML entities to apply the plug-in |
2021 * - applying a class matching plug-in name on a set of HTML entities to apply the plug-in |
1819 * - defining a set of data-attributes on each of these entities to customize the plug-in |
2022 * - defining a set of data-attributes on each of these entities to customize the plug-in |
1820 * For each standard plug-in, you can also provide an options object (to define plug-in options not handled |
2023 * For each standard plug-in, you can also provide an options object (to define plug-in options not handled |
1821 * by default MyAMS initialization engine) and an initialization callback (to define these options dynamically). |
2024 * by default MyAMS initialization engine) and an initialization callback (to define these options dynamically). |
1822 * Another callback can also be provided to be called after plug-in initialization. |
2025 * Another callback can also be provided to be called after plug-in initialization. |
|
2026 * |
|
2027 * You can also register plug-ins using the 'register' function |
1823 */ |
2028 */ |
1824 enabled: { |
2029 enabled: { |
1825 |
2030 |
1826 /** |
2031 /** |
1827 * Label hints |
2032 * Label hints |
2235 ams.ajax.check($.fn.datetimepicker, |
2440 ams.ajax.check($.fn.datetimepicker, |
2236 ams.baseURL + 'ext/jquery-datetimepicker' + (ams.devmode ? '.js': '.min.js'), |
2441 ams.baseURL + 'ext/jquery-datetimepicker' + (ams.devmode ? '.js': '.min.js'), |
2237 function(first_load) { |
2442 function(first_load) { |
2238 if (first_load) { |
2443 if (first_load) { |
2239 ams.getCSS(ams.baseURL + '../css/ext/jquery-datetimepicker' + (ams.devmode ? '.css' : '.min.css'), 'jquery-datetimepicker'); |
2444 ams.getCSS(ams.baseURL + '../css/ext/jquery-datetimepicker' + (ams.devmode ? '.css' : '.min.css'), 'jquery-datetimepicker'); |
|
2445 ams.dialog.registerHideCallback(ams.helpers.datetimepickerDialogHiddenCallback); |
2240 } |
2446 } |
2241 datepickers.each(function() { |
2447 datepickers.each(function() { |
2242 var input = $(this); |
2448 var input = $(this); |
2243 var data = input.data(); |
2449 var data = input.data(); |
2244 var data_options = { |
2450 var data_options = { |
2266 ams.ajax.check($.fn.datetimepicker, |
2472 ams.ajax.check($.fn.datetimepicker, |
2267 ams.baseURL + 'ext/jquery-datetimepicker' + (ams.devmode ? '.js': '.min.js'), |
2473 ams.baseURL + 'ext/jquery-datetimepicker' + (ams.devmode ? '.js': '.min.js'), |
2268 function(first_load) { |
2474 function(first_load) { |
2269 if (first_load) { |
2475 if (first_load) { |
2270 ams.getCSS(ams.baseURL + '../css/ext/jquery-datetimepicker' + (ams.devmode ? '.css' : '.min.css'), 'jquery-datetimepicker'); |
2476 ams.getCSS(ams.baseURL + '../css/ext/jquery-datetimepicker' + (ams.devmode ? '.css' : '.min.css'), 'jquery-datetimepicker'); |
|
2477 ams.dialog.registerHideCallback(ams.helpers.datetimepickerDialogHiddenCallback); |
2271 } |
2478 } |
2272 datetimepickers.each(function() { |
2479 datetimepickers.each(function() { |
2273 var input = $(this); |
2480 var input = $(this); |
2274 var data = input.data(); |
2481 var data = input.data(); |
2275 var data_options = { |
2482 var data_options = { |
2297 ams.ajax.check($.fn.datetimepicker, |
2504 ams.ajax.check($.fn.datetimepicker, |
2298 ams.baseURL + 'ext/jquery-datetimepicker' + (ams.devmode ? '.js': '.min.js'), |
2505 ams.baseURL + 'ext/jquery-datetimepicker' + (ams.devmode ? '.js': '.min.js'), |
2299 function(first_load) { |
2506 function(first_load) { |
2300 if (first_load) { |
2507 if (first_load) { |
2301 ams.getCSS(ams.baseURL + '../css/ext/jquery-datetimepicker' + (ams.devmode ? '.css' : '.min.css'), 'jquery-datetimepicker'); |
2508 ams.getCSS(ams.baseURL + '../css/ext/jquery-datetimepicker' + (ams.devmode ? '.css' : '.min.css'), 'jquery-datetimepicker'); |
|
2509 ams.dialog.registerHideCallback(ams.helpers.datetimepickerDialogHiddenCallback); |
2302 } |
2510 } |
2303 timepickers.each(function() { |
2511 timepickers.each(function() { |
2304 var input = $(this); |
2512 var input = $(this); |
2305 var data = input.data(); |
2513 var data = input.data(); |
2306 var data_options = { |
2514 var data_options = { |
2310 timepicker: true |
2518 timepicker: true |
2311 }; |
2519 }; |
2312 var settings = $.extend({}, data_options, data.amsDatetimepickerOptions); |
2520 var settings = $.extend({}, data_options, data.amsDatetimepickerOptions); |
2313 settings = ams.executeFunctionByName(data.amsDatetimepickerInitCallback, input, settings) || settings; |
2521 settings = ams.executeFunctionByName(data.amsDatetimepickerInitCallback, input, settings) || settings; |
2314 var plugin = input.datetimepicker(settings); |
2522 var plugin = input.datetimepicker(settings); |
|
2523 ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings); |
|
2524 }); |
|
2525 }); |
|
2526 } |
|
2527 }, |
|
2528 |
|
2529 /** |
|
2530 * JQuery color picker |
|
2531 */ |
|
2532 colorpicker: function(element) { |
|
2533 var colorpickers = $('.colorpicker', element); |
|
2534 if (colorpickers.length > 0) { |
|
2535 ams.ajax.check($.fn.minicolors, |
|
2536 ams.baseURL + 'ext/jquery-minicolors' + (ams.devmode ? '.js' : '.min.js'), |
|
2537 function(first_load) { |
|
2538 if (first_load) { |
|
2539 ams.getCSS(ams.baseURL + '../css/ext/jquery-minicolors' + (ams.devmode ? '.css' : '.min.css'), 'jquery-minicolors'); |
|
2540 } |
|
2541 colorpickers.each(function() { |
|
2542 var input = $(this); |
|
2543 var data = input.data(); |
|
2544 var data_options = { |
|
2545 position: data.amsColorpickerPosition || input.closest('label.input').data('ams-colorpicker-position') || 'bottom left' |
|
2546 }; |
|
2547 var settings = $.extend({}, data_options, data.amsColorpickerOptions); |
|
2548 settings = ams.executeFunctionByName(data.amsColorpickerInitCallback, input, settings) || settings; |
|
2549 var plugin = input.minicolors(settings); |
2315 ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings); |
2550 ams.executeFunctionByName(data.amsDatetimepickerAfterInitCallback, input, plugin, settings); |
2316 }); |
2551 }); |
2317 }); |
2552 }); |
2318 } |
2553 } |
2319 }, |
2554 }, |
3013 */ |
3248 */ |
3014 deleteElement: function(element) { |
3249 deleteElement: function(element) { |
3015 return function() { |
3250 return function() { |
3016 var link = $(this); |
3251 var link = $(this); |
3017 MyAMS.skin.bigBox({ |
3252 MyAMS.skin.bigBox({ |
3018 title: MyAMS.i18n.WARNING, |
3253 title: ams.i18n.WARNING, |
3019 content: '<i class="text-danger fa fa-2x fa-bell shake animated"></i> ' + MyAMS.i18n.DELETE_WARNING, |
3254 content: '<i class="text-danger fa fa-2x fa-bell shake animated"></i> ' + ams.i18n.DELETE_WARNING, |
3020 buttons: MyAMS.i18n.BTN_OK_CANCEL |
3255 buttons: ams.i18n.BTN_OK_CANCEL |
3021 }, function(button) { |
3256 }, function(button) { |
3022 if (button == MyAMS.i18n.BTN_OK) { |
3257 if (button == ams.i18n.BTN_OK) { |
3023 var table = link.parents('table'); |
3258 var table = link.parents('table'); |
3024 var location = table.data('ams-location'); |
3259 var location = table.data('ams-location') || ''; |
3025 var tr = link.parents('tr'); |
3260 var tr = link.parents('tr'); |
3026 var delete_target = tr.data('ams-delete-target') || table.data('ams-delete-target') || 'delete-element.json'; |
3261 var delete_target = tr.data('ams-delete-target') || table.data('ams-delete-target') || 'delete-element.json'; |
3027 var object_name = tr.data('ams-element-name'); |
3262 var object_name = tr.data('ams-element-name'); |
3028 MyAMS.ajax.post(location + '/' + delete_target, {'object_name': object_name}, function(result, status) { |
3263 MyAMS.ajax.post(location + '/' + delete_target, {'object_name': object_name}, function(result, status) { |
3029 if (result.status == 'success') { |
3264 if (result.status == 'success') { |
3670 e.preventDefault(); |
3905 e.preventDefault(); |
3671 ams.dialog.open(source); |
3906 ams.dialog.open(source); |
3672 if (source.parents('#shortcut').exists()) |
3907 if (source.parents('#shortcut').exists()) |
3673 setTimeout(ams.skin._hideShortcutButtons, 300); |
3908 setTimeout(ams.skin._hideShortcutButtons, 300); |
3674 }); |
3909 }); |
3675 $(document).on('shown.bs.modal', ams.dialog.shown); |
|
3676 |
3910 |
3677 // Initialize form buttons |
3911 // Initialize form buttons |
3678 $(document).on('click', 'button[type="submit"], button.submit', function() { |
3912 $(document).on('click', 'button[type="submit"], button.submit', function() { |
3679 var button = $(this); |
3913 var button = $(this); |
3680 $(button.get(0).form).data('ams-submit-button', button); |
3914 $(button.get(0).form).data('ams-submit-button', button); |