ajax.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*globals elgg, $*/
  2. elgg.provide('elgg.ajax');
  3. /**
  4. * @author Evan Winslow
  5. * Provides a bunch of useful shortcut functions for making ajax calls
  6. */
  7. /**
  8. * Wrapper function for jQuery.ajax which ensures that the url being called
  9. * is relative to the elgg site root.
  10. *
  11. * You would most likely use elgg.get or elgg.post, rather than this function
  12. *
  13. * @param {string} url Optionally specify the url as the first argument
  14. * @param {Object} options Optional. {@link jQuery#ajax}
  15. * @return {jqXHR}
  16. */
  17. elgg.ajax = function(url, options) {
  18. options = elgg.ajax.handleOptions(url, options);
  19. options.url = elgg.normalize_url(options.url);
  20. return $.ajax(options);
  21. };
  22. /**
  23. * @const
  24. */
  25. elgg.ajax.SUCCESS = 0;
  26. /**
  27. * @const
  28. */
  29. elgg.ajax.ERROR = -1;
  30. /**
  31. * Handle optional arguments and return the resulting options object
  32. *
  33. * @param url
  34. * @param options
  35. * @return {Object}
  36. * @private
  37. */
  38. elgg.ajax.handleOptions = function(url, options) {
  39. var data_only = true,
  40. data,
  41. member;
  42. //elgg.ajax('example/file.php', {...});
  43. if (elgg.isString(url)) {
  44. options = options || {};
  45. //elgg.ajax({...});
  46. } else {
  47. options = url || {};
  48. url = options.url;
  49. }
  50. //elgg.ajax('example/file.php', function() {...});
  51. if (elgg.isFunction(options)) {
  52. data_only = false;
  53. options = {success: options};
  54. }
  55. //elgg.ajax('example/file.php', {data:{...}});
  56. if (options.data) {
  57. data_only = false;
  58. } else {
  59. for (member in options) {
  60. //elgg.ajax('example/file.php', {callback:function(){...}});
  61. if (elgg.isFunction(options[member])) {
  62. data_only = false;
  63. }
  64. }
  65. }
  66. //elgg.ajax('example/file.php', {notdata:notfunc});
  67. if (data_only) {
  68. data = options;
  69. options = {data: data};
  70. }
  71. if (!elgg.isFunction(options.error)) {
  72. // add a generic error handler
  73. options.error = function(xhr, status, error) {
  74. elgg.ajax.handleAjaxError(xhr, status, error);
  75. };
  76. }
  77. if (url) {
  78. options.url = url;
  79. }
  80. return options;
  81. };
  82. /**
  83. * Handles low level errors like 404
  84. *
  85. * @param xhr
  86. * @param status
  87. * @param error
  88. * @private
  89. */
  90. elgg.ajax.handleAjaxError = function(xhr, status, error) {
  91. elgg.register_error(elgg.echo('ajax:error'));
  92. };
  93. /**
  94. * Wrapper function for elgg.ajax which forces the request type to 'get.'
  95. *
  96. * @param {string} url Optionally specify the url as the first argument
  97. * @param {Object} options {@link jQuery#ajax}
  98. * @return {jqXHR}
  99. */
  100. elgg.get = function(url, options) {
  101. options = elgg.ajax.handleOptions(url, options);
  102. options.type = 'get';
  103. return elgg.ajax(options);
  104. };
  105. /**
  106. * Wrapper function for elgg.get which forces the dataType to 'json.'
  107. *
  108. * @param {string} url Optionally specify the url as the first argument
  109. * @param {Object} options {@link jQuery#ajax}
  110. * @return {jqXHR}
  111. */
  112. elgg.getJSON = function(url, options) {
  113. options = elgg.ajax.handleOptions(url, options);
  114. options.dataType = 'json';
  115. return elgg.get(options);
  116. };
  117. /**
  118. * Wrapper function for elgg.ajax which forces the request type to 'post.'
  119. *
  120. * @param {string} url Optionally specify the url as the first argument
  121. * @param {Object} options {@link jQuery#ajax}
  122. * @return {jqXHR}
  123. */
  124. elgg.post = function(url, options) {
  125. options = elgg.ajax.handleOptions(url, options);
  126. options.type = 'post';
  127. return elgg.ajax(options);
  128. };
  129. /**
  130. * Perform an action via ajax
  131. *
  132. * @example Usage 1:
  133. * At its simplest, only the action name is required (and anything more than the
  134. * action name will be invalid).
  135. * <pre>
  136. * elgg.action('name/of/action');
  137. * </pre>
  138. *
  139. * The action can be relative to the current site ('name/of/action') or
  140. * the full URL of the action ('http://elgg.org/action/name/of/action').
  141. *
  142. * @example Usage 2:
  143. * If you want to pass some data along with it, use the second parameter
  144. * <pre>
  145. * elgg.action('friend/add', { friend: some_guid });
  146. * </pre>
  147. *
  148. * @example Usage 3:
  149. * Of course, you will have no control over what happens when the request
  150. * completes if you do it like that, so there's also the most verbose method
  151. * <pre>
  152. * elgg.action('friend/add', {
  153. * data: {
  154. * friend: some_guid
  155. * },
  156. * success: function(json) {
  157. * //do something
  158. * },
  159. * }
  160. * </pre>
  161. * You can pass any of your favorite $.ajax arguments into this second parameter.
  162. *
  163. * @note If you intend to use the second field in the "verbose" way, you must
  164. * specify a callback method or the data parameter. If you do not, elgg.action
  165. * will think you mean to send the second parameter as data.
  166. *
  167. * @note You do not have to add security tokens to this request. Elgg does that
  168. * for you automatically.
  169. *
  170. * @see jQuery.ajax
  171. *
  172. * @param {String} action The action to call.
  173. * @param {Object} options
  174. * @return {jqXHR}
  175. */
  176. elgg.action = function(action, options) {
  177. elgg.assertTypeOf('string', action);
  178. // support shortcut and full URLs
  179. // this will mangle URLs that aren't elgg actions.
  180. // Use post, get, or ajax for those.
  181. if (action.indexOf('action/') < 0) {
  182. action = 'action/' + action;
  183. }
  184. options = elgg.ajax.handleOptions(action, options);
  185. // This is a misuse of elgg.security.addToken() because it is not always a
  186. // full query string with a ?. As such we need a special check for the tokens.
  187. if (!elgg.isString(options.data) || options.data.indexOf('__elgg_ts') == -1) {
  188. options.data = elgg.security.addToken(options.data);
  189. }
  190. options.dataType = 'json';
  191. //Always display system messages after actions
  192. var custom_success = options.success || elgg.nullFunction;
  193. options.success = function(json, two, three, four) {
  194. if (json && json.system_messages) {
  195. elgg.register_error(json.system_messages.error);
  196. elgg.system_message(json.system_messages.success);
  197. }
  198. custom_success(json, two, three, four);
  199. };
  200. return elgg.post(options);
  201. };
  202. /**
  203. * Make an API call
  204. *
  205. * @example Usage:
  206. * <pre>
  207. * elgg.api('system.api.list', {
  208. * success: function(data) {
  209. * console.log(data);
  210. * }
  211. * });
  212. * </pre>
  213. *
  214. * @param {String} method The API method to be called
  215. * @param {Object} options {@link jQuery#ajax}
  216. * @return {jqXHR}
  217. */
  218. elgg.api = function (method, options) {
  219. elgg.assertTypeOf('string', method);
  220. var defaults = {
  221. dataType: 'json',
  222. data: {}
  223. };
  224. options = elgg.ajax.handleOptions(method, options);
  225. options = $.extend(defaults, options);
  226. options.url = 'services/api/rest/' + options.dataType + '/';
  227. options.data.method = method;
  228. return elgg.ajax(options);
  229. };