ajax.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. function AjaxErrorBadStatusCode(message) { this.name = 'AjaxErrorBadStatusCode'; this.message = message; };
  2. AjaxErrorBadStatusCode.prototype = new Error();
  3. var ajax = {loaded: false};
  4. ajax.callTagsBefore = function(tag) {};
  5. ajax.callTagsAfter = function(tag) {};
  6. ajax.callFormsBefore = function(form) {};
  7. ajax.callFormsAfter = function(form) {};
  8. ajax.callCheckboxesBefore = function(box) {};
  9. ajax.callCheckboxesAfter = function(box) {};
  10. ajax.create = function() {
  11. if(typeof XMLHttpRequest !== 'undefined') {
  12. return new XMLHttpRequest();
  13. };
  14. var versions = [
  15. "MSXML2.XmlHttp.6.0",
  16. "MSXML2.XmlHttp.5.0",
  17. "MSXML2.XmlHttp.4.0",
  18. "MSXML2.XmlHttp.3.0",
  19. "MSXML2.XmlHttp.2.0",
  20. "Microsoft.XmlHttp"
  21. ];
  22. var xhr;
  23. for(var i = 0; i < versions.length; i++) {
  24. try {
  25. xhr = new ActiveXObject(versions[i]);
  26. break;
  27. } catch(e) {
  28. // Silent
  29. };
  30. };
  31. return xhr;
  32. };
  33. ajax.send = function(url, callback, method, data, async, multipart) {
  34. if(async === undefined) {
  35. async = true;
  36. };
  37. if(multipart === undefined) {
  38. multipart = false;
  39. };
  40. var a = ajax.create();
  41. a.open(method, url, async);
  42. a.onreadystatechange = function() {
  43. // a.readyState:
  44. // 0 - UNSENT
  45. // 1 - OPENED
  46. // 2 - HEADERS_RECEIVED
  47. // 3 - LOADING
  48. // 4 - DONE
  49. callback(method, data, a.readyState, a.status, a.responseText);
  50. };
  51. if(method == 'PUT' || method == 'POST') {
  52. if(!multipart) {
  53. a.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  54. };
  55. };
  56. a.send(data);
  57. };
  58. ajax.del = function(url, data, callback, async) {
  59. var query = [];
  60. for(var key in data) {
  61. query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
  62. };
  63. ajax.send(url + (query.length ? '?' + query.join('&') : ''), callback, 'DELETE', null, async);
  64. };
  65. ajax.delJSON = function(url, data, callbackSuccess, callbackError, async) {
  66. ajax.del(url, data, function(method, data, readyState, status, responseText) {
  67. if(readyState == 4) {
  68. if(status == 200) {
  69. try {
  70. var r = JSON.parse(responseText);
  71. if(callbackSuccess) {
  72. callbackSuccess(method, data, readyState, status, r);
  73. };
  74. } catch(e) {
  75. if(callbackError) {
  76. callbackError(method, data, readyState, status, e);
  77. };
  78. };
  79. } else {
  80. if(callbackError) {
  81. var e = new AjaxErrorBadStatusCode('Bad status code '+status);
  82. callbackError(method, data, readyState, status, e);
  83. };
  84. };
  85. };
  86. }, async);
  87. };
  88. ajax.get = function(url, data, callback, async) {
  89. var query = [];
  90. for(var key in data) {
  91. query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
  92. };
  93. ajax.send(url + (query.length ? '?' + query.join('&') : ''), callback, 'GET', null, async);
  94. };
  95. ajax.getJSON = function(url, data, callbackSuccess, callbackError, async) {
  96. ajax.get(url, data, function(method, data, readyState, status, responseText) {
  97. if(readyState == 4) {
  98. if(status == 200) {
  99. try {
  100. var r = JSON.parse(responseText);
  101. if(callbackSuccess) {
  102. callbackSuccess(method, data, readyState, status, r);
  103. };
  104. } catch(e) {
  105. if(callbackError) {
  106. callbackError(method, data, readyState, status, e);
  107. };
  108. };
  109. } else {
  110. if(callbackError) {
  111. var e = new AjaxErrorBadStatusCode('Bad status code '+status);
  112. callbackError(method, data, readyState, status, e);
  113. };
  114. };
  115. };
  116. }, async);
  117. };
  118. ajax.put = function(url, data, callback, async, multipart) {
  119. if(multipart) {
  120. ajax.send(url, callback, 'PUT', data, async, multipart);
  121. } else {
  122. var query = [];
  123. for (var key in data) {
  124. query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
  125. };
  126. ajax.send(url, callback, 'PUT', query.join('&'), async, multipart);
  127. };
  128. };
  129. ajax.putJSON = function(url, data, callbackSuccess, callbackError, async, multipart) {
  130. ajax.put(url, data, function(method, data, readyState, status, responseText) {
  131. if(readyState == 4) {
  132. if(status == 200) {
  133. try {
  134. var r = JSON.parse(responseText);
  135. if(callbackSuccess) {
  136. callbackSuccess(method, data, readyState, status, r);
  137. };
  138. } catch(e) {
  139. if(callbackError) {
  140. callbackError(method, data, readyState, status, e);
  141. };
  142. };
  143. } else {
  144. if(callbackError) {
  145. var e = new AjaxErrorBadStatusCode('Bad status code '+status);
  146. callbackError(method, data, readyState, status, e);
  147. };
  148. };
  149. };
  150. }, async, multipart);
  151. };
  152. ajax.post = function(url, data, callback, async, multipart) {
  153. if(multipart) {
  154. ajax.send(url, callback, 'POST', data, async, multipart);
  155. } else {
  156. var query = [];
  157. for (var key in data) {
  158. query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
  159. };
  160. ajax.send(url, callback, 'POST', query.join('&'), async, multipart);
  161. };
  162. };
  163. ajax.postJSON = function(url, data, callbackSuccess, callbackError, async, multipart) {
  164. ajax.post(url, data, function(method, data, readyState, status, responseText) {
  165. if(readyState == 4) {
  166. if(status == 200) {
  167. try {
  168. var r = JSON.parse(responseText);
  169. if(callbackSuccess) {
  170. callbackSuccess(method, data, readyState, status, r);
  171. };
  172. } catch(e) {
  173. if(callbackError) {
  174. callbackError(method, data, readyState, status, e);
  175. };
  176. };
  177. } else {
  178. if(callbackError) {
  179. var e = new AjaxErrorBadStatusCode('Bad status code '+status);
  180. callbackError(method, data, readyState, status, e);
  181. };
  182. };
  183. };
  184. }, async, multipart);
  185. };
  186. ajax.loadTag = function(tag, url, func, field) {
  187. if((typeof window[func] === 'function') || field != null) {
  188. if(!!!tag.className.match(new RegExp('(\\s|^)loading(\\s|$)'))) {
  189. ajax.callTagsBefore(tag);
  190. tag.className += " loading";
  191. ajax.getJSON(url, {}, function(method, data, readyState, status, responseData) {
  192. try {
  193. if(typeof window[func] === 'function') {
  194. var html = window[func](tag, responseData);
  195. tag.innerHTML = html;
  196. } else if(field != null) {
  197. tag.innerHTML = responseData[field];
  198. };
  199. } catch(e) {
  200. console.log('ajax.loadTag', 'e', e);
  201. };
  202. tag.className = tag.className.replace(new RegExp('(\\s|^)loading(\\s|$)'), ' ').trim();
  203. ajax.callTagsAfter(tag);
  204. }, function(method, data, readyState, status, responseData) {
  205. tag.className = tag.className.replace(new RegExp('(\\s|^)loading(\\s|$)'), ' ').trim();
  206. ajax.callTagsAfter(tag);
  207. });
  208. };
  209. };
  210. };
  211. ajax.processTag = function(tag) {
  212. var get = tag.getAttribute('data-ajax-get');
  213. var func = tag.getAttribute('data-ajax-func');
  214. var field = tag.getAttribute('data-ajax-field');
  215. var delay = tag.getAttribute('data-ajax-delay');
  216. if((get && get != null) && ((func && func != null) || (field && field != null))) {
  217. if(delay == null) {
  218. ajax.loadTag(tag, get, func, field);
  219. } else {
  220. setTimeout(function() {
  221. ajax.loadTag(tag, get, func, field);
  222. }, delay);
  223. };
  224. };
  225. };
  226. ajax.processTags = function() {
  227. var tags = document.querySelectorAll('[data-ajax-get]');
  228. for(var key in tags) if(tags.hasOwnProperty(key)) {
  229. var tag = tags[key];
  230. ajax.processTag(tag);
  231. };
  232. };
  233. ajax.reloadTag = function(tag) {
  234. ajax.processTag(tag);
  235. };
  236. ajax.reloadTagById = function(id) {
  237. var tag = document.getElementById(id)
  238. if(tag != null) {
  239. ajax.reloadTag(tag);
  240. };
  241. };
  242. ajax.processFormSubmit = function(event) {
  243. if(!event) var event = window.event;
  244. event.preventDefault();
  245. var form = event.target;
  246. var func = form.getAttribute('data-ajax-func');
  247. var put = form.getAttribute('data-put');
  248. if(func && func != null && typeof window[func] === 'function') {
  249. if(!!!form.className.match(new RegExp('(\\s|^)loading(\\s|$)'))) {
  250. ajax.callFormsBefore(form);
  251. form.className += " loading";
  252. var data = null;
  253. var inputs = form.querySelectorAll("input,select,textarea");
  254. var files = form.querySelectorAll("input[type=file]");
  255. var multipart = files.length > 0;
  256. if(!multipart) {
  257. data = {};
  258. var inputs = form.querySelectorAll("input,select,textarea");
  259. for(var i=0,m=inputs.length-1; i<=m; i++) {
  260. data[inputs[i].name] = inputs[i].value;
  261. };
  262. } else {
  263. data = new FormData();
  264. var inputs = form.querySelectorAll("input,select,textarea");
  265. for(var i=0,m=inputs.length-1; i<=m; i++) {
  266. if(inputs[i].type != 'file') {
  267. data.append(inputs[i].name, inputs[i].value);
  268. } else {
  269. if(!multipart) {
  270. multipart = true;
  271. };
  272. };
  273. };
  274. var files = form.querySelectorAll("input[type=file]");
  275. for(var i=0,m=files.length-1; i<=m; i++) {
  276. for(var j=0,k=files[i].files.length-1; j<=k; j++) {
  277. data.append(files[i].name, files[i].files[j]);
  278. };
  279. };
  280. };
  281. var ajaxFunc = ajax.get;
  282. if(form.method == "post") { ajaxFunc = ajax.post; };
  283. if(put && put != null && put == "true") { ajaxFunc = ajax.put; };
  284. ajaxFunc(form.action, data, function(method, data, readyState, status, responseText) {
  285. if(readyState == 4) {
  286. var error = (status != 200);
  287. var responseData = responseText;
  288. try {
  289. var responseData = JSON.parse(responseText);
  290. } catch(e) {
  291. console.log('ajax.processFormSubmit', 'e', e);
  292. };
  293. try {
  294. window[func](form, responseData, error, status);
  295. } catch(e) {
  296. console.log('ajax.processFormSubmit', 'e', e);
  297. };
  298. form.className = form.className.replace(new RegExp('(\\s|^)loading(\\s|$)'), ' ').trim();
  299. ajax.callFormsAfter(form);
  300. };
  301. }, true, multipart);
  302. };
  303. };
  304. };
  305. ajax.processForm = function(form) {
  306. var is = form.getAttribute('data-ajax-form');
  307. var func = form.getAttribute('data-ajax-func');
  308. if((is && is != null && is == "true") && (func && func != null)) {
  309. if(window.attachEvent) {
  310. form.attachEvent('onsubmit', ajax.processFormSubmit);
  311. } else if(window.addEventListener) {
  312. form.addEventListener('submit', ajax.processFormSubmit, false);
  313. };
  314. };
  315. };
  316. ajax.processForms = function() {
  317. var forms = document.querySelectorAll('[data-ajax-form]');
  318. for(var key in forms) if(forms.hasOwnProperty(key)) {
  319. var form = forms[key];
  320. ajax.processForm(form);
  321. };
  322. };
  323. ajax.processCheckboxClick = function(event) {
  324. if(!event) var event = window.event;
  325. var checkbox = event.target;
  326. var on = checkbox.getAttribute('data-ajax-on');
  327. var off = checkbox.getAttribute('data-ajax-off');
  328. var func = checkbox.getAttribute('data-ajax-func');
  329. var box = checkbox.parentNode;
  330. if(!!box.className.match(new RegExp('(\\s|^)loading(\\s|$)'))) {
  331. event.preventDefault();
  332. event.stopPropagation();
  333. return false;
  334. };
  335. ajax.callCheckboxesBefore(box);
  336. box.className += " loading";
  337. ajax.post(checkbox.checked ? on : off, {}, function(method, data, readyState, status, responseText) {
  338. if(readyState == 4) {
  339. var error = (status != 200);
  340. var responseData = responseText;
  341. try {
  342. var responseData = JSON.parse(responseText);
  343. } catch(e) {
  344. console.log('ajax.processCheckboxClick', 'e', e);
  345. };
  346. try {
  347. window[func](checkbox, responseData, error, status);
  348. } catch(e) {
  349. console.log('ajax.processCheckboxClick', 'e', e);
  350. };
  351. if(error) {
  352. checkbox.checked = !checkbox.checked;
  353. };
  354. box.className = box.className.replace(new RegExp('(\\s|^)loading(\\s|$)'), ' ').trim();
  355. ajax.callCheckboxesAfter(box);
  356. };
  357. });
  358. return true;
  359. };
  360. ajax.processCheckbox = function(checkbox) {
  361. var is = checkbox.getAttribute('data-ajax-checkbox');
  362. var on = checkbox.getAttribute('data-ajax-on');
  363. var off = checkbox.getAttribute('data-ajax-off');
  364. var func = checkbox.getAttribute('data-ajax-func');
  365. if((is && is != null && is == "true") && (on && on != null) && (off && off != null) && (func && func != null)) {
  366. if(window.attachEvent) {
  367. checkbox.attachEvent('onclick', ajax.processCheckboxClick);
  368. } else if(window.addEventListener) {
  369. checkbox.addEventListener('click', ajax.processCheckboxClick, false);
  370. };
  371. };
  372. };
  373. ajax.processCheckboxes = function() {
  374. var checkboxes = document.querySelectorAll('[data-ajax-checkbox]');
  375. for(var key in checkboxes) if(checkboxes.hasOwnProperty(key)) {
  376. var checkbox = checkboxes[key];
  377. ajax.processCheckbox(checkbox);
  378. };
  379. };
  380. ajax.load = function() {
  381. if(!ajax.loaded) {
  382. if(window.AjaxInit !== undefined) {
  383. if(typeof window['AjaxInit'] === 'function') {
  384. AjaxInit();
  385. };
  386. };
  387. ajax.loaded = true;
  388. ajax.processTags();
  389. ajax.processForms();
  390. ajax.processCheckboxes();
  391. };
  392. };
  393. if(window.attachEvent) {
  394. window.attachEvent('onload', ajax.load);
  395. } else if(window.addEventListener) {
  396. window.addEventListener('load', ajax.load, false);
  397. };