[9604] | 1 | /*! |
---|
| 2 | ** Unobtrusive Ajax support library for jQuery |
---|
| 3 | ** Copyright (C) Microsoft Corporation. All rights reserved. |
---|
| 4 | */ |
---|
| 5 | |
---|
| 6 | /*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 */ |
---|
| 7 | /*global window: false, jQuery: false */ |
---|
| 8 | |
---|
| 9 | (function ($) { |
---|
| 10 | var data_click = "unobtrusiveAjaxClick", |
---|
| 11 | data_validation = "unobtrusiveValidation"; |
---|
| 12 | |
---|
| 13 | function getFunction(code, argNames) { |
---|
| 14 | var fn = window, parts = (code || "").split("."); |
---|
| 15 | while (fn && parts.length) { |
---|
| 16 | fn = fn[parts.shift()]; |
---|
| 17 | } |
---|
| 18 | if (typeof (fn) === "function") { |
---|
| 19 | return fn; |
---|
| 20 | } |
---|
| 21 | argNames.push(code); |
---|
| 22 | return Function.constructor.apply(null, argNames); |
---|
| 23 | } |
---|
| 24 | |
---|
| 25 | function isMethodProxySafe(method) { |
---|
| 26 | return method === "GET" || method === "POST"; |
---|
| 27 | } |
---|
| 28 | |
---|
| 29 | function asyncOnBeforeSend(xhr, method) { |
---|
| 30 | if (!isMethodProxySafe(method)) { |
---|
| 31 | xhr.setRequestHeader("X-HTTP-Method-Override", method); |
---|
| 32 | } |
---|
| 33 | } |
---|
| 34 | |
---|
| 35 | function asyncOnSuccess(element, data, contentType) { |
---|
| 36 | var mode; |
---|
| 37 | |
---|
| 38 | if (contentType.indexOf("application/x-javascript") !== -1) { // jQuery already executes JavaScript for us |
---|
| 39 | return; |
---|
| 40 | } |
---|
| 41 | |
---|
| 42 | mode = (element.getAttribute("data-ajax-mode") || "").toUpperCase(); |
---|
| 43 | $(element.getAttribute("data-ajax-update")).each(function (i, update) { |
---|
| 44 | var top; |
---|
| 45 | |
---|
| 46 | switch (mode) { |
---|
| 47 | case "BEFORE": |
---|
| 48 | top = update.firstChild; |
---|
| 49 | $("<div />").html(data).contents().each(function () { |
---|
| 50 | update.insertBefore(this, top); |
---|
| 51 | }); |
---|
| 52 | break; |
---|
| 53 | case "AFTER": |
---|
| 54 | $("<div />").html(data).contents().each(function () { |
---|
| 55 | update.appendChild(this); |
---|
| 56 | }); |
---|
| 57 | break; |
---|
| 58 | default: |
---|
| 59 | $(update).html(data); |
---|
| 60 | break; |
---|
| 61 | } |
---|
| 62 | }); |
---|
| 63 | } |
---|
| 64 | |
---|
| 65 | function asyncRequest(element, options) { |
---|
| 66 | var confirm, loading, method, duration; |
---|
| 67 | |
---|
| 68 | confirm = element.getAttribute("data-ajax-confirm"); |
---|
| 69 | if (confirm && !window.confirm(confirm)) { |
---|
| 70 | return; |
---|
| 71 | } |
---|
| 72 | |
---|
| 73 | loading = $(element.getAttribute("data-ajax-loading")); |
---|
| 74 | duration = element.getAttribute("data-ajax-loading-duration") || 0; |
---|
| 75 | |
---|
| 76 | $.extend(options, { |
---|
| 77 | type: element.getAttribute("data-ajax-method") || undefined, |
---|
| 78 | url: element.getAttribute("data-ajax-url") || undefined, |
---|
| 79 | beforeSend: function (xhr) { |
---|
| 80 | var result; |
---|
| 81 | asyncOnBeforeSend(xhr, method); |
---|
| 82 | result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(this, arguments); |
---|
| 83 | if (result !== false) { |
---|
| 84 | loading.show(duration); |
---|
| 85 | } |
---|
| 86 | return result; |
---|
| 87 | }, |
---|
| 88 | complete: function () { |
---|
| 89 | loading.hide(duration); |
---|
| 90 | getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(this, arguments); |
---|
| 91 | }, |
---|
| 92 | success: function (data, status, xhr) { |
---|
| 93 | asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html"); |
---|
| 94 | getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(this, arguments); |
---|
| 95 | }, |
---|
| 96 | error: getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"]) |
---|
| 97 | }); |
---|
| 98 | |
---|
| 99 | options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" }); |
---|
| 100 | |
---|
| 101 | method = options.type.toUpperCase(); |
---|
| 102 | if (!isMethodProxySafe(method)) { |
---|
| 103 | options.type = "POST"; |
---|
| 104 | options.data.push({ name: "X-HTTP-Method-Override", value: method }); |
---|
| 105 | } |
---|
| 106 | |
---|
| 107 | $.ajax(options); |
---|
| 108 | } |
---|
| 109 | |
---|
| 110 | function validate(form) { |
---|
| 111 | var validationInfo = $(form).data(data_validation); |
---|
| 112 | return !validationInfo || !validationInfo.validate || validationInfo.validate(); |
---|
| 113 | } |
---|
| 114 | |
---|
| 115 | $(document).on("click", "a[data-ajax=true]", function (evt) { |
---|
| 116 | evt.preventDefault(); |
---|
| 117 | asyncRequest(this, { |
---|
| 118 | url: this.href, |
---|
| 119 | type: "GET", |
---|
| 120 | data: [] |
---|
| 121 | }); |
---|
| 122 | }); |
---|
| 123 | |
---|
| 124 | $(document).on("click", "form[data-ajax=true] input[type=image]", function (evt) { |
---|
| 125 | var name = evt.target.name, |
---|
| 126 | $target = $(evt.target), |
---|
| 127 | form = $target.parents("form")[0], |
---|
| 128 | offset = $target.offset(); |
---|
| 129 | |
---|
| 130 | $(form).data(data_click, [ |
---|
| 131 | { name: name + ".x", value: Math.round(evt.pageX - offset.left) }, |
---|
| 132 | { name: name + ".y", value: Math.round(evt.pageY - offset.top) } |
---|
| 133 | ]); |
---|
| 134 | |
---|
| 135 | setTimeout(function () { |
---|
| 136 | $(form).removeData(data_click); |
---|
| 137 | }, 0); |
---|
| 138 | }); |
---|
| 139 | |
---|
| 140 | $(document).on("click", "form[data-ajax=true] :submit", function (evt) { |
---|
| 141 | var name = evt.target.name, |
---|
| 142 | form = $(evt.target).parents("form")[0]; |
---|
| 143 | |
---|
| 144 | $(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []); |
---|
| 145 | |
---|
| 146 | setTimeout(function () { |
---|
| 147 | $(form).removeData(data_click); |
---|
| 148 | }, 0); |
---|
| 149 | }); |
---|
| 150 | |
---|
| 151 | $(document).on("submit", "form[data-ajax=true]", function (evt) { |
---|
| 152 | var clickInfo = $(this).data(data_click) || []; |
---|
| 153 | evt.preventDefault(); |
---|
| 154 | if (!validate(this)) { |
---|
| 155 | return; |
---|
| 156 | } |
---|
| 157 | asyncRequest(this, { |
---|
| 158 | url: this.action, |
---|
| 159 | type: this.method || "GET", |
---|
| 160 | data: clickInfo.concat($(this).serializeArray()) |
---|
| 161 | }); |
---|
| 162 | }); |
---|
| 163 | }(jQuery)); |
---|