best_in_place 0.1.7 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +8 -0
- data/lib/best_in_place.rb +9 -5
- data/lib/best_in_place/version.rb +2 -2
- data/public/javascripts/best_in_place.js +132 -114
- data/public/javascripts/jquery-1.4.4.js +7179 -0
- data/test_app/Gemfile.lock +1 -1
- data/test_app/public/javascripts/best_in_place.js +132 -114
- data/test_app/public/javascripts/rails.js +148 -133
- metadata +5 -5
- data/public/javascripts/jquery-1.4.2.min.js +0 -154
data/test_app/Gemfile.lock
CHANGED
@@ -20,250 +20,268 @@
|
|
20
20
|
*/
|
21
21
|
|
22
22
|
function BestInPlaceEditor(e) {
|
23
|
-
this.element = jQuery(e)
|
24
|
-
this.initOptions()
|
25
|
-
this.bindForm()
|
26
|
-
$(this.activator).bind('click', {editor: this}, this.clickHandler)
|
23
|
+
this.element = jQuery(e);
|
24
|
+
this.initOptions();
|
25
|
+
this.bindForm();
|
26
|
+
$(this.activator).bind('click', {editor: this}, this.clickHandler);
|
27
27
|
}
|
28
28
|
|
29
29
|
BestInPlaceEditor.prototype = {
|
30
30
|
// Public Interface Functions //////////////////////////////////////////////
|
31
31
|
|
32
32
|
activate : function() {
|
33
|
-
var elem = this.element.html()
|
34
|
-
this.oldValue = elem
|
35
|
-
$(this.activator).unbind("click", this.clickHandler)
|
36
|
-
this.activateForm()
|
33
|
+
var elem = this.element.html();
|
34
|
+
this.oldValue = elem;
|
35
|
+
$(this.activator).unbind("click", this.clickHandler);
|
36
|
+
this.activateForm();
|
37
37
|
},
|
38
38
|
|
39
39
|
abort : function() {
|
40
|
-
this.element.html(this.oldValue)
|
41
|
-
$(this.activator).bind('click', {editor: this}, this.clickHandler)
|
40
|
+
this.element.html(this.oldValue);
|
41
|
+
$(this.activator).bind('click', {editor: this}, this.clickHandler);
|
42
42
|
},
|
43
43
|
|
44
44
|
update : function() {
|
45
|
-
var editor = this
|
45
|
+
var editor = this;
|
46
46
|
if (this.formType in {"input":1, "textarea":1} && this.getValue() == this.oldValue)
|
47
47
|
{ // Avoid request if no change is made
|
48
|
-
editor.element.html(this.getValue())
|
49
|
-
$(this.activator).bind('click', {editor: this}, this.clickHandler)
|
50
|
-
return true
|
48
|
+
editor.element.html(this.getValue());
|
49
|
+
$(this.activator).bind('click', {editor: this}, this.clickHandler);
|
50
|
+
return true;
|
51
51
|
}
|
52
52
|
editor.ajax({
|
53
53
|
"type" : "post",
|
54
54
|
"dataType" : "text",
|
55
55
|
"data" : editor.requestData(),
|
56
|
-
"success" : function(data){ editor.loadSuccessCallback(data) },
|
57
|
-
"error" : function(request, error){ editor.loadErrorCallback(request, error) }
|
58
|
-
})
|
56
|
+
"success" : function(data){ editor.loadSuccessCallback(data); },
|
57
|
+
"error" : function(request, error){ editor.loadErrorCallback(request, error); }
|
58
|
+
});
|
59
59
|
if (this.formType == "select") {
|
60
|
-
var value = this.getValue()
|
61
|
-
$.each(this.values, function(i, v) {
|
60
|
+
var value = this.getValue();
|
61
|
+
$.each(this.values, function(i, v) {
|
62
|
+
if (value == v[0]) {
|
63
|
+
editor.element.html(v[1]);
|
64
|
+
}
|
65
|
+
}
|
66
|
+
);
|
62
67
|
} else if (this.formType == "checkbox") {
|
63
|
-
editor.element.html(this.getValue() ? this.values[1] : this.values[0])
|
64
|
-
} else
|
68
|
+
editor.element.html(this.getValue() ? this.values[1] : this.values[0]);
|
69
|
+
} else {
|
70
|
+
editor.element.html(this.getValue());
|
71
|
+
}
|
65
72
|
},
|
66
73
|
|
67
74
|
activateForm : function() {
|
68
|
-
alert("The form was not properly initialized. activateForm is unbound")
|
75
|
+
alert("The form was not properly initialized. activateForm is unbound");
|
69
76
|
},
|
70
77
|
|
71
78
|
// Helper Functions ////////////////////////////////////////////////////////
|
72
79
|
|
73
80
|
initOptions : function() {
|
74
81
|
// Try parent supplied info
|
75
|
-
var self = this
|
82
|
+
var self = this;
|
76
83
|
self.element.parents().each(function(){
|
77
|
-
self.url = self.url || jQuery(this).attr("data-url")
|
78
|
-
self.collection = self.collection || jQuery(this).attr("data-collection")
|
79
|
-
self.formType = self.formType || jQuery(this).attr("data-type")
|
80
|
-
self.objectName = self.objectName || jQuery(this).attr("data-object")
|
81
|
-
self.attributeName = self.attributeName || jQuery(this).attr("data-attribute")
|
82
|
-
})
|
84
|
+
self.url = self.url || jQuery(this).attr("data-url");
|
85
|
+
self.collection = self.collection || jQuery(this).attr("data-collection");
|
86
|
+
self.formType = self.formType || jQuery(this).attr("data-type");
|
87
|
+
self.objectName = self.objectName || jQuery(this).attr("data-object");
|
88
|
+
self.attributeName = self.attributeName || jQuery(this).attr("data-attribute");
|
89
|
+
});
|
83
90
|
|
84
91
|
// Try Rails-id based if parents did not explicitly supply something
|
85
92
|
self.element.parents().each(function(){
|
86
|
-
var res
|
87
|
-
if (res
|
88
|
-
self.objectName = self.objectName || res[1]
|
93
|
+
var res = this.id.match(/^(\w+)_(\d+)$/i);
|
94
|
+
if (res) {
|
95
|
+
self.objectName = self.objectName || res[1];
|
89
96
|
}
|
90
|
-
})
|
97
|
+
});
|
91
98
|
|
92
99
|
// Load own attributes (overrides all others)
|
93
|
-
self.url = self.element.attr("data-url")
|
94
|
-
self.collection = self.element.attr("data-collection")
|
95
|
-
self.formType = self.element.attr("data-type")
|
96
|
-
self.objectName = self.element.attr("data-object")
|
97
|
-
self.attributeName = self.element.attr("data-attribute")
|
98
|
-
self.activator = self.element.attr("data-activator")
|
99
|
-
|
100
|
-
if (!self.element.attr("data-sanitize"))
|
101
|
-
|
102
|
-
|
100
|
+
self.url = self.element.attr("data-url") || self.url || document.location.pathname;
|
101
|
+
self.collection = self.element.attr("data-collection") || self.collection;
|
102
|
+
self.formType = self.element.attr("data-type") || self.formtype || "input";
|
103
|
+
self.objectName = self.element.attr("data-object") || self.objectName;
|
104
|
+
self.attributeName = self.element.attr("data-attribute") || self.attributeName;
|
105
|
+
self.activator = self.element.attr("data-activator") || self.element;
|
106
|
+
|
107
|
+
if (!self.element.attr("data-sanitize")) {
|
108
|
+
self.sanitize = true;
|
109
|
+
}
|
110
|
+
else {
|
111
|
+
self.sanitize = (self.element.attr("data-sanitize") == "true");
|
112
|
+
}
|
103
113
|
|
104
|
-
if ((self.formType == "select" || self.formType == "checkbox") && self.collection
|
114
|
+
if ((self.formType == "select" || self.formType == "checkbox") && self.collection !== null)
|
105
115
|
{
|
106
|
-
self.values = jQuery.parseJSON(self.collection)
|
116
|
+
self.values = jQuery.parseJSON(self.collection);
|
107
117
|
}
|
108
118
|
},
|
109
119
|
|
110
120
|
bindForm : function() {
|
111
|
-
this.activateForm = BestInPlaceEditor.forms[this.formType].activateForm
|
112
|
-
this.getValue = BestInPlaceEditor.forms[this.formType].getValue
|
121
|
+
this.activateForm = BestInPlaceEditor.forms[this.formType].activateForm;
|
122
|
+
this.getValue = BestInPlaceEditor.forms[this.formType].getValue;
|
113
123
|
},
|
114
124
|
|
115
125
|
getValue : function() {
|
116
|
-
alert("The form was not properly initialized. getValue is unbound")
|
126
|
+
alert("The form was not properly initialized. getValue is unbound");
|
117
127
|
},
|
118
128
|
|
119
129
|
// Trim and Strips HTML from text
|
120
130
|
sanitizeValue : function(s) {
|
121
131
|
if (this.sanitize)
|
122
132
|
{
|
123
|
-
var tmp = document.createElement("DIV")
|
124
|
-
tmp.innerHTML = s
|
125
|
-
s = tmp.textContent || tmp.innerText
|
133
|
+
var tmp = document.createElement("DIV");
|
134
|
+
tmp.innerHTML = s;
|
135
|
+
s = tmp.textContent || tmp.innerText;
|
126
136
|
}
|
127
|
-
return jQuery.trim(s)
|
137
|
+
return jQuery.trim(s);
|
128
138
|
},
|
129
139
|
|
130
140
|
/* Generate the data sent in the POST request */
|
131
141
|
requestData : function() {
|
132
|
-
//
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
142
|
+
// To prevent xss attacks, a csrf token must be defined as a meta attribute
|
143
|
+
csrf_token = $('meta[name=csrf-token]').attr('content');
|
144
|
+
csrf_param = $('meta[name=csrf-param]').attr('content');
|
145
|
+
|
146
|
+
var data = "_method=put";
|
147
|
+
data += "&" + this.objectName + '[' + this.attributeName + ']=' + encodeURIComponent(this.getValue());
|
148
|
+
|
149
|
+
if (csrf_param !== undefined && csrf_token !== undefined) {
|
150
|
+
data += "&" + csrf_param + "=" + encodeURIComponent(csrf_token);
|
151
|
+
}
|
152
|
+
return data;
|
139
153
|
},
|
140
154
|
|
141
155
|
ajax : function(options) {
|
142
|
-
options.url = this.url
|
143
|
-
options.beforeSend = function(xhr){ xhr.setRequestHeader("Accept", "application/json") }
|
144
|
-
return jQuery.ajax(options)
|
156
|
+
options.url = this.url;
|
157
|
+
options.beforeSend = function(xhr){ xhr.setRequestHeader("Accept", "application/json"); };
|
158
|
+
return jQuery.ajax(options);
|
145
159
|
},
|
146
160
|
|
147
161
|
// Handlers ////////////////////////////////////////////////////////////////
|
148
162
|
|
149
163
|
loadSuccessCallback : function(data) {
|
150
|
-
|
151
|
-
if (jQuery.fn.jquery < "1.4") data = eval('(' + data + ')' )
|
152
|
-
this.element.html(data[this.objectName])
|
153
|
-
|
164
|
+
this.element.html(data[this.objectName]);
|
154
165
|
// Binding back after being clicked
|
155
|
-
$(this.activator).bind('click', {editor: this}, this.clickHandler)
|
166
|
+
$(this.activator).bind('click', {editor: this}, this.clickHandler);
|
156
167
|
},
|
157
168
|
|
158
169
|
loadErrorCallback : function(request, error) {
|
159
|
-
this.element.html(this.oldValue)
|
170
|
+
this.element.html(this.oldValue);
|
160
171
|
|
161
172
|
// Display all error messages from server side validation
|
162
173
|
$.each(jQuery.parseJSON(request.responseText), function(index, value) {
|
163
|
-
var container = $("<span class='flash-error'></span>").html(value)
|
164
|
-
container.purr()
|
165
|
-
})
|
174
|
+
var container = $("<span class='flash-error'></span>").html(value);
|
175
|
+
container.purr();
|
176
|
+
});
|
166
177
|
|
167
178
|
// Binding back after being clicked
|
168
|
-
$(this.activator).bind('click', {editor: this}, this.clickHandler)
|
179
|
+
$(this.activator).bind('click', {editor: this}, this.clickHandler);
|
169
180
|
},
|
170
181
|
|
171
182
|
clickHandler : function(event) {
|
172
|
-
event.data.editor.activate()
|
183
|
+
event.data.editor.activate();
|
173
184
|
}
|
174
|
-
}
|
185
|
+
};
|
175
186
|
|
176
187
|
|
177
188
|
BestInPlaceEditor.forms = {
|
178
189
|
"input" : {
|
179
190
|
activateForm : function() {
|
180
|
-
var
|
181
|
-
this.
|
182
|
-
this.element.
|
183
|
-
this.element.find(
|
184
|
-
this.element.find("
|
185
|
-
this.element.find("input").bind('
|
191
|
+
var output = '<form class="form_in_place" action="javascript:void(0)" style="display:inline;">';
|
192
|
+
output += '<input type="text" value="' + this.sanitizeValue(this.oldValue) + '"></form>';
|
193
|
+
this.element.html(output);
|
194
|
+
this.element.find('input')[0].select();
|
195
|
+
this.element.find("form").bind('submit', {editor: this}, BestInPlaceEditor.forms.input.submitHandler);
|
196
|
+
this.element.find("input").bind('blur', {editor: this}, BestInPlaceEditor.forms.input.inputBlurHandler);
|
197
|
+
this.element.find("input").bind('keyup', {editor: this}, BestInPlaceEditor.forms.input.keyupHandler);
|
186
198
|
},
|
187
199
|
|
188
200
|
getValue : function() {
|
189
|
-
return this.sanitizeValue(this.element.find("input").val())
|
201
|
+
return this.sanitizeValue(this.element.find("input").val());
|
190
202
|
},
|
191
203
|
|
192
204
|
inputBlurHandler : function(event) {
|
193
|
-
event.data.editor.update()
|
205
|
+
event.data.editor.update();
|
194
206
|
},
|
195
207
|
|
196
208
|
submitHandler : function(event) {
|
197
|
-
event.data.editor.update()
|
209
|
+
event.data.editor.update();
|
198
210
|
},
|
199
211
|
|
200
212
|
keyupHandler : function(event) {
|
201
|
-
if (event.keyCode == 27)
|
213
|
+
if (event.keyCode == 27) {
|
214
|
+
event.data.editor.abort();
|
215
|
+
}
|
202
216
|
}
|
203
217
|
},
|
204
218
|
|
205
219
|
"select" : {
|
206
220
|
activateForm : function() {
|
207
|
-
var output = "<form action='javascript:void(0)' style='display:inline;'><select>"
|
208
|
-
var selected = ""
|
209
|
-
var oldValue = this.oldValue
|
221
|
+
var output = "<form action='javascript:void(0)' style='display:inline;'><select>";
|
222
|
+
var selected = "";
|
223
|
+
var oldValue = this.oldValue;
|
210
224
|
$.each(this.values, function(index, value) {
|
211
|
-
selected = (value[1] == oldValue ? "selected='selected'" : "")
|
212
|
-
output += "<option value='" + value[0] + "' " + selected + ">" + value[1] + "</option>"
|
213
|
-
})
|
214
|
-
output += "</select></form>"
|
215
|
-
this.element.html(output)
|
216
|
-
this.element.find("select").bind('change', {editor: this}, BestInPlaceEditor.forms.select.blurHandler)
|
225
|
+
selected = (value[1] == oldValue ? "selected='selected'" : "");
|
226
|
+
output += "<option value='" + value[0] + "' " + selected + ">" + value[1] + "</option>";
|
227
|
+
});
|
228
|
+
output += "</select></form>";
|
229
|
+
this.element.html(output);
|
230
|
+
this.element.find("select").bind('change', {editor: this}, BestInPlaceEditor.forms.select.blurHandler);
|
217
231
|
},
|
218
232
|
|
219
233
|
getValue : function() {
|
220
|
-
return this.sanitizeValue(this.element.find("select").val())
|
234
|
+
return this.sanitizeValue(this.element.find("select").val());
|
221
235
|
},
|
222
236
|
|
223
237
|
blurHandler : function(event) {
|
224
|
-
event.data.editor.update()
|
225
|
-
}
|
238
|
+
event.data.editor.update();
|
239
|
+
}
|
226
240
|
},
|
227
241
|
|
228
242
|
"checkbox" : {
|
229
243
|
activateForm : function() {
|
230
|
-
var newValue = Boolean(this.oldValue != this.values[1])
|
231
|
-
var output = newValue ? this.values[1] : this.values[0]
|
232
|
-
this.element.html(output)
|
233
|
-
this.update()
|
244
|
+
var newValue = Boolean(this.oldValue != this.values[1]);
|
245
|
+
var output = newValue ? this.values[1] : this.values[0];
|
246
|
+
this.element.html(output);
|
247
|
+
this.update();
|
234
248
|
},
|
235
249
|
|
236
250
|
getValue : function() {
|
237
|
-
return Boolean(this.element.html() == this.values[1])
|
251
|
+
return Boolean(this.element.html() == this.values[1]);
|
238
252
|
}
|
239
253
|
},
|
240
254
|
|
241
255
|
"textarea" : {
|
242
256
|
activateForm : function() {
|
243
|
-
|
244
|
-
this.
|
245
|
-
|
246
|
-
this.element.
|
257
|
+
var output = '<form action="javascript:void(0)" style="display:inline;"><textarea>';
|
258
|
+
output += this.sanitizeValue(this.oldValue);
|
259
|
+
output += '</textarea></form>';
|
260
|
+
this.element.html(output);
|
261
|
+
this.element.find('textarea')[0].select();
|
262
|
+
this.element.find("textarea").bind('blur', {editor: this}, BestInPlaceEditor.forms.textarea.blurHandler);
|
263
|
+
this.element.find("textarea").bind('keyup', {editor: this}, BestInPlaceEditor.forms.textarea.keyupHandler);
|
247
264
|
},
|
248
265
|
|
249
266
|
getValue : function() {
|
250
|
-
return this.sanitizeValue(this.element.find("textarea").val())
|
267
|
+
return this.sanitizeValue(this.element.find("textarea").val());
|
251
268
|
},
|
252
269
|
|
253
270
|
blurHandler : function(event) {
|
254
|
-
event.data.editor.update()
|
271
|
+
event.data.editor.update();
|
255
272
|
},
|
256
273
|
|
257
274
|
keyupHandler : function(event) {
|
258
|
-
if (event.keyCode == 27)
|
275
|
+
if (event.keyCode == 27) {
|
276
|
+
event.data.editor.abort();
|
277
|
+
}
|
259
278
|
}
|
260
|
-
|
261
279
|
}
|
262
|
-
}
|
280
|
+
};
|
263
281
|
|
264
282
|
jQuery.fn.best_in_place = function() {
|
265
283
|
this.each(function(){
|
266
|
-
jQuery(this).data('bestInPlaceEditor', new BestInPlaceEditor(this))
|
267
|
-
})
|
268
|
-
return this
|
269
|
-
}
|
284
|
+
jQuery(this).data('bestInPlaceEditor', new BestInPlaceEditor(this));
|
285
|
+
});
|
286
|
+
return this;
|
287
|
+
};
|
@@ -1,133 +1,148 @@
|
|
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
|
-
|
1
|
+
/**
|
2
|
+
* Unobtrusive scripting adapter for jQuery
|
3
|
+
*
|
4
|
+
* Requires jQuery 1.4.3 or later.
|
5
|
+
* https://github.com/rails/jquery-ujs
|
6
|
+
*/
|
7
|
+
|
8
|
+
(function($) {
|
9
|
+
// Triggers an event on an element and returns the event result
|
10
|
+
function fire(obj, name, data) {
|
11
|
+
var event = new $.Event(name);
|
12
|
+
obj.trigger(event, data);
|
13
|
+
return event.result !== false;
|
14
|
+
}
|
15
|
+
|
16
|
+
// Submits "remote" forms and links with ajax
|
17
|
+
function handleRemote(element) {
|
18
|
+
var method, url, data,
|
19
|
+
dataType = element.attr('data-type') || ($.ajaxSettings && $.ajaxSettings.dataType);
|
20
|
+
|
21
|
+
if (element.is('form')) {
|
22
|
+
method = element.attr('method');
|
23
|
+
url = element.attr('action');
|
24
|
+
data = element.serializeArray();
|
25
|
+
// memoized value from clicked submit button
|
26
|
+
var button = element.data('ujs:submit-button');
|
27
|
+
if (button) {
|
28
|
+
data.push(button);
|
29
|
+
element.data('ujs:submit-button', null);
|
30
|
+
}
|
31
|
+
} else {
|
32
|
+
method = element.attr('data-method');
|
33
|
+
url = element.attr('href');
|
34
|
+
data = null;
|
35
|
+
}
|
36
|
+
|
37
|
+
$.ajax({
|
38
|
+
url: url, type: method || 'GET', data: data, dataType: dataType,
|
39
|
+
// stopping the "ajax:beforeSend" event will cancel the ajax request
|
40
|
+
beforeSend: function(xhr, settings) {
|
41
|
+
if (settings.dataType === undefined) {
|
42
|
+
xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
|
43
|
+
}
|
44
|
+
return fire(element, 'ajax:beforeSend', [xhr, settings]);
|
45
|
+
},
|
46
|
+
success: function(data, status, xhr) {
|
47
|
+
element.trigger('ajax:success', [data, status, xhr]);
|
48
|
+
},
|
49
|
+
complete: function(xhr, status) {
|
50
|
+
element.trigger('ajax:complete', [xhr, status]);
|
51
|
+
},
|
52
|
+
error: function(xhr, status, error) {
|
53
|
+
element.trigger('ajax:error', [xhr, status, error]);
|
54
|
+
}
|
55
|
+
});
|
56
|
+
}
|
57
|
+
|
58
|
+
// Handles "data-method" on links such as:
|
59
|
+
// <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
|
60
|
+
function handleMethod(link) {
|
61
|
+
var href = link.attr('href'),
|
62
|
+
method = link.attr('data-method'),
|
63
|
+
csrf_token = $('meta[name=csrf-token]').attr('content'),
|
64
|
+
csrf_param = $('meta[name=csrf-param]').attr('content'),
|
65
|
+
form = $('<form method="post" action="' + href + '"></form>'),
|
66
|
+
metadata_input = '<input name="_method" value="' + method + '" type="hidden" />';
|
67
|
+
|
68
|
+
if (csrf_param !== undefined && csrf_token !== undefined) {
|
69
|
+
metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />';
|
70
|
+
}
|
71
|
+
|
72
|
+
form.hide().append(metadata_input).appendTo('body');
|
73
|
+
form.submit();
|
74
|
+
}
|
75
|
+
|
76
|
+
function disableFormElements(form) {
|
77
|
+
form.find('input[data-disable-with]').each(function() {
|
78
|
+
var input = $(this);
|
79
|
+
input.data('ujs:enable-with', input.val())
|
80
|
+
.val(input.attr('data-disable-with'))
|
81
|
+
.attr('disabled', 'disabled');
|
82
|
+
});
|
83
|
+
}
|
84
|
+
|
85
|
+
function enableFormElements(form) {
|
86
|
+
form.find('input[data-disable-with]').each(function() {
|
87
|
+
var input = $(this);
|
88
|
+
input.val(input.data('ujs:enable-with')).removeAttr('disabled');
|
89
|
+
});
|
90
|
+
}
|
91
|
+
|
92
|
+
function allowAction(element) {
|
93
|
+
var message = element.attr('data-confirm');
|
94
|
+
return !message || (fire(element, 'confirm') && confirm(message));
|
95
|
+
}
|
96
|
+
|
97
|
+
function requiredValuesMissing(form) {
|
98
|
+
var missing = false;
|
99
|
+
form.find('input[name][required]').each(function() {
|
100
|
+
if (!$(this).val()) missing = true;
|
101
|
+
});
|
102
|
+
return missing;
|
103
|
+
}
|
104
|
+
|
105
|
+
$('a[data-confirm], a[data-method], a[data-remote]').live('click.rails', function(e) {
|
106
|
+
var link = $(this);
|
107
|
+
if (!allowAction(link)) return false;
|
108
|
+
|
109
|
+
if (link.attr('data-remote') != undefined) {
|
110
|
+
handleRemote(link);
|
111
|
+
return false;
|
112
|
+
} else if (link.attr('data-method')) {
|
113
|
+
handleMethod(link);
|
114
|
+
return false;
|
115
|
+
}
|
116
|
+
});
|
117
|
+
|
118
|
+
$('form').live('submit.rails', function(e) {
|
119
|
+
var form = $(this), remote = form.attr('data-remote') != undefined;
|
120
|
+
if (!allowAction(form)) return false;
|
121
|
+
|
122
|
+
// skip other logic when required values are missing
|
123
|
+
if (requiredValuesMissing(form)) return !remote;
|
124
|
+
|
125
|
+
if (remote) {
|
126
|
+
handleRemote(form);
|
127
|
+
return false;
|
128
|
+
} else {
|
129
|
+
disableFormElements(form);
|
130
|
+
}
|
131
|
+
});
|
132
|
+
|
133
|
+
$('form input[type=submit], form button[type=submit], form button:not([type])').live('click.rails', function() {
|
134
|
+
var button = $(this);
|
135
|
+
if (!allowAction(button)) return false;
|
136
|
+
// register the pressed submit button
|
137
|
+
var name = button.attr('name'), data = name ? {name:name, value:button.val()} : null;
|
138
|
+
button.closest('form').data('ujs:submit-button', data);
|
139
|
+
});
|
140
|
+
|
141
|
+
$('form').live('ajax:beforeSend.rails', function(event) {
|
142
|
+
if (this == event.target) disableFormElements($(this));
|
143
|
+
});
|
144
|
+
|
145
|
+
$('form').live('ajax:complete.rails', function(event) {
|
146
|
+
if (this == event.target) enableFormElements($(this));
|
147
|
+
});
|
148
|
+
})( jQuery );
|