effective_datatables 2.6.19 → 2.6.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/effective_datatables.js +1 -0
- data/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee +31 -13
- data/app/assets/javascripts/vendor/jquery.fileDownload.js +493 -0
- data/app/models/effective/effective_datatable/dsl/bulk_actions.rb +4 -0
- data/lib/effective_datatables/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46fe407f06c151568668a2aa211c442393d9ecf8
|
4
|
+
data.tar.gz: 460205e93e92b89fec4827914b9c393de5d589dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3b1d6bcc145535b55e1428f1c75a23f78f0ac6d0570cddd429efbedab459d611df8d98a45326ffab54d76817d93e1d3c18ce1001bb4d6fedb4110200e5b5015
|
7
|
+
data.tar.gz: 83da2377c96fe023f26b77e28186767a4de926e16b80a03903ec1451c21648f497de8ef7f2db52bc3977c5ee39986a7a13c64cd8c58ae31765b85b3d08cc675b
|
@@ -39,6 +39,7 @@ $(document).on 'click', '.buttons-bulk-actions a', (event) ->
|
|
39
39
|
url = $bulkAction.attr('href')
|
40
40
|
title = $bulkAction.text()
|
41
41
|
values = $.map($selected, (input) -> input.getAttribute('value'))
|
42
|
+
token = $bulkAction.parent('li').data('authenticity-token')
|
42
43
|
|
43
44
|
return unless url && values
|
44
45
|
|
@@ -48,16 +49,33 @@ $(document).on 'click', '.buttons-bulk-actions a', (event) ->
|
|
48
49
|
# Show Processing...
|
49
50
|
$processing.show().data('bulk-actions-processing', true)
|
50
51
|
|
51
|
-
|
52
|
-
url,
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
52
|
+
if token # This is a file download
|
53
|
+
$.fileDownload(url,
|
54
|
+
httpMethod: 'POST',
|
55
|
+
data: { ids: values, authenticity_token: token }
|
56
|
+
successCallback: ->
|
57
|
+
success = "Successfully completed #{title} bulk action"
|
58
|
+
$processing.html(success)
|
59
|
+
$table.dataTable().data('bulk-actions-restore-selected-values', values)
|
60
|
+
$table.DataTable().draw()
|
61
|
+
failCallback: ->
|
62
|
+
error = "An error occured while attempting #{title} bulk action"
|
63
|
+
$processing.html(error)
|
64
|
+
alert(error)
|
65
|
+
$table.dataTable().data('bulk-actions-restore-selected-values', values)
|
66
|
+
$table.DataTable().draw()
|
67
|
+
)
|
68
|
+
else # Normal AJAX post
|
69
|
+
$.post(
|
70
|
+
url, { ids: values }
|
71
|
+
).done((response) ->
|
72
|
+
success = response['message'] || "Successfully completed #{title} bulk action"
|
73
|
+
$processing.html(success)
|
74
|
+
).fail((response) ->
|
75
|
+
error = response['message'] || "An error occured while attempting #{title} bulk action: #{response.statusText}"
|
76
|
+
$processing.html(error)
|
77
|
+
alert(error)
|
78
|
+
).always((response) ->
|
79
|
+
$table.dataTable().data('bulk-actions-restore-selected-values', values)
|
80
|
+
$table.DataTable().draw()
|
81
|
+
)
|
@@ -0,0 +1,493 @@
|
|
1
|
+
/*
|
2
|
+
* jQuery File Download Plugin v1.4.5
|
3
|
+
*
|
4
|
+
* http://www.johnculviner.com
|
5
|
+
*
|
6
|
+
* Copyright (c) 2013 - John Culviner
|
7
|
+
*
|
8
|
+
* Licensed under the MIT license:
|
9
|
+
* http://www.opensource.org/licenses/mit-license.php
|
10
|
+
*
|
11
|
+
* !!!!NOTE!!!!
|
12
|
+
* You must also write a cookie in conjunction with using this plugin as mentioned in the orignal post:
|
13
|
+
* http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/
|
14
|
+
* !!!!NOTE!!!!
|
15
|
+
*/
|
16
|
+
|
17
|
+
(function($, window){
|
18
|
+
// i'll just put them here to get evaluated on script load
|
19
|
+
var htmlSpecialCharsRegEx = /[<>&\r\n"']/gm;
|
20
|
+
var htmlSpecialCharsPlaceHolders = {
|
21
|
+
'<': 'lt;',
|
22
|
+
'>': 'gt;',
|
23
|
+
'&': 'amp;',
|
24
|
+
'\r': "#13;",
|
25
|
+
'\n': "#10;",
|
26
|
+
'"': 'quot;',
|
27
|
+
"'": '#39;' /*single quotes just to be safe, IE8 doesn't support ', so use ' instead */
|
28
|
+
};
|
29
|
+
|
30
|
+
$.extend({
|
31
|
+
//
|
32
|
+
//$.fileDownload('/path/to/url/', options)
|
33
|
+
// see directly below for possible 'options'
|
34
|
+
fileDownload: function (fileUrl, options) {
|
35
|
+
|
36
|
+
//provide some reasonable defaults to any unspecified options below
|
37
|
+
var settings = $.extend({
|
38
|
+
|
39
|
+
//
|
40
|
+
//Requires jQuery UI: provide a message to display to the user when the file download is being prepared before the browser's dialog appears
|
41
|
+
//
|
42
|
+
preparingMessageHtml: null,
|
43
|
+
|
44
|
+
//
|
45
|
+
//Requires jQuery UI: provide a message to display to the user when a file download fails
|
46
|
+
//
|
47
|
+
failMessageHtml: null,
|
48
|
+
|
49
|
+
//
|
50
|
+
//the stock android browser straight up doesn't support file downloads initiated by a non GET: http://code.google.com/p/android/issues/detail?id=1780
|
51
|
+
//specify a message here to display if a user tries with an android browser
|
52
|
+
//if jQuery UI is installed this will be a dialog, otherwise it will be an alert
|
53
|
+
//Set to null to disable the message and attempt to download anyway
|
54
|
+
//
|
55
|
+
androidPostUnsupportedMessageHtml: "Unfortunately your Android browser doesn't support this type of file download. Please try again with a different browser.",
|
56
|
+
|
57
|
+
//
|
58
|
+
//Requires jQuery UI: options to pass into jQuery UI Dialog
|
59
|
+
//
|
60
|
+
dialogOptions: { modal: true },
|
61
|
+
|
62
|
+
//
|
63
|
+
//a function to call while the dowload is being prepared before the browser's dialog appears
|
64
|
+
//Args:
|
65
|
+
// url - the original url attempted
|
66
|
+
//
|
67
|
+
prepareCallback: function (url) { },
|
68
|
+
|
69
|
+
//
|
70
|
+
//a function to call after a file download successfully completed
|
71
|
+
//Args:
|
72
|
+
// url - the original url attempted
|
73
|
+
//
|
74
|
+
successCallback: function (url) { },
|
75
|
+
|
76
|
+
//
|
77
|
+
//a function to call after a file download request was canceled
|
78
|
+
//Args:
|
79
|
+
// url - the original url attempted
|
80
|
+
//
|
81
|
+
abortCallback: function (url) { },
|
82
|
+
|
83
|
+
//
|
84
|
+
//a function to call after a file download failed
|
85
|
+
//Args:
|
86
|
+
// responseHtml - the html that came back in response to the file download. this won't necessarily come back depending on the browser.
|
87
|
+
// in less than IE9 a cross domain error occurs because 500+ errors cause a cross domain issue due to IE subbing out the
|
88
|
+
// server's error message with a "helpful" IE built in message
|
89
|
+
// url - the original url attempted
|
90
|
+
// error - original error cautch from exception
|
91
|
+
//
|
92
|
+
failCallback: function (responseHtml, url, error) { },
|
93
|
+
|
94
|
+
//
|
95
|
+
// the HTTP method to use. Defaults to "GET".
|
96
|
+
//
|
97
|
+
httpMethod: "GET",
|
98
|
+
|
99
|
+
//
|
100
|
+
// if specified will perform a "httpMethod" request to the specified 'fileUrl' using the specified data.
|
101
|
+
// data must be an object (which will be $.param serialized) or already a key=value param string
|
102
|
+
//
|
103
|
+
data: null,
|
104
|
+
|
105
|
+
//
|
106
|
+
//a period in milliseconds to poll to determine if a successful file download has occured or not
|
107
|
+
//
|
108
|
+
checkInterval: 100,
|
109
|
+
|
110
|
+
//
|
111
|
+
//the cookie name to indicate if a file download has occured
|
112
|
+
//
|
113
|
+
cookieName: "fileDownload",
|
114
|
+
|
115
|
+
//
|
116
|
+
//the cookie value for the above name to indicate that a file download has occured
|
117
|
+
//
|
118
|
+
cookieValue: "true",
|
119
|
+
|
120
|
+
//
|
121
|
+
//the cookie path for above name value pair
|
122
|
+
//
|
123
|
+
cookiePath: "/",
|
124
|
+
|
125
|
+
//
|
126
|
+
//if specified it will be used when attempting to clear the above name value pair
|
127
|
+
//useful for when downloads are being served on a subdomain (e.g. downloads.example.com)
|
128
|
+
//
|
129
|
+
cookieDomain: null,
|
130
|
+
|
131
|
+
//
|
132
|
+
//the title for the popup second window as a download is processing in the case of a mobile browser
|
133
|
+
//
|
134
|
+
popupWindowTitle: "Initiating file download...",
|
135
|
+
|
136
|
+
//
|
137
|
+
//Functionality to encode HTML entities for a POST, need this if data is an object with properties whose values contains strings with quotation marks.
|
138
|
+
//HTML entity encoding is done by replacing all &,<,>,',",\r,\n characters.
|
139
|
+
//Note that some browsers will POST the string htmlentity-encoded whilst others will decode it before POSTing.
|
140
|
+
//It is recommended that on the server, htmlentity decoding is done irrespective.
|
141
|
+
//
|
142
|
+
encodeHTMLEntities: true
|
143
|
+
|
144
|
+
}, options);
|
145
|
+
|
146
|
+
var deferred = new $.Deferred();
|
147
|
+
|
148
|
+
//Setup mobile browser detection: Partial credit: http://detectmobilebrowser.com/
|
149
|
+
var userAgent = (navigator.userAgent || navigator.vendor || window.opera).toLowerCase();
|
150
|
+
|
151
|
+
var isIos; //has full support of features in iOS 4.0+, uses a new window to accomplish this.
|
152
|
+
var isAndroid; //has full support of GET features in 4.0+ by using a new window. Non-GET is completely unsupported by the browser. See above for specifying a message.
|
153
|
+
var isOtherMobileBrowser; //there is no way to reliably guess here so all other mobile devices will GET and POST to the current window.
|
154
|
+
|
155
|
+
if (/ip(ad|hone|od)/.test(userAgent)) {
|
156
|
+
|
157
|
+
isIos = true;
|
158
|
+
|
159
|
+
} else if (userAgent.indexOf('android') !== -1) {
|
160
|
+
|
161
|
+
isAndroid = true;
|
162
|
+
|
163
|
+
} else {
|
164
|
+
|
165
|
+
isOtherMobileBrowser = /avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|playbook|silk|iemobile|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i.test(userAgent.substr(0, 4));
|
166
|
+
|
167
|
+
}
|
168
|
+
|
169
|
+
var httpMethodUpper = settings.httpMethod.toUpperCase();
|
170
|
+
|
171
|
+
if (isAndroid && httpMethodUpper !== "GET" && settings.androidPostUnsupportedMessageHtml) {
|
172
|
+
//the stock android browser straight up doesn't support file downloads initiated by non GET requests: http://code.google.com/p/android/issues/detail?id=1780
|
173
|
+
|
174
|
+
if ($().dialog) {
|
175
|
+
$("<div>").html(settings.androidPostUnsupportedMessageHtml).dialog(settings.dialogOptions);
|
176
|
+
} else {
|
177
|
+
alert(settings.androidPostUnsupportedMessageHtml);
|
178
|
+
}
|
179
|
+
|
180
|
+
return deferred.reject();
|
181
|
+
}
|
182
|
+
|
183
|
+
var $preparingDialog = null;
|
184
|
+
|
185
|
+
var internalCallbacks = {
|
186
|
+
|
187
|
+
onPrepare: function (url) {
|
188
|
+
|
189
|
+
//wire up a jquery dialog to display the preparing message if specified
|
190
|
+
if (settings.preparingMessageHtml) {
|
191
|
+
|
192
|
+
$preparingDialog = $("<div>").html(settings.preparingMessageHtml).dialog(settings.dialogOptions);
|
193
|
+
|
194
|
+
} else if (settings.prepareCallback) {
|
195
|
+
|
196
|
+
settings.prepareCallback(url);
|
197
|
+
|
198
|
+
}
|
199
|
+
|
200
|
+
},
|
201
|
+
|
202
|
+
onSuccess: function (url) {
|
203
|
+
|
204
|
+
//remove the perparing message if it was specified
|
205
|
+
if ($preparingDialog) {
|
206
|
+
$preparingDialog.dialog('close');
|
207
|
+
}
|
208
|
+
|
209
|
+
settings.successCallback(url);
|
210
|
+
|
211
|
+
deferred.resolve(url);
|
212
|
+
},
|
213
|
+
|
214
|
+
onAbort: function (url) {
|
215
|
+
|
216
|
+
//remove the perparing message if it was specified
|
217
|
+
if ($preparingDialog) {
|
218
|
+
$preparingDialog.dialog('close');
|
219
|
+
};
|
220
|
+
|
221
|
+
settings.abortCallback(url);
|
222
|
+
|
223
|
+
deferred.reject(url);
|
224
|
+
},
|
225
|
+
|
226
|
+
onFail: function (responseHtml, url, error) {
|
227
|
+
|
228
|
+
//remove the perparing message if it was specified
|
229
|
+
if ($preparingDialog) {
|
230
|
+
$preparingDialog.dialog('close');
|
231
|
+
}
|
232
|
+
|
233
|
+
//wire up a jquery dialog to display the fail message if specified
|
234
|
+
if (settings.failMessageHtml) {
|
235
|
+
$("<div>").html(settings.failMessageHtml).dialog(settings.dialogOptions);
|
236
|
+
}
|
237
|
+
|
238
|
+
settings.failCallback(responseHtml, url, error);
|
239
|
+
|
240
|
+
deferred.reject(responseHtml, url);
|
241
|
+
}
|
242
|
+
};
|
243
|
+
|
244
|
+
internalCallbacks.onPrepare(fileUrl);
|
245
|
+
|
246
|
+
//make settings.data a param string if it exists and isn't already
|
247
|
+
if (settings.data !== null && typeof settings.data !== "string") {
|
248
|
+
settings.data = $.param(settings.data);
|
249
|
+
}
|
250
|
+
|
251
|
+
|
252
|
+
var $iframe,
|
253
|
+
downloadWindow,
|
254
|
+
formDoc,
|
255
|
+
$form;
|
256
|
+
|
257
|
+
if (httpMethodUpper === "GET") {
|
258
|
+
|
259
|
+
if (settings.data !== null) {
|
260
|
+
//need to merge any fileUrl params with the data object
|
261
|
+
|
262
|
+
var qsStart = fileUrl.indexOf('?');
|
263
|
+
|
264
|
+
if (qsStart !== -1) {
|
265
|
+
//we have a querystring in the url
|
266
|
+
|
267
|
+
if (fileUrl.substring(fileUrl.length - 1) !== "&") {
|
268
|
+
fileUrl = fileUrl + "&";
|
269
|
+
}
|
270
|
+
} else {
|
271
|
+
|
272
|
+
fileUrl = fileUrl + "?";
|
273
|
+
}
|
274
|
+
|
275
|
+
fileUrl = fileUrl + settings.data;
|
276
|
+
}
|
277
|
+
|
278
|
+
if (isIos || isAndroid) {
|
279
|
+
|
280
|
+
downloadWindow = window.open(fileUrl);
|
281
|
+
downloadWindow.document.title = settings.popupWindowTitle;
|
282
|
+
window.focus();
|
283
|
+
|
284
|
+
} else if (isOtherMobileBrowser) {
|
285
|
+
|
286
|
+
window.location(fileUrl);
|
287
|
+
|
288
|
+
} else {
|
289
|
+
|
290
|
+
//create a temporary iframe that is used to request the fileUrl as a GET request
|
291
|
+
$iframe = $("<iframe>")
|
292
|
+
.hide()
|
293
|
+
.prop("src", fileUrl)
|
294
|
+
.appendTo("body");
|
295
|
+
}
|
296
|
+
|
297
|
+
} else {
|
298
|
+
|
299
|
+
var formInnerHtml = "";
|
300
|
+
|
301
|
+
if (settings.data !== null) {
|
302
|
+
|
303
|
+
$.each(settings.data.replace(/\+/g, ' ').split("&"), function () {
|
304
|
+
|
305
|
+
var kvp = this.split("=");
|
306
|
+
|
307
|
+
//Issue: When value contains sign '=' then the kvp array does have more than 2 items. We have to join value back
|
308
|
+
var k = kvp[0];
|
309
|
+
kvp.shift();
|
310
|
+
var v = kvp.join("=");
|
311
|
+
kvp = [k, v];
|
312
|
+
|
313
|
+
var key = settings.encodeHTMLEntities ? htmlSpecialCharsEntityEncode(decodeURIComponent(kvp[0])) : decodeURIComponent(kvp[0]);
|
314
|
+
if (key) {
|
315
|
+
var value = settings.encodeHTMLEntities ? htmlSpecialCharsEntityEncode(decodeURIComponent(kvp[1])) : decodeURIComponent(kvp[1]);
|
316
|
+
formInnerHtml += '<input type="hidden" name="' + key + '" value="' + value + '" />';
|
317
|
+
}
|
318
|
+
});
|
319
|
+
}
|
320
|
+
|
321
|
+
if (isOtherMobileBrowser) {
|
322
|
+
|
323
|
+
$form = $("<form>").appendTo("body");
|
324
|
+
$form.hide()
|
325
|
+
.prop('method', settings.httpMethod)
|
326
|
+
.prop('action', fileUrl)
|
327
|
+
.html(formInnerHtml);
|
328
|
+
|
329
|
+
} else {
|
330
|
+
|
331
|
+
if (isIos) {
|
332
|
+
|
333
|
+
downloadWindow = window.open("about:blank");
|
334
|
+
downloadWindow.document.title = settings.popupWindowTitle;
|
335
|
+
formDoc = downloadWindow.document;
|
336
|
+
window.focus();
|
337
|
+
|
338
|
+
} else {
|
339
|
+
|
340
|
+
$iframe = $("<iframe style='display: none' src='about:blank'></iframe>").appendTo("body");
|
341
|
+
formDoc = getiframeDocument($iframe);
|
342
|
+
}
|
343
|
+
|
344
|
+
formDoc.write("<html><head></head><body><form method='" + settings.httpMethod + "' action='" + fileUrl + "'>" + formInnerHtml + "</form>" + settings.popupWindowTitle + "</body></html>");
|
345
|
+
$form = $(formDoc).find('form');
|
346
|
+
}
|
347
|
+
|
348
|
+
$form.submit();
|
349
|
+
}
|
350
|
+
|
351
|
+
|
352
|
+
//check if the file download has completed every checkInterval ms
|
353
|
+
setTimeout(checkFileDownloadComplete, settings.checkInterval);
|
354
|
+
|
355
|
+
|
356
|
+
function checkFileDownloadComplete() {
|
357
|
+
//has the cookie been written due to a file download occuring?
|
358
|
+
|
359
|
+
var cookieValue = settings.cookieValue;
|
360
|
+
if(typeof cookieValue == 'string') {
|
361
|
+
cookieValue = cookieValue.toLowerCase();
|
362
|
+
}
|
363
|
+
|
364
|
+
var lowerCaseCookie = settings.cookieName.toLowerCase() + "=" + cookieValue;
|
365
|
+
|
366
|
+
if (document.cookie.toLowerCase().indexOf(lowerCaseCookie) > -1) {
|
367
|
+
|
368
|
+
//execute specified callback
|
369
|
+
internalCallbacks.onSuccess(fileUrl);
|
370
|
+
|
371
|
+
//remove cookie
|
372
|
+
var cookieData = settings.cookieName + "=; path=" + settings.cookiePath + "; expires=" + new Date(0).toUTCString() + ";";
|
373
|
+
if (settings.cookieDomain) cookieData += " domain=" + settings.cookieDomain + ";";
|
374
|
+
document.cookie = cookieData;
|
375
|
+
|
376
|
+
//remove iframe
|
377
|
+
cleanUp(false);
|
378
|
+
|
379
|
+
return;
|
380
|
+
}
|
381
|
+
|
382
|
+
//has an error occured?
|
383
|
+
//if neither containers exist below then the file download is occuring on the current window
|
384
|
+
if (downloadWindow || $iframe) {
|
385
|
+
|
386
|
+
//has an error occured?
|
387
|
+
try {
|
388
|
+
|
389
|
+
var formDoc = downloadWindow ? downloadWindow.document : getiframeDocument($iframe);
|
390
|
+
|
391
|
+
if (formDoc && formDoc.body !== null && formDoc.body.innerHTML.length) {
|
392
|
+
|
393
|
+
var isFailure = true;
|
394
|
+
|
395
|
+
if ($form && $form.length) {
|
396
|
+
var $contents = $(formDoc.body).contents().first();
|
397
|
+
|
398
|
+
try {
|
399
|
+
if ($contents.length && $contents[0] === $form[0]) {
|
400
|
+
isFailure = false;
|
401
|
+
}
|
402
|
+
} catch (e) {
|
403
|
+
if (e && e.number == -2146828218) {
|
404
|
+
// IE 8-10 throw a permission denied after the form reloads on the "$contents[0] === $form[0]" comparison
|
405
|
+
isFailure = true;
|
406
|
+
} else {
|
407
|
+
throw e;
|
408
|
+
}
|
409
|
+
}
|
410
|
+
}
|
411
|
+
|
412
|
+
if (isFailure) {
|
413
|
+
// IE 8-10 don't always have the full content available right away, they need a litle bit to finish
|
414
|
+
setTimeout(function () {
|
415
|
+
internalCallbacks.onFail(formDoc.body.innerHTML, fileUrl);
|
416
|
+
cleanUp(true);
|
417
|
+
}, 100);
|
418
|
+
|
419
|
+
return;
|
420
|
+
}
|
421
|
+
}
|
422
|
+
}
|
423
|
+
catch (err) {
|
424
|
+
|
425
|
+
//500 error less than IE9
|
426
|
+
internalCallbacks.onFail('', fileUrl, err);
|
427
|
+
|
428
|
+
cleanUp(true);
|
429
|
+
|
430
|
+
return;
|
431
|
+
}
|
432
|
+
}
|
433
|
+
|
434
|
+
|
435
|
+
//keep checking...
|
436
|
+
setTimeout(checkFileDownloadComplete, settings.checkInterval);
|
437
|
+
}
|
438
|
+
|
439
|
+
//gets an iframes document in a cross browser compatible manner
|
440
|
+
function getiframeDocument($iframe) {
|
441
|
+
var iframeDoc = $iframe[0].contentWindow || $iframe[0].contentDocument;
|
442
|
+
if (iframeDoc.document) {
|
443
|
+
iframeDoc = iframeDoc.document;
|
444
|
+
}
|
445
|
+
return iframeDoc;
|
446
|
+
}
|
447
|
+
|
448
|
+
function cleanUp(isFailure) {
|
449
|
+
|
450
|
+
setTimeout(function() {
|
451
|
+
|
452
|
+
if (downloadWindow) {
|
453
|
+
|
454
|
+
if (isAndroid) {
|
455
|
+
downloadWindow.close();
|
456
|
+
}
|
457
|
+
|
458
|
+
if (isIos) {
|
459
|
+
if (downloadWindow.focus) {
|
460
|
+
downloadWindow.focus(); //ios safari bug doesn't allow a window to be closed unless it is focused
|
461
|
+
if (isFailure) {
|
462
|
+
downloadWindow.close();
|
463
|
+
}
|
464
|
+
}
|
465
|
+
}
|
466
|
+
}
|
467
|
+
|
468
|
+
//iframe cleanup appears to randomly cause the download to fail
|
469
|
+
//not doing it seems better than failure...
|
470
|
+
//if ($iframe) {
|
471
|
+
// $iframe.remove();
|
472
|
+
//}
|
473
|
+
|
474
|
+
}, 0);
|
475
|
+
}
|
476
|
+
|
477
|
+
|
478
|
+
function htmlSpecialCharsEntityEncode(str) {
|
479
|
+
return str.replace(htmlSpecialCharsRegEx, function(match) {
|
480
|
+
return '&' + htmlSpecialCharsPlaceHolders[match];
|
481
|
+
});
|
482
|
+
}
|
483
|
+
var promise = deferred.promise();
|
484
|
+
promise.abort = function() {
|
485
|
+
cleanUp();
|
486
|
+
$iframe.attr('src', '').html('');
|
487
|
+
internalCallbacks.onAbort(fileUrl);
|
488
|
+
};
|
489
|
+
return promise;
|
490
|
+
}
|
491
|
+
});
|
492
|
+
|
493
|
+
})(jQuery, this || window);
|
@@ -8,6 +8,10 @@ module Effective
|
|
8
8
|
concat content_tag(:li, link_to(*args))
|
9
9
|
end
|
10
10
|
|
11
|
+
def bulk_download(*args)
|
12
|
+
concat content_tag(:li, link_to(*args), 'data-authenticity-token' => form_authenticity_token)
|
13
|
+
end
|
14
|
+
|
11
15
|
def bulk_action_divider
|
12
16
|
concat content_tag(:li, '', class: 'divider', role: 'separator')
|
13
17
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_datatables
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.6.
|
4
|
+
version: 2.6.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -127,6 +127,7 @@ files:
|
|
127
127
|
- app/assets/javascripts/effective_datatables/responsive.js.coffee
|
128
128
|
- app/assets/javascripts/effective_datatables/scopes.js.coffee
|
129
129
|
- app/assets/javascripts/vendor/jquery.delayedChange.js
|
130
|
+
- app/assets/javascripts/vendor/jquery.fileDownload.js
|
130
131
|
- app/assets/stylesheets/dataTables/buttons/buttons.bootstrap.css
|
131
132
|
- app/assets/stylesheets/dataTables/colReorder/colReorder.bootstrap.css
|
132
133
|
- app/assets/stylesheets/dataTables/dataTables.bootstrap.css
|