jquery.unobtrusive-ajax.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /* NUGET: BEGIN LICENSE TEXT
  2. *
  3. * Microsoft grants you the right to use these script files for the sole
  4. * purpose of either: (i) interacting through your browser with the Microsoft
  5. * website or online service, subject to the applicable licensing or use
  6. * terms; or (ii) using the files as included with a Microsoft product subject
  7. * to that product's license terms. Microsoft reserves all other rights to the
  8. * files not expressly granted by Microsoft, whether by implication, estoppel
  9. * or otherwise. Insofar as a script file is dual licensed under GPL,
  10. * Microsoft neither took the code under GPL nor distributes it thereunder but
  11. * under the terms set out in this paragraph. All notices and licenses
  12. * below are for informational purposes only.
  13. *
  14. * NUGET: END LICENSE TEXT */
  15. /*!
  16. ** Unobtrusive Ajax support library for jQuery
  17. ** Copyright (C) Microsoft Corporation. All rights reserved.
  18. */
  19. /*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
  20. /*global window: false, jQuery: false */
  21. (function ($) {
  22. var data_click = "unobtrusiveAjaxClick",
  23. data_target = "unobtrusiveAjaxClickTarget"
  24. data_validation = "unobtrusiveValidation";
  25. function getFunction(code, argNames) {
  26. var fn = window, parts = (code || "").split(".");
  27. while (fn && parts.length) {
  28. fn = fn[parts.shift()];
  29. }
  30. if (typeof (fn) === "function") {
  31. return fn;
  32. }
  33. argNames.push(code);
  34. return Function.constructor.apply(null, argNames);
  35. }
  36. function isMethodProxySafe(method) {
  37. return method === "GET" || method === "POST";
  38. }
  39. function asyncOnBeforeSend(xhr, method) {
  40. if (!isMethodProxySafe(method)) {
  41. xhr.setRequestHeader("X-HTTP-Method-Override", method);
  42. }
  43. }
  44. function asyncOnSuccess(element, data, contentType) {
  45. var mode;
  46. if (contentType.indexOf("application/x-javascript") !== -1) { // jQuery already executes JavaScript for us
  47. return;
  48. }
  49. mode = (element.getAttribute("data-ajax-mode") || "").toUpperCase();
  50. $(element.getAttribute("data-ajax-update")).each(function (i, update) {
  51. var top;
  52. switch (mode) {
  53. case "BEFORE":
  54. top = update.firstChild;
  55. $("<div />").html(data).contents().each(function () {
  56. update.insertBefore(this, top);
  57. });
  58. break;
  59. case "AFTER":
  60. $("<div />").html(data).contents().each(function () {
  61. update.appendChild(this);
  62. });
  63. break;
  64. default:
  65. $(update).html(data);
  66. break;
  67. }
  68. });
  69. }
  70. function asyncRequest(element, options) {
  71. var confirm, loading, method, duration;
  72. confirm = element.getAttribute("data-ajax-confirm");
  73. if (confirm && !window.confirm(confirm)) {
  74. return;
  75. }
  76. loading = $(element.getAttribute("data-ajax-loading"));
  77. duration = parseInt(element.getAttribute("data-ajax-loading-duration"), 10) || 0;
  78. $.extend(options, {
  79. context: element,
  80. type: element.getAttribute("data-ajax-method") || undefined,
  81. url: element.getAttribute("data-ajax-url") || undefined,
  82. beforeSend: function (xhr) {
  83. var result;
  84. asyncOnBeforeSend(xhr, method);
  85. result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(this, arguments);
  86. if (result !== false) {
  87. loading.show(duration);
  88. }
  89. return result;
  90. },
  91. complete: function () {
  92. loading.hide(duration);
  93. getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(this, arguments);
  94. },
  95. success: function (data, status, xhr) {
  96. asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html");
  97. getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(this, arguments);
  98. },
  99. error: getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"])
  100. });
  101. options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" });
  102. method = options.type.toUpperCase();
  103. if (!isMethodProxySafe(method)) {
  104. options.type = "POST";
  105. options.data.push({ name: "X-HTTP-Method-Override", value: method });
  106. }
  107. $.ajax(options);
  108. }
  109. function validate(form) {
  110. var validationInfo = $(form).data(data_validation);
  111. return !validationInfo || !validationInfo.validate || validationInfo.validate();
  112. }
  113. $(document).on("click", "a[data-ajax=true]", function (evt) {
  114. evt.preventDefault();
  115. asyncRequest(this, {
  116. url: this.href,
  117. type: "GET",
  118. data: []
  119. });
  120. });
  121. $(document).on("click", "form[data-ajax=true] input[type=image]", function (evt) {
  122. var name = evt.target.name,
  123. target = $(evt.target),
  124. form = $(target.parents("form")[0]),
  125. offset = target.offset();
  126. form.data(data_click, [
  127. { name: name + ".x", value: Math.round(evt.pageX - offset.left) },
  128. { name: name + ".y", value: Math.round(evt.pageY - offset.top) }
  129. ]);
  130. setTimeout(function () {
  131. form.removeData(data_click);
  132. }, 0);
  133. });
  134. $(document).on("click", "form[data-ajax=true] :submit", function (evt) {
  135. var name = evt.currentTarget.name,
  136. target = $(evt.target),
  137. form = $(target.parents("form")[0]);
  138. form.data(data_click, name ? [{ name: name, value: evt.currentTarget.value }] : []);
  139. form.data(data_target, target);
  140. setTimeout(function () {
  141. form.removeData(data_click);
  142. form.removeData(data_target);
  143. }, 0);
  144. });
  145. $(document).on("submit", "form[data-ajax=true]", function (evt) {
  146. var clickInfo = $(this).data(data_click) || [],
  147. clickTarget = $(this).data(data_target),
  148. isCancel = clickTarget && clickTarget.hasClass("cancel");
  149. evt.preventDefault();
  150. if (!isCancel && !validate(this)) {
  151. return;
  152. }
  153. asyncRequest(this, {
  154. url: this.action,
  155. type: this.method || "GET",
  156. data: clickInfo.concat($(this).serializeArray())
  157. });
  158. });
  159. }(jQuery));