effective_datatables 2.1.20 → 2.2.0
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/README.md +1 -11
- data/app/assets/javascripts/dataTables/buttons/buttons.bootstrap.js +68 -0
- data/app/assets/javascripts/dataTables/buttons/buttons.colVis.js +197 -0
- data/app/assets/javascripts/dataTables/buttons/buttons.html5.js +828 -0
- data/app/assets/javascripts/dataTables/buttons/buttons.print.js +159 -0
- data/app/assets/javascripts/dataTables/buttons/dataTables.buttons.js +1607 -0
- data/app/assets/javascripts/dataTables/dataTables.colReorder.min.js +24 -24
- data/app/assets/javascripts/dataTables/{bootstrap/3/jquery.dataTables.bootstrap.js → jquery.dataTables.bootstrap.js} +69 -34
- data/app/assets/javascripts/dataTables/jquery.dataTables.min.js +164 -160
- data/app/assets/javascripts/dataTables/responsive/dataTables.responsive.min.js +23 -0
- data/app/assets/javascripts/dataTables/responsive/responsive.bootstrap.min.js +7 -0
- data/app/assets/javascripts/effective_datatables.js +15 -6
- data/app/assets/javascripts/effective_datatables/initialize.js.coffee.erb +118 -92
- data/app/assets/javascripts/vendor/jszip.min.js +14 -0
- data/app/assets/stylesheets/dataTables/buttons/buttons.bootstrap.min.css +102 -0
- data/app/assets/stylesheets/dataTables/buttons/buttons.dataTables.min.css +298 -0
- data/app/assets/stylesheets/dataTables/colReorder/colReorder.bootstrap.min.css +1 -0
- data/app/assets/stylesheets/dataTables/{dataTables.colReorder.min.css → colReorder/colReorder.dataTables.min.css} +0 -0
- data/app/assets/stylesheets/dataTables/dataTables.bootstrap.min.css +187 -0
- data/app/assets/stylesheets/dataTables/jquery.dataTables.min.css +24 -26
- data/app/assets/stylesheets/dataTables/responsive/responsive.bootstrap.min.css +1 -0
- data/app/assets/stylesheets/dataTables/responsive/responsive.dataTables.min.css +1 -0
- data/app/assets/stylesheets/effective_datatables.scss +10 -4
- data/app/assets/stylesheets/effective_datatables/_overrides.scss.erb +118 -103
- data/app/helpers/effective_datatables_helper.rb +25 -36
- data/app/models/effective/effective_datatable/dsl.rb +1 -0
- data/app/models/effective/effective_datatable/options.rb +1 -1
- data/app/views/effective/datatables/_datatable.html.haml +7 -20
- data/lib/effective_datatables/version.rb +1 -1
- metadata +18 -15
- data/app/assets/javascripts/dataTables/bootstrap/2/jquery.dataTables.bootstrap.js +0 -148
- data/app/assets/javascripts/dataTables/dataTables.colVis.min.js +0 -24
- data/app/assets/javascripts/dataTables/dataTables.fixedColumns.min.js +0 -30
- data/app/assets/javascripts/dataTables/dataTables.tableTools.min.js +0 -70
- data/app/assets/javascripts/effective_datatables.bootstrap2.js +0 -12
- data/app/assets/stylesheets/dataTables/bootstrap/2/jquery.dataTables.bootstrap.scss +0 -207
- data/app/assets/stylesheets/dataTables/bootstrap/3/jquery.dataTables.bootstrap.scss +0 -280
- data/app/assets/stylesheets/dataTables/dataTables.colVis.min.css +0 -1
- data/app/assets/stylesheets/dataTables/dataTables.fixedColumns.min.css +0 -1
- data/app/assets/stylesheets/dataTables/dataTables.tableTools.min.css +0 -1
- data/app/assets/stylesheets/effective_datatables.bootstrap2.scss +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a11a4152015f5e0e9ac464f327b5948c88e0ff1e
|
4
|
+
data.tar.gz: 0340d9dbfa87581de8316de5f4cae793d4a3f7bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7f862762dc7adb0694cd5036455cdd022058a5c91aabaaeaf08baa441aa3ff7cbb23b20b395815d730b25de4008417c090febc563d41922e66877eb69f40bc8
|
7
|
+
data.tar.gz: 1c141fc85e8614b7a409ba632dc376ea369a306c03fa2b6ff94b41cccd8894667bc2527d549be13c472e569570c454bc00d887ffec95bfc0239ae7adb38a71f4
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ Use a simple DSL in just one ruby file to implement all features
|
|
6
6
|
|
7
7
|
Search raw database tables and ruby post-rendered results at the same time
|
8
8
|
|
9
|
-
Packages the jQuery DataTables assets for use in a Rails 3.2.x & Rails 4.x application using Twitter Bootstrap
|
9
|
+
Packages the jQuery DataTables assets for use in a Rails 3.2.x & Rails 4.x application using Twitter Bootstrap 3
|
10
10
|
|
11
11
|
Works with postgres, mysql, sqlite3 and arrays.
|
12
12
|
|
@@ -30,25 +30,16 @@ rails generate effective_datatables:install
|
|
30
30
|
|
31
31
|
The generator will install an initializer which describes all configuration options.
|
32
32
|
|
33
|
-
|
34
33
|
Require the javascript on the asset pipeline by adding the following to your application.js:
|
35
34
|
|
36
35
|
```ruby
|
37
|
-
# For use with Bootstrap3 (which is not included in this gem):
|
38
36
|
//= require effective_datatables
|
39
|
-
|
40
|
-
# For use with Bootstrap2 (which is not includled in this gem):
|
41
|
-
//= require effective_datatables.bootstrap2
|
42
37
|
```
|
43
38
|
|
44
39
|
Require the stylesheet on the asset pipeline by adding the following to your application.css:
|
45
40
|
|
46
41
|
```ruby
|
47
|
-
# For use with Bootstrap3 (which is not included in this gem):
|
48
42
|
*= require effective_datatables
|
49
|
-
|
50
|
-
# For use with Bootstrap2 (which is not not included in this gem):
|
51
|
-
*= require effective_datatables.bootstrap2
|
52
43
|
```
|
53
44
|
|
54
45
|
## Usage
|
@@ -108,7 +99,6 @@ Here we just render the datatable:
|
|
108
99
|
<%= render_datatable(@datatable) %>
|
109
100
|
```
|
110
101
|
|
111
|
-
|
112
102
|
## How It Works
|
113
103
|
|
114
104
|
When the jQuery DataTable is first initialized on the front-end, it makes an AJAX request back to the server asking for data.
|
@@ -0,0 +1,68 @@
|
|
1
|
+
/*! Bootstrap integration for DataTables' Buttons
|
2
|
+
* ©2015 SpryMedia Ltd - datatables.net/license
|
3
|
+
*/
|
4
|
+
|
5
|
+
(function( factory ){
|
6
|
+
if ( typeof define === 'function' && define.amd ) {
|
7
|
+
// AMD
|
8
|
+
define( ['jquery', 'datatables.net-bs', 'datatables.net-buttons'], function ( $ ) {
|
9
|
+
return factory( $, window, document );
|
10
|
+
} );
|
11
|
+
}
|
12
|
+
else if ( typeof exports === 'object' ) {
|
13
|
+
// CommonJS
|
14
|
+
module.exports = function (root, $) {
|
15
|
+
if ( ! root ) {
|
16
|
+
root = window;
|
17
|
+
}
|
18
|
+
|
19
|
+
if ( ! $ || ! $.fn.dataTable ) {
|
20
|
+
$ = require('datatables.net-bs')(root, $).$;
|
21
|
+
}
|
22
|
+
|
23
|
+
if ( ! $.fn.dataTable.Buttons ) {
|
24
|
+
require('datatables.net-buttons')(root, $);
|
25
|
+
}
|
26
|
+
|
27
|
+
return factory( $, root, root.document );
|
28
|
+
};
|
29
|
+
}
|
30
|
+
else {
|
31
|
+
// Browser
|
32
|
+
factory( jQuery, window, document );
|
33
|
+
}
|
34
|
+
}(function( $, window, document, undefined ) {
|
35
|
+
'use strict';
|
36
|
+
var DataTable = $.fn.dataTable;
|
37
|
+
|
38
|
+
|
39
|
+
$.extend( true, DataTable.Buttons.defaults, {
|
40
|
+
dom: {
|
41
|
+
container: {
|
42
|
+
className: 'dt-buttons btn-group'
|
43
|
+
},
|
44
|
+
button: {
|
45
|
+
className: 'btn btn-default'
|
46
|
+
},
|
47
|
+
collection: {
|
48
|
+
tag: 'ul',
|
49
|
+
className: 'dt-button-collection dropdown-menu',
|
50
|
+
button: {
|
51
|
+
tag: 'li',
|
52
|
+
className: 'dt-button'
|
53
|
+
},
|
54
|
+
buttonLiner: {
|
55
|
+
tag: 'a',
|
56
|
+
className: ''
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
} );
|
61
|
+
|
62
|
+
DataTable.ext.buttons.collection.text = function ( dt ) {
|
63
|
+
return dt.i18n('buttons.collection', 'Collection <span class="caret"/>');
|
64
|
+
};
|
65
|
+
|
66
|
+
|
67
|
+
return DataTable.Buttons;
|
68
|
+
}));
|
@@ -0,0 +1,197 @@
|
|
1
|
+
/*!
|
2
|
+
* Column visibility buttons for Buttons and DataTables.
|
3
|
+
* 2015 SpryMedia Ltd - datatables.net/license
|
4
|
+
*/
|
5
|
+
|
6
|
+
(function( factory ){
|
7
|
+
if ( typeof define === 'function' && define.amd ) {
|
8
|
+
// AMD
|
9
|
+
define( ['jquery', 'datatables.net', 'datatables.net-buttons'], function ( $ ) {
|
10
|
+
return factory( $, window, document );
|
11
|
+
} );
|
12
|
+
}
|
13
|
+
else if ( typeof exports === 'object' ) {
|
14
|
+
// CommonJS
|
15
|
+
module.exports = function (root, $) {
|
16
|
+
if ( ! root ) {
|
17
|
+
root = window;
|
18
|
+
}
|
19
|
+
|
20
|
+
if ( ! $ || ! $.fn.dataTable ) {
|
21
|
+
$ = require('datatables.net')(root, $).$;
|
22
|
+
}
|
23
|
+
|
24
|
+
if ( ! $.fn.dataTable.Buttons ) {
|
25
|
+
require('datatables.net-buttons')(root, $);
|
26
|
+
}
|
27
|
+
|
28
|
+
return factory( $, root, root.document );
|
29
|
+
};
|
30
|
+
}
|
31
|
+
else {
|
32
|
+
// Browser
|
33
|
+
factory( jQuery, window, document );
|
34
|
+
}
|
35
|
+
}(function( $, window, document, undefined ) {
|
36
|
+
'use strict';
|
37
|
+
var DataTable = $.fn.dataTable;
|
38
|
+
|
39
|
+
|
40
|
+
$.extend( DataTable.ext.buttons, {
|
41
|
+
// A collection of column visibility buttons
|
42
|
+
colvis: function ( dt, conf ) {
|
43
|
+
return {
|
44
|
+
extend: 'collection',
|
45
|
+
text: function ( dt ) {
|
46
|
+
return dt.i18n( 'buttons.colvis', 'Column visibility' );
|
47
|
+
},
|
48
|
+
className: 'buttons-colvis',
|
49
|
+
buttons: [ {
|
50
|
+
extend: 'columnsToggle',
|
51
|
+
columns: conf.columns
|
52
|
+
} ]
|
53
|
+
};
|
54
|
+
},
|
55
|
+
|
56
|
+
// Selected columns with individual buttons - toggle column visibility
|
57
|
+
columnsToggle: function ( dt, conf ) {
|
58
|
+
var columns = dt.columns( conf.columns ).indexes().map( function ( idx ) {
|
59
|
+
return {
|
60
|
+
extend: 'columnToggle',
|
61
|
+
columns: idx
|
62
|
+
};
|
63
|
+
} ).toArray();
|
64
|
+
|
65
|
+
return columns;
|
66
|
+
},
|
67
|
+
|
68
|
+
// Single button to toggle column visibility
|
69
|
+
columnToggle: function ( dt, conf ) {
|
70
|
+
return {
|
71
|
+
extend: 'columnVisibility',
|
72
|
+
columns: conf.columns
|
73
|
+
};
|
74
|
+
},
|
75
|
+
|
76
|
+
// Selected columns with individual buttons - set column visibility
|
77
|
+
columnsVisibility: function ( dt, conf ) {
|
78
|
+
var columns = dt.columns( conf.columns ).indexes().map( function ( idx ) {
|
79
|
+
return {
|
80
|
+
extend: 'columnVisibility',
|
81
|
+
columns: idx,
|
82
|
+
visibility: conf.visibility
|
83
|
+
};
|
84
|
+
} ).toArray();
|
85
|
+
|
86
|
+
return columns;
|
87
|
+
},
|
88
|
+
|
89
|
+
// Single button to set column visibility
|
90
|
+
columnVisibility: {
|
91
|
+
columns: undefined, // column selector
|
92
|
+
text: function ( dt, button, conf ) {
|
93
|
+
return conf._columnText( dt, conf.columns );
|
94
|
+
},
|
95
|
+
className: 'buttons-columnVisibility',
|
96
|
+
action: function ( e, dt, button, conf ) {
|
97
|
+
var col = dt.columns( conf.columns );
|
98
|
+
var curr = col.visible();
|
99
|
+
|
100
|
+
col.visible( conf.visibility !== undefined ?
|
101
|
+
conf.visibility :
|
102
|
+
! (curr.length ? curr[0] : false )
|
103
|
+
);
|
104
|
+
},
|
105
|
+
init: function ( dt, button, conf ) {
|
106
|
+
var that = this;
|
107
|
+
var col = dt.column( conf.columns );
|
108
|
+
|
109
|
+
dt
|
110
|
+
.on( 'column-visibility.dt'+conf.namespace, function (e, settings, column, state) {
|
111
|
+
if ( column === conf.columns ) {
|
112
|
+
that.active( state );
|
113
|
+
}
|
114
|
+
} )
|
115
|
+
.on( 'column-reorder.dt'+conf.namespace, function (e, settings, details) {
|
116
|
+
// Don't rename buttons based on column name if the button
|
117
|
+
// controls more than one column!
|
118
|
+
if ( dt.columns( conf.columns ).count() !== 1 ) {
|
119
|
+
return;
|
120
|
+
}
|
121
|
+
|
122
|
+
if ( typeof conf.columns === 'number' ) {
|
123
|
+
conf.columns = details.mapping[ conf.columns ];
|
124
|
+
}
|
125
|
+
|
126
|
+
var col = dt.column( conf.columns );
|
127
|
+
|
128
|
+
that.text( conf._columnText( dt, conf.columns ) );
|
129
|
+
that.active( col.visible() );
|
130
|
+
} );
|
131
|
+
|
132
|
+
this.active( col.visible() );
|
133
|
+
},
|
134
|
+
destroy: function ( dt, button, conf ) {
|
135
|
+
dt
|
136
|
+
.off( 'column-visibility.dt'+conf.namespace )
|
137
|
+
.off( 'column-reorder.dt'+conf.namespace );
|
138
|
+
},
|
139
|
+
|
140
|
+
_columnText: function ( dt, col ) {
|
141
|
+
// Use DataTables' internal data structure until this is presented
|
142
|
+
// is a public API. The other option is to use
|
143
|
+
// `$( column(col).node() ).text()` but the node might not have been
|
144
|
+
// populated when Buttons is constructed.
|
145
|
+
var idx = dt.column( col ).index();
|
146
|
+
return dt.settings()[0].aoColumns[ idx ].sTitle
|
147
|
+
.replace(/\n/g," ") // remove new lines
|
148
|
+
.replace( /<.*?>/g, "" ) // strip HTML
|
149
|
+
.replace(/^\s+|\s+$/g,""); // trim
|
150
|
+
}
|
151
|
+
},
|
152
|
+
|
153
|
+
|
154
|
+
colvisRestore: {
|
155
|
+
className: 'buttons-colvisRestore',
|
156
|
+
|
157
|
+
text: function ( dt ) {
|
158
|
+
return dt.i18n( 'buttons.colvisRestore', 'Restore visibility' );
|
159
|
+
},
|
160
|
+
|
161
|
+
init: function ( dt, button, conf ) {
|
162
|
+
conf._visOriginal = dt.columns().indexes().map( function ( idx ) {
|
163
|
+
return dt.column( idx ).visible();
|
164
|
+
} ).toArray();
|
165
|
+
},
|
166
|
+
|
167
|
+
action: function ( e, dt, button, conf ) {
|
168
|
+
dt.columns().every( function ( i ) {
|
169
|
+
// Take into account that ColReorder might have disrupted our
|
170
|
+
// indexes
|
171
|
+
var idx = dt.colReorder && dt.colReorder.transpose ?
|
172
|
+
dt.colReorder.transpose( i, 'toOriginal' ) :
|
173
|
+
i;
|
174
|
+
|
175
|
+
this.visible( conf._visOriginal[ idx ] );
|
176
|
+
} );
|
177
|
+
}
|
178
|
+
},
|
179
|
+
|
180
|
+
|
181
|
+
colvisGroup: {
|
182
|
+
className: 'buttons-colvisGroup',
|
183
|
+
|
184
|
+
action: function ( e, dt, button, conf ) {
|
185
|
+
dt.columns( conf.show ).visible( true );
|
186
|
+
dt.columns( conf.hide ).visible( false );
|
187
|
+
},
|
188
|
+
|
189
|
+
show: [],
|
190
|
+
|
191
|
+
hide: []
|
192
|
+
}
|
193
|
+
} );
|
194
|
+
|
195
|
+
|
196
|
+
return DataTable.Buttons;
|
197
|
+
}));
|
@@ -0,0 +1,828 @@
|
|
1
|
+
/*!
|
2
|
+
* HTML5 export buttons for Buttons and DataTables.
|
3
|
+
* 2015 SpryMedia Ltd - datatables.net/license
|
4
|
+
*
|
5
|
+
* FileSaver.js (2015-05-07.2) - MIT license
|
6
|
+
* Copyright © 2015 Eli Grey - http://eligrey.com
|
7
|
+
*/
|
8
|
+
|
9
|
+
(function( factory ){
|
10
|
+
if ( typeof define === 'function' && define.amd ) {
|
11
|
+
// AMD
|
12
|
+
define( ['jquery', 'datatables.net', 'datatables.net-buttons'], function ( $ ) {
|
13
|
+
return factory( $, window, document );
|
14
|
+
} );
|
15
|
+
}
|
16
|
+
else if ( typeof exports === 'object' ) {
|
17
|
+
// CommonJS
|
18
|
+
module.exports = function (root, $) {
|
19
|
+
if ( ! root ) {
|
20
|
+
root = window;
|
21
|
+
}
|
22
|
+
|
23
|
+
if ( ! $ || ! $.fn.dataTable ) {
|
24
|
+
$ = require('datatables.net')(root, $).$;
|
25
|
+
}
|
26
|
+
|
27
|
+
if ( ! $.fn.dataTable.Buttons ) {
|
28
|
+
require('datatables.net-buttons')(root, $);
|
29
|
+
}
|
30
|
+
|
31
|
+
return factory( $, root, root.document );
|
32
|
+
};
|
33
|
+
}
|
34
|
+
else {
|
35
|
+
// Browser
|
36
|
+
factory( jQuery, window, document );
|
37
|
+
}
|
38
|
+
}(function( $, window, document, undefined ) {
|
39
|
+
'use strict';
|
40
|
+
var DataTable = $.fn.dataTable;
|
41
|
+
|
42
|
+
|
43
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
44
|
+
* FileSaver.js dependency
|
45
|
+
*/
|
46
|
+
|
47
|
+
/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
|
48
|
+
|
49
|
+
var _saveAs = (function(view) {
|
50
|
+
// IE <10 is explicitly unsupported
|
51
|
+
if (typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
|
52
|
+
return;
|
53
|
+
}
|
54
|
+
var
|
55
|
+
doc = view.document
|
56
|
+
// only get URL when necessary in case Blob.js hasn't overridden it yet
|
57
|
+
, get_URL = function() {
|
58
|
+
return view.URL || view.webkitURL || view;
|
59
|
+
}
|
60
|
+
, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
|
61
|
+
, can_use_save_link = "download" in save_link
|
62
|
+
, click = function(node) {
|
63
|
+
var event = doc.createEvent("MouseEvents");
|
64
|
+
event.initMouseEvent(
|
65
|
+
"click", true, false, view, 0, 0, 0, 0, 0
|
66
|
+
, false, false, false, false, 0, null
|
67
|
+
);
|
68
|
+
node.dispatchEvent(event);
|
69
|
+
}
|
70
|
+
, webkit_req_fs = view.webkitRequestFileSystem
|
71
|
+
, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
|
72
|
+
, throw_outside = function(ex) {
|
73
|
+
(view.setImmediate || view.setTimeout)(function() {
|
74
|
+
throw ex;
|
75
|
+
}, 0);
|
76
|
+
}
|
77
|
+
, force_saveable_type = "application/octet-stream"
|
78
|
+
, fs_min_size = 0
|
79
|
+
// See https://code.google.com/p/chromium/issues/detail?id=375297#c7 and
|
80
|
+
// https://github.com/eligrey/FileSaver.js/commit/485930a#commitcomment-8768047
|
81
|
+
// for the reasoning behind the timeout and revocation flow
|
82
|
+
, arbitrary_revoke_timeout = 500 // in ms
|
83
|
+
, revoke = function(file) {
|
84
|
+
var revoker = function() {
|
85
|
+
if (typeof file === "string") { // file is an object URL
|
86
|
+
get_URL().revokeObjectURL(file);
|
87
|
+
} else { // file is a File
|
88
|
+
file.remove();
|
89
|
+
}
|
90
|
+
};
|
91
|
+
if (view.chrome) {
|
92
|
+
revoker();
|
93
|
+
} else {
|
94
|
+
setTimeout(revoker, arbitrary_revoke_timeout);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
, dispatch = function(filesaver, event_types, event) {
|
98
|
+
event_types = [].concat(event_types);
|
99
|
+
var i = event_types.length;
|
100
|
+
while (i--) {
|
101
|
+
var listener = filesaver["on" + event_types[i]];
|
102
|
+
if (typeof listener === "function") {
|
103
|
+
try {
|
104
|
+
listener.call(filesaver, event || filesaver);
|
105
|
+
} catch (ex) {
|
106
|
+
throw_outside(ex);
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
, auto_bom = function(blob) {
|
112
|
+
// prepend BOM for UTF-8 XML and text/* types (including HTML)
|
113
|
+
if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
|
114
|
+
return new Blob(["\ufeff", blob], {type: blob.type});
|
115
|
+
}
|
116
|
+
return blob;
|
117
|
+
}
|
118
|
+
, FileSaver = function(blob, name) {
|
119
|
+
blob = auto_bom(blob);
|
120
|
+
// First try a.download, then web filesystem, then object URLs
|
121
|
+
var
|
122
|
+
filesaver = this
|
123
|
+
, type = blob.type
|
124
|
+
, blob_changed = false
|
125
|
+
, object_url
|
126
|
+
, target_view
|
127
|
+
, dispatch_all = function() {
|
128
|
+
dispatch(filesaver, "writestart progress write writeend".split(" "));
|
129
|
+
}
|
130
|
+
// on any filesys errors revert to saving with object URLs
|
131
|
+
, fs_error = function() {
|
132
|
+
// don't create more object URLs than needed
|
133
|
+
if (blob_changed || !object_url) {
|
134
|
+
object_url = get_URL().createObjectURL(blob);
|
135
|
+
}
|
136
|
+
if (target_view) {
|
137
|
+
target_view.location.href = object_url;
|
138
|
+
} else {
|
139
|
+
var new_tab = view.open(object_url, "_blank");
|
140
|
+
if (new_tab === undefined && typeof safari !== "undefined") {
|
141
|
+
//Apple do not allow window.open, see http://bit.ly/1kZffRI
|
142
|
+
view.location.href = object_url;
|
143
|
+
}
|
144
|
+
}
|
145
|
+
filesaver.readyState = filesaver.DONE;
|
146
|
+
dispatch_all();
|
147
|
+
revoke(object_url);
|
148
|
+
}
|
149
|
+
, abortable = function(func) {
|
150
|
+
return function() {
|
151
|
+
if (filesaver.readyState !== filesaver.DONE) {
|
152
|
+
return func.apply(this, arguments);
|
153
|
+
}
|
154
|
+
};
|
155
|
+
}
|
156
|
+
, create_if_not_found = {create: true, exclusive: false}
|
157
|
+
, slice
|
158
|
+
;
|
159
|
+
filesaver.readyState = filesaver.INIT;
|
160
|
+
if (!name) {
|
161
|
+
name = "download";
|
162
|
+
}
|
163
|
+
if (can_use_save_link) {
|
164
|
+
object_url = get_URL().createObjectURL(blob);
|
165
|
+
save_link.href = object_url;
|
166
|
+
save_link.download = name;
|
167
|
+
click(save_link);
|
168
|
+
filesaver.readyState = filesaver.DONE;
|
169
|
+
dispatch_all();
|
170
|
+
revoke(object_url);
|
171
|
+
return;
|
172
|
+
}
|
173
|
+
// Object and web filesystem URLs have a problem saving in Google Chrome when
|
174
|
+
// viewed in a tab, so I force save with application/octet-stream
|
175
|
+
// http://code.google.com/p/chromium/issues/detail?id=91158
|
176
|
+
// Update: Google errantly closed 91158, I submitted it again:
|
177
|
+
// https://code.google.com/p/chromium/issues/detail?id=389642
|
178
|
+
if (view.chrome && type && type !== force_saveable_type) {
|
179
|
+
slice = blob.slice || blob.webkitSlice;
|
180
|
+
blob = slice.call(blob, 0, blob.size, force_saveable_type);
|
181
|
+
blob_changed = true;
|
182
|
+
}
|
183
|
+
// Since I can't be sure that the guessed media type will trigger a download
|
184
|
+
// in WebKit, I append .download to the filename.
|
185
|
+
// https://bugs.webkit.org/show_bug.cgi?id=65440
|
186
|
+
if (webkit_req_fs && name !== "download") {
|
187
|
+
name += ".download";
|
188
|
+
}
|
189
|
+
if (type === force_saveable_type || webkit_req_fs) {
|
190
|
+
target_view = view;
|
191
|
+
}
|
192
|
+
if (!req_fs) {
|
193
|
+
fs_error();
|
194
|
+
return;
|
195
|
+
}
|
196
|
+
fs_min_size += blob.size;
|
197
|
+
req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
|
198
|
+
fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
|
199
|
+
var save = function() {
|
200
|
+
dir.getFile(name, create_if_not_found, abortable(function(file) {
|
201
|
+
file.createWriter(abortable(function(writer) {
|
202
|
+
writer.onwriteend = function(event) {
|
203
|
+
target_view.location.href = file.toURL();
|
204
|
+
filesaver.readyState = filesaver.DONE;
|
205
|
+
dispatch(filesaver, "writeend", event);
|
206
|
+
revoke(file);
|
207
|
+
};
|
208
|
+
writer.onerror = function() {
|
209
|
+
var error = writer.error;
|
210
|
+
if (error.code !== error.ABORT_ERR) {
|
211
|
+
fs_error();
|
212
|
+
}
|
213
|
+
};
|
214
|
+
"writestart progress write abort".split(" ").forEach(function(event) {
|
215
|
+
writer["on" + event] = filesaver["on" + event];
|
216
|
+
});
|
217
|
+
writer.write(blob);
|
218
|
+
filesaver.abort = function() {
|
219
|
+
writer.abort();
|
220
|
+
filesaver.readyState = filesaver.DONE;
|
221
|
+
};
|
222
|
+
filesaver.readyState = filesaver.WRITING;
|
223
|
+
}), fs_error);
|
224
|
+
}), fs_error);
|
225
|
+
};
|
226
|
+
dir.getFile(name, {create: false}, abortable(function(file) {
|
227
|
+
// delete file if it already exists
|
228
|
+
file.remove();
|
229
|
+
save();
|
230
|
+
}), abortable(function(ex) {
|
231
|
+
if (ex.code === ex.NOT_FOUND_ERR) {
|
232
|
+
save();
|
233
|
+
} else {
|
234
|
+
fs_error();
|
235
|
+
}
|
236
|
+
}));
|
237
|
+
}), fs_error);
|
238
|
+
}), fs_error);
|
239
|
+
}
|
240
|
+
, FS_proto = FileSaver.prototype
|
241
|
+
, saveAs = function(blob, name) {
|
242
|
+
return new FileSaver(blob, name);
|
243
|
+
}
|
244
|
+
;
|
245
|
+
// IE 10+ (native saveAs)
|
246
|
+
if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
|
247
|
+
return function(blob, name) {
|
248
|
+
return navigator.msSaveOrOpenBlob(auto_bom(blob), name);
|
249
|
+
};
|
250
|
+
}
|
251
|
+
|
252
|
+
FS_proto.abort = function() {
|
253
|
+
var filesaver = this;
|
254
|
+
filesaver.readyState = filesaver.DONE;
|
255
|
+
dispatch(filesaver, "abort");
|
256
|
+
};
|
257
|
+
FS_proto.readyState = FS_proto.INIT = 0;
|
258
|
+
FS_proto.WRITING = 1;
|
259
|
+
FS_proto.DONE = 2;
|
260
|
+
|
261
|
+
FS_proto.error =
|
262
|
+
FS_proto.onwritestart =
|
263
|
+
FS_proto.onprogress =
|
264
|
+
FS_proto.onwrite =
|
265
|
+
FS_proto.onabort =
|
266
|
+
FS_proto.onerror =
|
267
|
+
FS_proto.onwriteend =
|
268
|
+
null;
|
269
|
+
|
270
|
+
return saveAs;
|
271
|
+
}(window));
|
272
|
+
|
273
|
+
|
274
|
+
|
275
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
276
|
+
* Local (private) functions
|
277
|
+
*/
|
278
|
+
|
279
|
+
/**
|
280
|
+
* Get the file name for an exported file.
|
281
|
+
*
|
282
|
+
* @param {object} config Button configuration
|
283
|
+
* @param {boolean} incExtension Include the file name extension
|
284
|
+
*/
|
285
|
+
var _filename = function ( config, incExtension )
|
286
|
+
{
|
287
|
+
// Backwards compatibility
|
288
|
+
var filename = config.filename === '*' && config.title !== '*' && config.title !== undefined ?
|
289
|
+
config.title :
|
290
|
+
config.filename;
|
291
|
+
|
292
|
+
if ( filename.indexOf( '*' ) !== -1 ) {
|
293
|
+
filename = filename.replace( '*', $('title').text() );
|
294
|
+
}
|
295
|
+
|
296
|
+
// Strip characters which the OS will object to
|
297
|
+
filename = filename.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g, "");
|
298
|
+
|
299
|
+
return incExtension === undefined || incExtension === true ?
|
300
|
+
filename+config.extension :
|
301
|
+
filename;
|
302
|
+
};
|
303
|
+
|
304
|
+
/**
|
305
|
+
* Get the title for an exported file.
|
306
|
+
*
|
307
|
+
* @param {object} config Button configuration
|
308
|
+
*/
|
309
|
+
var _title = function ( config )
|
310
|
+
{
|
311
|
+
var title = config.title;
|
312
|
+
|
313
|
+
return title.indexOf( '*' ) !== -1 ?
|
314
|
+
title.replace( '*', $('title').text() ) :
|
315
|
+
title;
|
316
|
+
};
|
317
|
+
|
318
|
+
/**
|
319
|
+
* Get the newline character(s)
|
320
|
+
*
|
321
|
+
* @param {object} config Button configuration
|
322
|
+
* @return {string} Newline character
|
323
|
+
*/
|
324
|
+
var _newLine = function ( config )
|
325
|
+
{
|
326
|
+
return config.newline ?
|
327
|
+
config.newline :
|
328
|
+
navigator.userAgent.match(/Windows/) ?
|
329
|
+
'\r\n' :
|
330
|
+
'\n';
|
331
|
+
};
|
332
|
+
|
333
|
+
/**
|
334
|
+
* Combine the data from the `buttons.exportData` method into a string that
|
335
|
+
* will be used in the export file.
|
336
|
+
*
|
337
|
+
* @param {DataTable.Api} dt DataTables API instance
|
338
|
+
* @param {object} config Button configuration
|
339
|
+
* @return {object} The data to export
|
340
|
+
*/
|
341
|
+
var _exportData = function ( dt, config )
|
342
|
+
{
|
343
|
+
var newLine = _newLine( config );
|
344
|
+
var data = dt.buttons.exportData( config.exportOptions );
|
345
|
+
var boundary = config.fieldBoundary;
|
346
|
+
var separator = config.fieldSeparator;
|
347
|
+
var reBoundary = new RegExp( boundary, 'g' );
|
348
|
+
var escapeChar = config.escapeChar !== undefined ?
|
349
|
+
config.escapeChar :
|
350
|
+
'\\';
|
351
|
+
var join = function ( a ) {
|
352
|
+
var s = '';
|
353
|
+
|
354
|
+
// If there is a field boundary, then we might need to escape it in
|
355
|
+
// the source data
|
356
|
+
for ( var i=0, ien=a.length ; i<ien ; i++ ) {
|
357
|
+
if ( i > 0 ) {
|
358
|
+
s += separator;
|
359
|
+
}
|
360
|
+
|
361
|
+
s += boundary ?
|
362
|
+
boundary + ('' + a[i]).replace( reBoundary, escapeChar+boundary ) + boundary :
|
363
|
+
a[i];
|
364
|
+
}
|
365
|
+
|
366
|
+
return s;
|
367
|
+
};
|
368
|
+
|
369
|
+
var header = config.header ? join( data.header )+newLine : '';
|
370
|
+
var footer = config.footer ? newLine+join( data.footer ) : '';
|
371
|
+
var body = [];
|
372
|
+
|
373
|
+
for ( var i=0, ien=data.body.length ; i<ien ; i++ ) {
|
374
|
+
body.push( join( data.body[i] ) );
|
375
|
+
}
|
376
|
+
|
377
|
+
return {
|
378
|
+
str: header + body.join( newLine ) + footer,
|
379
|
+
rows: body.length
|
380
|
+
};
|
381
|
+
};
|
382
|
+
|
383
|
+
/**
|
384
|
+
* Safari's data: support for creating and downloading files is really poor, so
|
385
|
+
* various options need to be disabled in it. See
|
386
|
+
* https://bugs.webkit.org/show_bug.cgi?id=102914
|
387
|
+
*
|
388
|
+
* @return {Boolean} `true` if Safari
|
389
|
+
*/
|
390
|
+
var _isSafari = function ()
|
391
|
+
{
|
392
|
+
return navigator.userAgent.indexOf('Safari') !== -1 &&
|
393
|
+
navigator.userAgent.indexOf('Chrome') === -1 &&
|
394
|
+
navigator.userAgent.indexOf('Opera') === -1;
|
395
|
+
};
|
396
|
+
|
397
|
+
|
398
|
+
// Excel - Pre-defined strings to build a minimal XLSX file
|
399
|
+
var excelStrings = {
|
400
|
+
"_rels/.rels": '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\
|
401
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">\
|
402
|
+
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>\
|
403
|
+
</Relationships>',
|
404
|
+
|
405
|
+
"xl/_rels/workbook.xml.rels": '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\
|
406
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">\
|
407
|
+
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>\
|
408
|
+
</Relationships>',
|
409
|
+
|
410
|
+
"[Content_Types].xml": '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\
|
411
|
+
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">\
|
412
|
+
<Default Extension="xml" ContentType="application/xml"/>\
|
413
|
+
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>\
|
414
|
+
<Default Extension="jpeg" ContentType="image/jpeg"/>\
|
415
|
+
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>\
|
416
|
+
<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>\
|
417
|
+
</Types>',
|
418
|
+
|
419
|
+
"xl/workbook.xml": '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\
|
420
|
+
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">\
|
421
|
+
<fileVersion appName="xl" lastEdited="5" lowestEdited="5" rupBuild="24816"/>\
|
422
|
+
<workbookPr showInkAnnotation="0" autoCompressPictures="0"/>\
|
423
|
+
<bookViews>\
|
424
|
+
<workbookView xWindow="0" yWindow="0" windowWidth="25600" windowHeight="19020" tabRatio="500"/>\
|
425
|
+
</bookViews>\
|
426
|
+
<sheets>\
|
427
|
+
<sheet name="Sheet1" sheetId="1" r:id="rId1"/>\
|
428
|
+
</sheets>\
|
429
|
+
</workbook>',
|
430
|
+
|
431
|
+
"xl/worksheets/sheet1.xml": '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\
|
432
|
+
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">\
|
433
|
+
<sheetData>\
|
434
|
+
__DATA__\
|
435
|
+
</sheetData>\
|
436
|
+
</worksheet>'
|
437
|
+
};
|
438
|
+
|
439
|
+
|
440
|
+
|
441
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
442
|
+
* Buttons
|
443
|
+
*/
|
444
|
+
|
445
|
+
//
|
446
|
+
// Copy to clipboard
|
447
|
+
//
|
448
|
+
DataTable.ext.buttons.copyHtml5 = {
|
449
|
+
className: 'buttons-copy buttons-html5',
|
450
|
+
|
451
|
+
text: function ( dt ) {
|
452
|
+
return dt.i18n( 'buttons.copy', 'Copy' );
|
453
|
+
},
|
454
|
+
|
455
|
+
action: function ( e, dt, button, config ) {
|
456
|
+
var exportData = _exportData( dt, config );
|
457
|
+
var output = exportData.str;
|
458
|
+
var hiddenDiv = $('<div/>')
|
459
|
+
.css( {
|
460
|
+
height: 1,
|
461
|
+
width: 1,
|
462
|
+
overflow: 'hidden',
|
463
|
+
position: 'fixed',
|
464
|
+
top: 0,
|
465
|
+
left: 0
|
466
|
+
} );
|
467
|
+
var textarea = $('<textarea readonly/>')
|
468
|
+
.val( output )
|
469
|
+
.appendTo( hiddenDiv );
|
470
|
+
|
471
|
+
// For browsers that support the copy execCommand, try to use it
|
472
|
+
if ( document.queryCommandSupported('copy') ) {
|
473
|
+
hiddenDiv.appendTo( 'body' );
|
474
|
+
textarea[0].focus();
|
475
|
+
textarea[0].select();
|
476
|
+
|
477
|
+
try {
|
478
|
+
document.execCommand( 'copy' );
|
479
|
+
hiddenDiv.remove();
|
480
|
+
|
481
|
+
dt.buttons.info(
|
482
|
+
dt.i18n( 'buttons.copyTitle', 'Copy to clipboard' ),
|
483
|
+
dt.i18n( 'buttons.copySuccess', {
|
484
|
+
1: "Copied one row to clipboard",
|
485
|
+
_: "Copied %d rows to clipboard"
|
486
|
+
}, exportData.rows ),
|
487
|
+
2000
|
488
|
+
);
|
489
|
+
|
490
|
+
return;
|
491
|
+
}
|
492
|
+
catch (t) {}
|
493
|
+
}
|
494
|
+
|
495
|
+
// Otherwise we show the text box and instruct the user to use it
|
496
|
+
var message = $('<span>'+dt.i18n( 'buttons.copyKeys',
|
497
|
+
'Press <i>ctrl</i> or <i>\u2318</i> + <i>C</i> to copy the table data<br>to your system clipboard.<br><br>'+
|
498
|
+
'To cancel, click this message or press escape.' )+'</span>'
|
499
|
+
)
|
500
|
+
.append( hiddenDiv );
|
501
|
+
|
502
|
+
dt.buttons.info( dt.i18n( 'buttons.copyTitle', 'Copy to clipboard' ), message, 0 );
|
503
|
+
|
504
|
+
// Select the text so when the user activates their system clipboard
|
505
|
+
// it will copy that text
|
506
|
+
textarea[0].focus();
|
507
|
+
textarea[0].select();
|
508
|
+
|
509
|
+
// Event to hide the message when the user is done
|
510
|
+
var container = $(message).closest('.dt-button-info');
|
511
|
+
var close = function () {
|
512
|
+
container.off( 'click.buttons-copy' );
|
513
|
+
$(document).off( '.buttons-copy' );
|
514
|
+
dt.buttons.info( false );
|
515
|
+
};
|
516
|
+
|
517
|
+
container.on( 'click.buttons-copy', close );
|
518
|
+
$(document)
|
519
|
+
.on( 'keydown.buttons-copy', function (e) {
|
520
|
+
if ( e.keyCode === 27 ) { // esc
|
521
|
+
close();
|
522
|
+
}
|
523
|
+
} )
|
524
|
+
.on( 'copy.buttons-copy cut.buttons-copy', function () {
|
525
|
+
close();
|
526
|
+
} );
|
527
|
+
},
|
528
|
+
|
529
|
+
exportOptions: {},
|
530
|
+
|
531
|
+
fieldSeparator: '\t',
|
532
|
+
|
533
|
+
fieldBoundary: '',
|
534
|
+
|
535
|
+
header: true,
|
536
|
+
|
537
|
+
footer: false
|
538
|
+
};
|
539
|
+
|
540
|
+
//
|
541
|
+
// CSV export
|
542
|
+
//
|
543
|
+
DataTable.ext.buttons.csvHtml5 = {
|
544
|
+
className: 'buttons-csv buttons-html5',
|
545
|
+
|
546
|
+
available: function () {
|
547
|
+
return window.FileReader !== undefined && window.Blob;
|
548
|
+
},
|
549
|
+
|
550
|
+
text: function ( dt ) {
|
551
|
+
return dt.i18n( 'buttons.csv', 'CSV' );
|
552
|
+
},
|
553
|
+
|
554
|
+
action: function ( e, dt, button, config ) {
|
555
|
+
// Set the text
|
556
|
+
var newLine = _newLine( config );
|
557
|
+
var output = _exportData( dt, config ).str;
|
558
|
+
var charset = config.charset;
|
559
|
+
|
560
|
+
if ( charset !== false ) {
|
561
|
+
if ( ! charset ) {
|
562
|
+
charset = document.characterSet || document.charset;
|
563
|
+
}
|
564
|
+
|
565
|
+
if ( charset ) {
|
566
|
+
charset = ';charset='+charset;
|
567
|
+
}
|
568
|
+
}
|
569
|
+
else {
|
570
|
+
charset = '';
|
571
|
+
}
|
572
|
+
|
573
|
+
_saveAs(
|
574
|
+
new Blob( [output], {type: 'text/csv'+charset} ),
|
575
|
+
_filename( config )
|
576
|
+
);
|
577
|
+
},
|
578
|
+
|
579
|
+
filename: '*',
|
580
|
+
|
581
|
+
extension: '.csv',
|
582
|
+
|
583
|
+
exportOptions: {},
|
584
|
+
|
585
|
+
fieldSeparator: ',',
|
586
|
+
|
587
|
+
fieldBoundary: '"',
|
588
|
+
|
589
|
+
escapeChar: '"',
|
590
|
+
|
591
|
+
charset: null,
|
592
|
+
|
593
|
+
header: true,
|
594
|
+
|
595
|
+
footer: false
|
596
|
+
};
|
597
|
+
|
598
|
+
//
|
599
|
+
// Excel (xlsx) export
|
600
|
+
//
|
601
|
+
DataTable.ext.buttons.excelHtml5 = {
|
602
|
+
className: 'buttons-excel buttons-html5',
|
603
|
+
|
604
|
+
available: function () {
|
605
|
+
return window.FileReader !== undefined && window.JSZip !== undefined && ! _isSafari();
|
606
|
+
},
|
607
|
+
|
608
|
+
text: function ( dt ) {
|
609
|
+
return dt.i18n( 'buttons.excel', 'Excel' );
|
610
|
+
},
|
611
|
+
|
612
|
+
action: function ( e, dt, button, config ) {
|
613
|
+
// Set the text
|
614
|
+
var xml = '';
|
615
|
+
var data = dt.buttons.exportData( config.exportOptions );
|
616
|
+
var addRow = function ( row ) {
|
617
|
+
var cells = [];
|
618
|
+
|
619
|
+
for ( var i=0, ien=row.length ; i<ien ; i++ ) {
|
620
|
+
if ( row[i] === null || row[i] === undefined ) {
|
621
|
+
row[i] = '';
|
622
|
+
}
|
623
|
+
|
624
|
+
// Don't match numbers with leading zeros or a negative anywhere
|
625
|
+
// but the start
|
626
|
+
cells.push( typeof row[i] === 'number' || (row[i].match && row[i].match(/^-?[0-9\.]+$/) && row[i].charAt(0) !== '0') ?
|
627
|
+
'<c t="n"><v>'+row[i]+'</v></c>' :
|
628
|
+
'<c t="inlineStr"><is><t>'+(
|
629
|
+
! row[i].replace ?
|
630
|
+
row[i] :
|
631
|
+
row[i]
|
632
|
+
.replace(/&(?!amp;)/g, '&')
|
633
|
+
.replace(/[\x00-\x1F\x7F-\x9F]/g, ''))+ // remove control characters
|
634
|
+
'</t></is></c>' // they are not valid in XML
|
635
|
+
);
|
636
|
+
}
|
637
|
+
|
638
|
+
return '<row>'+cells.join('')+'</row>';
|
639
|
+
};
|
640
|
+
|
641
|
+
if ( config.header ) {
|
642
|
+
xml += addRow( data.header );
|
643
|
+
}
|
644
|
+
|
645
|
+
for ( var i=0, ien=data.body.length ; i<ien ; i++ ) {
|
646
|
+
xml += addRow( data.body[i] );
|
647
|
+
}
|
648
|
+
|
649
|
+
if ( config.footer ) {
|
650
|
+
xml += addRow( data.footer );
|
651
|
+
}
|
652
|
+
|
653
|
+
var zip = new window.JSZip();
|
654
|
+
var _rels = zip.folder("_rels");
|
655
|
+
var xl = zip.folder("xl");
|
656
|
+
var xl_rels = zip.folder("xl/_rels");
|
657
|
+
var xl_worksheets = zip.folder("xl/worksheets");
|
658
|
+
|
659
|
+
zip.file( '[Content_Types].xml', excelStrings['[Content_Types].xml'] );
|
660
|
+
_rels.file( '.rels', excelStrings['_rels/.rels'] );
|
661
|
+
xl.file( 'workbook.xml', excelStrings['xl/workbook.xml'] );
|
662
|
+
xl_rels.file( 'workbook.xml.rels', excelStrings['xl/_rels/workbook.xml.rels'] );
|
663
|
+
xl_worksheets.file( 'sheet1.xml', excelStrings['xl/worksheets/sheet1.xml'].replace( '__DATA__', xml ) );
|
664
|
+
|
665
|
+
_saveAs(
|
666
|
+
zip.generate( {type:"blob"} ),
|
667
|
+
_filename( config )
|
668
|
+
);
|
669
|
+
},
|
670
|
+
|
671
|
+
filename: '*',
|
672
|
+
|
673
|
+
extension: '.xlsx',
|
674
|
+
|
675
|
+
exportOptions: {},
|
676
|
+
|
677
|
+
header: true,
|
678
|
+
|
679
|
+
footer: false
|
680
|
+
};
|
681
|
+
|
682
|
+
//
|
683
|
+
// PDF export - using pdfMake - http://pdfmake.org
|
684
|
+
//
|
685
|
+
DataTable.ext.buttons.pdfHtml5 = {
|
686
|
+
className: 'buttons-pdf buttons-html5',
|
687
|
+
|
688
|
+
available: function () {
|
689
|
+
return window.FileReader !== undefined && window.pdfMake;
|
690
|
+
},
|
691
|
+
|
692
|
+
text: function ( dt ) {
|
693
|
+
return dt.i18n( 'buttons.pdf', 'PDF' );
|
694
|
+
},
|
695
|
+
|
696
|
+
action: function ( e, dt, button, config ) {
|
697
|
+
var newLine = _newLine( config );
|
698
|
+
var data = dt.buttons.exportData( config.exportOptions );
|
699
|
+
var rows = [];
|
700
|
+
|
701
|
+
if ( config.header ) {
|
702
|
+
rows.push( $.map( data.header, function ( d ) {
|
703
|
+
return {
|
704
|
+
text: typeof d === 'string' ? d : d+'',
|
705
|
+
style: 'tableHeader'
|
706
|
+
};
|
707
|
+
} ) );
|
708
|
+
}
|
709
|
+
|
710
|
+
for ( var i=0, ien=data.body.length ; i<ien ; i++ ) {
|
711
|
+
rows.push( $.map( data.body[i], function ( d ) {
|
712
|
+
return {
|
713
|
+
text: typeof d === 'string' ? d : d+'',
|
714
|
+
style: i % 2 ? 'tableBodyEven' : 'tableBodyOdd'
|
715
|
+
};
|
716
|
+
} ) );
|
717
|
+
}
|
718
|
+
|
719
|
+
if ( config.footer ) {
|
720
|
+
rows.push( $.map( data.footer, function ( d ) {
|
721
|
+
return {
|
722
|
+
text: typeof d === 'string' ? d : d+'',
|
723
|
+
style: 'tableFooter'
|
724
|
+
};
|
725
|
+
} ) );
|
726
|
+
}
|
727
|
+
|
728
|
+
var doc = {
|
729
|
+
pageSize: config.pageSize,
|
730
|
+
pageOrientation: config.orientation,
|
731
|
+
content: [
|
732
|
+
{
|
733
|
+
table: {
|
734
|
+
headerRows: 1,
|
735
|
+
body: rows
|
736
|
+
},
|
737
|
+
layout: 'noBorders'
|
738
|
+
}
|
739
|
+
],
|
740
|
+
styles: {
|
741
|
+
tableHeader: {
|
742
|
+
bold: true,
|
743
|
+
fontSize: 11,
|
744
|
+
color: 'white',
|
745
|
+
fillColor: '#2d4154',
|
746
|
+
alignment: 'center'
|
747
|
+
},
|
748
|
+
tableBodyEven: {},
|
749
|
+
tableBodyOdd: {
|
750
|
+
fillColor: '#f3f3f3'
|
751
|
+
},
|
752
|
+
tableFooter: {
|
753
|
+
bold: true,
|
754
|
+
fontSize: 11,
|
755
|
+
color: 'white',
|
756
|
+
fillColor: '#2d4154'
|
757
|
+
},
|
758
|
+
title: {
|
759
|
+
alignment: 'center',
|
760
|
+
fontSize: 15
|
761
|
+
},
|
762
|
+
message: {}
|
763
|
+
},
|
764
|
+
defaultStyle: {
|
765
|
+
fontSize: 10
|
766
|
+
}
|
767
|
+
};
|
768
|
+
|
769
|
+
if ( config.message ) {
|
770
|
+
doc.content.unshift( {
|
771
|
+
text: config.message,
|
772
|
+
style: 'message',
|
773
|
+
margin: [ 0, 0, 0, 12 ]
|
774
|
+
} );
|
775
|
+
}
|
776
|
+
|
777
|
+
if ( config.title ) {
|
778
|
+
doc.content.unshift( {
|
779
|
+
text: _title( config, false ),
|
780
|
+
style: 'title',
|
781
|
+
margin: [ 0, 0, 0, 12 ]
|
782
|
+
} );
|
783
|
+
}
|
784
|
+
|
785
|
+
if ( config.customize ) {
|
786
|
+
config.customize( doc );
|
787
|
+
}
|
788
|
+
|
789
|
+
var pdf = window.pdfMake.createPdf( doc );
|
790
|
+
|
791
|
+
if ( config.download === 'open' && ! _isSafari() ) {
|
792
|
+
pdf.open();
|
793
|
+
}
|
794
|
+
else {
|
795
|
+
pdf.getBuffer( function (buffer) {
|
796
|
+
var blob = new Blob( [buffer], {type:'application/pdf'} );
|
797
|
+
|
798
|
+
_saveAs( blob, _filename( config ) );
|
799
|
+
} );
|
800
|
+
}
|
801
|
+
},
|
802
|
+
|
803
|
+
title: '*',
|
804
|
+
|
805
|
+
filename: '*',
|
806
|
+
|
807
|
+
extension: '.pdf',
|
808
|
+
|
809
|
+
exportOptions: {},
|
810
|
+
|
811
|
+
orientation: 'portrait',
|
812
|
+
|
813
|
+
pageSize: 'A4',
|
814
|
+
|
815
|
+
header: true,
|
816
|
+
|
817
|
+
footer: false,
|
818
|
+
|
819
|
+
message: null,
|
820
|
+
|
821
|
+
customize: null,
|
822
|
+
|
823
|
+
download: 'download'
|
824
|
+
};
|
825
|
+
|
826
|
+
|
827
|
+
return DataTable.Buttons;
|
828
|
+
}));
|