-
Notifications
You must be signed in to change notification settings - Fork 67
/
rails.js
143 lines (125 loc) · 4.72 KB
/
rails.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
dojo.provide("dojox.rails");
dojo.require("dojo.NodeList-traverse");
dojox.rails.live = function(selector, evtName, fn){
if (dojo.isIE && evtName.match(/^(on)?submit$/i)){
dojox.rails.live(selector, "click", function(evt){
var target = evt.target, tag = target.tagName.toLowerCase();
if ((tag == "input" || tag == "button") && dojo.attr(target, "type").toLowerCase() == "submit"){
var form = dojo.query(target).closest("form");
if (form.length){
var h = dojo.connect(form[0], "submit", function(evt){
dojo.disconnect(h);
fn.call(evt.target, evt);
});
}
}
});
}else{
dojo.connect(dojo.body(), evtName, function(evt){
var nl = dojo.query(evt.target).closest(selector);
if (nl.length){
fn.call(nl[0], evt);
}
});
}
};
dojo.ready((function(d, dr, dg){
return function() {
var q = d.query, live = dr.live,
csrfToken = q("meta[name=csrf-token]").attr("content"),
csrfParam = q("meta[name=csrf-param]").attr("content");
var createFormForLink = function(url, method){
var form = '<form style="display:none" method="post" action="'+ url +'">' +
'<input type="hidden" name="_method" value="'+ method +'" />' +
'<input type="hidden" name="'+ csrfParam +'" value="'+ csrfToken +'" />' +
'</form>';
return dojo.place(form, dojo.body());
};
var disable = function(elements){
d.forEach(elements, function(node){
if (!d.attr(node, "disabled")){
var attr = node.tagName.toLowerCase() == "input" ? "value" : "innerHTML";
var message = d.attr(node, "data-disable-with");
var originalValue = d.attr(node, attr);
d.attr(node, "disabled", true);
d.attr(node, "data-original-value", originalValue);
d.attr(node, attr, message);
}
});
};
var typeMap = {
"text": "text",
"json": "application/json",
"json-comment-optional": "text",
"json-comment-filtered": "text",
"javascript": "application/javascript",
"xml": "text/xml"
};
var handleRemote = function(evt){
var el = evt.target, tag = el.tagName.toLowerCase();
var content = tag.toLowerCase() == "form" ? d.formToObject(el) : {},
type = d.attr(el, "data-type") || "javascript",
method = (d.attr(el, "method") || d.attr(el, "data-method") || "get").toLowerCase(),
url = d.attr(el, "action") || d.attr(el, "href");
if (tag != "form" && method != "get"){
el = createFormForLink(url, method);
method = "POST";
}
evt.preventDefault();
// ajax:loading, ajax:loaded, and ajax:interactive are not supported
d.publish("ajax:before", [el]);
var deferred = d.xhr(method, {
url: url,
headers: { "Accept": typeMap[type] },
content: content,
handleAs: type,
load: function(response, ioArgs) {d.publish("ajax:success", [el, response, ioArgs]);},
error: function(response, ioArgs) {d.publish("ajax:failure", [el, response, ioArgs]);},
handle: function(response, ioArgs) {d.publish("ajax:complete", [el, response, ioArgs]);}
});
d.publish("ajax:after", [el]);
};
var handleEnable = function(el){
q("*[data-disable-with][disabled]", el).forEach(function(node){
var attr = node.tagName.toLowerCase() == "input" ? "value" : "innerHTML";
var value = d.attr(node, "data-original-value");
d.attr(node, "disabled", false);
d.attr(node, "data-original-value", null);
d.attr(node, attr, value);
});
};
var handleDataMethod = function(evt){
var el = evt.target, form = createFormForLink(el.href, dojo.attr(el, "data-method"));
evt.preventDefault();
form.submit();
};
var handleFormSubmit = function(evt){
var el = evt.target, elements = q("*[data-disable-with]", el);
if (elements.length){ disable(elements); }
if (d.attr(el, "data-remote")){
evt.preventDefault();
handleRemote(evt);
}
};
var handleConfirm = function(evt){
var proceed = dg.confirm(d.attr(evt.target, "data-confirm"));
if (!proceed){
evt.preventDefault();
}else if (d.attr(evt.target, "data-remote")){
handleRemote(evt);
}
};
// Register data-{action} elements. Order is important since the return values
// from previously called functions in the connect chain influence whether
// or not the next function in the chain is called.
// Register data-confirm elements
live("*[data-confirm]", "click", handleConfirm);
// data-disable-with only applies to forms
d.subscribe("ajax:complete", handleEnable);
// Register data-remote elements
live("a[data-remote]:not([data-confirm])", "click", handleRemote);
live("a[data-method]:not([data-remote])", "click", handleDataMethod);
// Handle form submits
live("form", "submit", handleFormSubmit);
};
})(dojo, dojox.rails, dojo.global));