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