api.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. $(document).ready(function() {
  2. function is_active(elem) {
  3. if ($(elem).data('submitted') == '1') {
  4. return true;
  5. } else {
  6. $(elem).text(loading_text);
  7. $(elem).attr('data-submitted', '1');
  8. function disableF5(e) { if ((e.which || e.keyCode) == 116 || (e.which || e.keyCode) == 82) e.preventDefault(); };
  9. $(document).on("keydown", disableF5);
  10. return false;
  11. }
  12. }
  13. $.fn.serializeObject = function() {
  14. var o = {};
  15. var a = this.serializeArray();
  16. $.each(a, function() {
  17. if (o[this.name]) {
  18. if (!o[this.name].push) {
  19. o[this.name] = [o[this.name]];
  20. }
  21. o[this.name].push(this.value || '');
  22. } else {
  23. o[this.name] = this.value || '';
  24. }
  25. });
  26. return o;
  27. };
  28. // Collect values of input fields with name "multi_select" and same data-id to js array multi_data[data-id]
  29. var multi_data = [];
  30. $(document).on('change', 'input[name=multi_select]:checkbox', function() {
  31. if ($(this).is(':checked') && $(this).data('id')) {
  32. var id = $(this).data('id');
  33. if (typeof multi_data[id] == "undefined") {
  34. multi_data[id] = [];
  35. }
  36. multi_data[id].push($(this).val());
  37. }
  38. else {
  39. var id = $(this).data('id');
  40. multi_data[id].splice($.inArray($(this).val(), multi_data[id]),1);
  41. }
  42. });
  43. // Select checkbox by click on parent tr
  44. $(document).on('click', 'tbody>tr', function(e) {
  45. if(e.target.tagName.toLowerCase() === 'button') {
  46. e.stopPropagation();
  47. }
  48. else if(e.target.tagName.toLowerCase() === 'a') {
  49. e.stopPropagation();
  50. }
  51. else if (e.target.type == "checkbox") {
  52. e.stopPropagation();
  53. }
  54. else {
  55. var checkbox = $(this).find(':checkbox');
  56. checkbox.trigger('click');
  57. }
  58. });
  59. // Select or deselect all checkboxes with same data-id
  60. $(document).on('click', '#toggle_multi_select_all', function(e) {
  61. e.preventDefault();
  62. id = $(this).data("id");
  63. var all_checkboxes = $("input[data-id=" + id + "]:enabled");
  64. all_checkboxes.prop("checked", !all_checkboxes.prop("checked")).change();
  65. });
  66. // General API edit actions
  67. $(document).on('click', '#edit_selected', function(e) {
  68. e.preventDefault();
  69. var id = $(this).data('id');
  70. var api_url = $(this).data('api-url');
  71. var api_attr = $(this).data('api-attr');
  72. if (typeof $(this).data('api-reload-window') !== 'undefined') {
  73. api_reload_window = $(this).data('api-reload-window');
  74. } else {
  75. api_reload_window = true;
  76. }
  77. // If clicked element #edit_selected is in a form with the same data-id as the button,
  78. // we merge all input fields by {"name":"value"} into api-attr
  79. if ($(this).closest("form").data('id') == id) {
  80. var req_empty = false;
  81. $(this).closest("form").find('select, textarea, input').each(function() {
  82. if ($(this).prop('required')) {
  83. if (!$(this).val() && $(this).prop('disabled') === false) {
  84. req_empty = true;
  85. $(this).addClass('inputMissingAttr');
  86. } else {
  87. $(this).removeClass('inputMissingAttr');
  88. }
  89. }
  90. if ($(this).attr("max")) {
  91. if (Number($(this).val()) > Number($(this).attr("max"))) {
  92. invalid = true;
  93. $(this).addClass('inputMissingAttr');
  94. } else {
  95. if ($(this).attr("min")) {
  96. if (Number($(this).val()) < Number($(this).attr("min"))) {
  97. invalid = true;
  98. $(this).addClass('inputMissingAttr');
  99. } else {
  100. $(this).removeClass('inputMissingAttr');
  101. }
  102. }
  103. }
  104. }
  105. });
  106. if (!req_empty) {
  107. var attr_to_merge = $(this).closest("form").serializeObject();
  108. var api_attr = $.extend(api_attr, attr_to_merge)
  109. } else {
  110. return false;
  111. }
  112. }
  113. // alert(JSON.stringify(api_attr));
  114. // If clicked element #edit_selected has data-item attribute, it is added to "items"
  115. if (typeof $(this).data('item') !== 'undefined') {
  116. var id = $(this).data('id');
  117. if (typeof multi_data[id] == "undefined") {
  118. multi_data[id] = [];
  119. }
  120. multi_data[id].splice($.inArray($(this).data('item'), multi_data[id]), 1);
  121. multi_data[id].push($(this).data('item'));
  122. }
  123. if (typeof multi_data[id] == "undefined") return;
  124. api_items = multi_data[id];
  125. for (var i in api_items) {
  126. api_items[i] = decodeURIComponent(api_items[i]);
  127. }
  128. // alert(JSON.stringify(api_attr));
  129. if (Object.keys(api_items).length !== 0) {
  130. if (is_active($(this))) { return false; }
  131. $.ajax({
  132. type: "POST",
  133. dataType: "json",
  134. data: {
  135. "items": JSON.stringify(api_items),
  136. "attr": JSON.stringify(api_attr),
  137. "csrf_token": csrf_token
  138. },
  139. url: '/api/v1/' + api_url,
  140. jsonp: false,
  141. complete: function(data) {
  142. var response = (data.responseText);
  143. if (typeof response !== 'undefined' && response.length !== 0) {
  144. response_obj = JSON.parse(response);
  145. }
  146. if (api_reload_window === true) {
  147. window.location = window.location.href.split("#")[0];
  148. }
  149. }
  150. });
  151. }
  152. });
  153. // General API add actions
  154. $(document).on('click', '#add_item', function(e) {
  155. e.preventDefault();
  156. var id = $(this).data('id');
  157. var api_url = $(this).data('api-url');
  158. var api_attr = $(this).data('api-attr');
  159. if (typeof $(this).data('api-reload-window') !== 'undefined') {
  160. api_reload_window = $(this).data('api-reload-window');
  161. } else {
  162. api_reload_window = true;
  163. }
  164. // If clicked button is in a form with the same data-id as the button,
  165. // we merge all input fields by {"name":"value"} into api-attr
  166. if ($(this).closest("form").data('id') == id) {
  167. var invalid = false;
  168. $(this).closest("form").find('select, textarea, input').each(function() {
  169. if ($(this).prop('required')) {
  170. if (!$(this).val() && $(this).prop('disabled') === false) {
  171. invalid = true;
  172. $(this).addClass('inputMissingAttr');
  173. } else {
  174. $(this).removeClass('inputMissingAttr');
  175. }
  176. }
  177. if ($(this).attr("max")) {
  178. if (Number($(this).val()) > Number($(this).attr("max"))) {
  179. alert($(this).attr("max"))
  180. invalid = true;
  181. $(this).addClass('inputMissingAttr');
  182. } else {
  183. if ($(this).attr("min")) {
  184. if (Number($(this).val()) < Number($(this).attr("min"))) {
  185. invalid = true;
  186. $(this).addClass('inputMissingAttr');
  187. } else {
  188. $(this).removeClass('inputMissingAttr');
  189. }
  190. }
  191. }
  192. }
  193. });
  194. if (!invalid) {
  195. var attr_to_merge = $(this).closest("form").serializeObject();
  196. var api_attr = $.extend(api_attr, attr_to_merge)
  197. } else {
  198. return false;
  199. }
  200. }
  201. if (is_active($(this))) { return false; }
  202. // alert(JSON.stringify(api_attr));
  203. $.ajax({
  204. type: "POST",
  205. dataType: "json",
  206. data: {
  207. "attr": JSON.stringify(api_attr),
  208. "csrf_token": csrf_token
  209. },
  210. url: '/api/v1/' + api_url,
  211. jsonp: false,
  212. complete: function(data) {
  213. var response = (data.responseText);
  214. if (typeof response !== 'undefined' && response.length !== 0) {
  215. response_obj = JSON.parse(response);
  216. if (response_obj.type == 'success') {
  217. $('form').formcache('clear');
  218. }
  219. else {
  220. var add_modal = $('.modal.in').attr('id');
  221. localStorage.setItem("add_modal", add_modal);
  222. }
  223. }
  224. if (api_reload_window === true) {
  225. window.location = window.location.href.split("#")[0];
  226. }
  227. }
  228. });
  229. });
  230. // General API delete actions
  231. $(document).on('click', '#delete_selected', function(e) {
  232. e.preventDefault();
  233. var id = $(this).data('id');
  234. // If clicked element #delete_selected has data-item attribute, it is added to "items"
  235. if (typeof $(this).data('item') !== 'undefined') {
  236. var id = $(this).data('id');
  237. if (typeof multi_data[id] == "undefined") {
  238. multi_data[id] = [];
  239. }
  240. multi_data[id].splice($.inArray($(this).data('item'), multi_data[id]), 1);
  241. multi_data[id].push($(this).data('item'));
  242. }
  243. if (typeof $(this).data('text') !== 'undefined') {
  244. $("#DeleteText").empty();
  245. $("#DeleteText").text($(this).data('text'));
  246. }
  247. if (typeof multi_data[id] == "undefined" || multi_data[id] == "") return;
  248. data_array = multi_data[id];
  249. api_url = $(this).data('api-url');
  250. $(document).on('show.bs.modal', '#ConfirmDeleteModal', function() {
  251. $("#ItemsToDelete").empty();
  252. for (var i in data_array) {
  253. data_array[i] = decodeURIComponent(data_array[i]);
  254. $("#ItemsToDelete").append("<li>" + data_array[i] + "</li>");
  255. }
  256. })
  257. $('#ConfirmDeleteModal').modal({
  258. backdrop: 'static',
  259. keyboard: false
  260. })
  261. .one('click', '#IsConfirmed', function(e) {
  262. $.ajax({
  263. type: "POST",
  264. dataType: "json",
  265. cache: false,
  266. data: {
  267. "items": JSON.stringify(data_array),
  268. "csrf_token": csrf_token
  269. },
  270. url: '/api/v1/' + api_url,
  271. jsonp: false,
  272. complete: function(data) {
  273. window.location = window.location.href.split("#")[0];
  274. }
  275. });
  276. })
  277. .one('click', '#isCanceled', function(e) {
  278. // Remove event handler to allow to close modal and restart dialog without multiple submits
  279. $('#ConfirmDeleteModal').off();
  280. $('#ConfirmDeleteModal').modal('hide');
  281. });
  282. });
  283. });