effective_datatables 4.17.4 → 4.18.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/app/assets/javascripts/dataTables/UPGRADE.md +17 -0
- data/app/assets/javascripts/dataTables/buttons/buttons.bootstrap4.js +73 -19
- data/app/assets/javascripts/dataTables/buttons/buttons.colVis.js +166 -120
- data/app/assets/javascripts/dataTables/buttons/buttons.html5.js +749 -667
- data/app/assets/javascripts/dataTables/buttons/buttons.print.js +96 -64
- data/app/assets/javascripts/dataTables/buttons/dataTables.buttons.js +1568 -909
- data/app/assets/javascripts/dataTables/dataTables.bootstrap4.js +172 -154
- data/app/assets/javascripts/dataTables/jquery.dataTables.js +3119 -2704
- data/app/assets/javascripts/dataTables/responsive/dataTables.responsive.js +707 -531
- data/app/assets/javascripts/dataTables/responsive/responsive.bootstrap4.js +61 -33
- data/app/assets/javascripts/dataTables/rowReorder/dataTables.rowReorder.js +961 -740
- data/app/assets/javascripts/dataTables/rowReorder/rowReorder.bootstrap4.js +50 -30
- data/app/assets/stylesheets/dataTables/buttons/buttons.bootstrap4.scss +178 -151
- data/app/assets/stylesheets/dataTables/dataTables.bootstrap4.scss +300 -81
- data/app/assets/stylesheets/dataTables/responsive/responsive.bootstrap4.scss +54 -71
- data/app/assets/stylesheets/dataTables/rowReorder/rowReorder.bootstrap4.scss +23 -4
- data/app/assets/stylesheets/effective_datatables/_overrides.bootstrap4.scss +81 -39
- data/lib/effective_datatables/version.rb +1 -1
- metadata +3 -2
@@ -1,5 +1,5 @@
|
|
1
|
-
/*! Buttons for DataTables
|
2
|
-
* ©
|
1
|
+
/*! Buttons for DataTables 2.4.1
|
2
|
+
* © SpryMedia Ltd - datatables.net/license
|
3
3
|
*/
|
4
4
|
|
5
5
|
(function( factory ){
|
@@ -11,17 +11,33 @@
|
|
11
11
|
}
|
12
12
|
else if ( typeof exports === 'object' ) {
|
13
13
|
// CommonJS
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
var jq = require('jquery');
|
15
|
+
var cjsRequires = function (root, $) {
|
16
|
+
if ( ! $.fn.dataTable ) {
|
17
|
+
require('datatables.net')(root, $);
|
17
18
|
}
|
19
|
+
};
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
if (typeof window === 'undefined') {
|
22
|
+
module.exports = function (root, $) {
|
23
|
+
if ( ! root ) {
|
24
|
+
// CommonJS environments without a window global must pass a
|
25
|
+
// root. This will give an error otherwise
|
26
|
+
root = window;
|
27
|
+
}
|
22
28
|
|
23
|
-
|
24
|
-
|
29
|
+
if ( ! $ ) {
|
30
|
+
$ = jq( root );
|
31
|
+
}
|
32
|
+
|
33
|
+
cjsRequires( root, $ );
|
34
|
+
return factory( $, root, root.document );
|
35
|
+
};
|
36
|
+
}
|
37
|
+
else {
|
38
|
+
cjsRequires( window, jq );
|
39
|
+
module.exports = factory( jq, window, window.document );
|
40
|
+
}
|
25
41
|
}
|
26
42
|
else {
|
27
43
|
// Browser
|
@@ -32,6 +48,7 @@
|
|
32
48
|
var DataTable = $.fn.dataTable;
|
33
49
|
|
34
50
|
|
51
|
+
|
35
52
|
// Used for namespacing events added to the document by each instance, so they
|
36
53
|
// can be removed on destroy
|
37
54
|
var _instCounter = 0;
|
@@ -41,52 +58,85 @@ var _buttonCounter = 0;
|
|
41
58
|
|
42
59
|
var _dtButtons = DataTable.ext.buttons;
|
43
60
|
|
61
|
+
// Allow for jQuery slim
|
62
|
+
function _fadeIn(el, duration, fn) {
|
63
|
+
if ($.fn.animate) {
|
64
|
+
el.stop().fadeIn(duration, fn);
|
65
|
+
}
|
66
|
+
else {
|
67
|
+
el.css('display', 'block');
|
68
|
+
|
69
|
+
if (fn) {
|
70
|
+
fn.call(el);
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
function _fadeOut(el, duration, fn) {
|
76
|
+
if ($.fn.animate) {
|
77
|
+
el.stop().fadeOut(duration, fn);
|
78
|
+
}
|
79
|
+
else {
|
80
|
+
el.css('display', 'none');
|
81
|
+
|
82
|
+
if (fn) {
|
83
|
+
fn.call(el);
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
44
88
|
/**
|
45
89
|
* [Buttons description]
|
46
90
|
* @param {[type]}
|
47
91
|
* @param {[type]}
|
48
92
|
*/
|
49
|
-
var Buttons = function(
|
50
|
-
|
93
|
+
var Buttons = function (dt, config) {
|
94
|
+
// If not created with a `new` keyword then we return a wrapper function that
|
95
|
+
// will take the settings object for a DT. This allows easy use of new instances
|
96
|
+
// with the `layout` option - e.g. `topLeft: $.fn.dataTable.Buttons( ... )`.
|
97
|
+
if (!(this instanceof Buttons)) {
|
98
|
+
return function (settings) {
|
99
|
+
return new Buttons(settings, dt).container();
|
100
|
+
};
|
101
|
+
}
|
102
|
+
|
51
103
|
// If there is no config set it to an empty object
|
52
|
-
if (
|
104
|
+
if (typeof config === 'undefined') {
|
53
105
|
config = {};
|
54
106
|
}
|
55
107
|
|
56
108
|
// Allow a boolean true for defaults
|
57
|
-
if (
|
109
|
+
if (config === true) {
|
58
110
|
config = {};
|
59
111
|
}
|
60
112
|
|
61
113
|
// For easy configuration of buttons an array can be given
|
62
|
-
if (
|
114
|
+
if (Array.isArray(config)) {
|
63
115
|
config = { buttons: config };
|
64
116
|
}
|
65
117
|
|
66
|
-
this.c = $.extend(
|
118
|
+
this.c = $.extend(true, {}, Buttons.defaults, config);
|
67
119
|
|
68
120
|
// Don't want a deep copy for the buttons
|
69
|
-
if (
|
121
|
+
if (config.buttons) {
|
70
122
|
this.c.buttons = config.buttons;
|
71
123
|
}
|
72
124
|
|
73
125
|
this.s = {
|
74
|
-
dt: new DataTable.Api(
|
126
|
+
dt: new DataTable.Api(dt),
|
75
127
|
buttons: [],
|
76
128
|
listenKeys: '',
|
77
|
-
namespace: 'dtb'+
|
129
|
+
namespace: 'dtb' + _instCounter++
|
78
130
|
};
|
79
131
|
|
80
132
|
this.dom = {
|
81
|
-
container: $('<'+this.c.dom.container.tag+'/>')
|
82
|
-
.addClass( this.c.dom.container.className )
|
133
|
+
container: $('<' + this.c.dom.container.tag + '/>').addClass(this.c.dom.container.className)
|
83
134
|
};
|
84
135
|
|
85
136
|
this._constructor();
|
86
137
|
};
|
87
138
|
|
88
|
-
|
89
|
-
$.extend( Buttons.prototype, {
|
139
|
+
$.extend(Buttons.prototype, {
|
90
140
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
91
141
|
* Public methods
|
92
142
|
*/
|
@@ -95,17 +145,16 @@ $.extend( Buttons.prototype, {
|
|
95
145
|
* Get the action of a button
|
96
146
|
* @param {int|string} Button index
|
97
147
|
* @return {function}
|
98
|
-
|
148
|
+
*/ /**
|
99
149
|
* Set the action of a button
|
100
150
|
* @param {node} node Button element
|
101
151
|
* @param {function} action Function to set
|
102
152
|
* @return {Buttons} Self for chaining
|
103
153
|
*/
|
104
|
-
action: function (
|
105
|
-
|
106
|
-
var button = this._nodeToButton( node );
|
154
|
+
action: function (node, action) {
|
155
|
+
var button = this._nodeToButton(node);
|
107
156
|
|
108
|
-
if (
|
157
|
+
if (action === undefined) {
|
109
158
|
return button.conf.action;
|
110
159
|
}
|
111
160
|
|
@@ -121,16 +170,24 @@ $.extend( Buttons.prototype, {
|
|
121
170
|
* @param {boolean} [flag] Enable / disable flag
|
122
171
|
* @return {Buttons} Self for chaining or boolean for getter
|
123
172
|
*/
|
124
|
-
active: function (
|
125
|
-
var button = this._nodeToButton(
|
173
|
+
active: function (node, flag) {
|
174
|
+
var button = this._nodeToButton(node);
|
126
175
|
var klass = this.c.dom.button.active;
|
127
176
|
var jqNode = $(button.node);
|
128
177
|
|
129
|
-
if (
|
130
|
-
|
178
|
+
if (
|
179
|
+
button.inCollection &&
|
180
|
+
this.c.dom.collection.button &&
|
181
|
+
this.c.dom.collection.button.active !== undefined
|
182
|
+
) {
|
183
|
+
klass = this.c.dom.collection.button.active;
|
184
|
+
}
|
185
|
+
|
186
|
+
if (flag === undefined) {
|
187
|
+
return jqNode.hasClass(klass);
|
131
188
|
}
|
132
189
|
|
133
|
-
jqNode.toggleClass(
|
190
|
+
jqNode.toggleClass(klass, flag === undefined ? true : flag);
|
134
191
|
|
135
192
|
return this;
|
136
193
|
},
|
@@ -139,36 +196,89 @@ $.extend( Buttons.prototype, {
|
|
139
196
|
* Add a new button
|
140
197
|
* @param {object} config Button configuration object, base string name or function
|
141
198
|
* @param {int|string} [idx] Button index for where to insert the button
|
199
|
+
* @param {boolean} [draw=true] Trigger a draw. Set a false when adding
|
200
|
+
* lots of buttons, until the last button.
|
142
201
|
* @return {Buttons} Self for chaining
|
143
202
|
*/
|
144
|
-
add: function (
|
145
|
-
{
|
203
|
+
add: function (config, idx, draw) {
|
146
204
|
var buttons = this.s.buttons;
|
147
205
|
|
148
|
-
if (
|
206
|
+
if (typeof idx === 'string') {
|
149
207
|
var split = idx.split('-');
|
150
208
|
var base = this.s;
|
151
209
|
|
152
|
-
for (
|
153
|
-
base = base.buttons[
|
210
|
+
for (var i = 0, ien = split.length - 1; i < ien; i++) {
|
211
|
+
base = base.buttons[split[i] * 1];
|
154
212
|
}
|
155
213
|
|
156
214
|
buttons = base.buttons;
|
157
|
-
idx = split[
|
215
|
+
idx = split[split.length - 1] * 1;
|
158
216
|
}
|
159
217
|
|
160
|
-
this._expandButton(
|
161
|
-
|
218
|
+
this._expandButton(
|
219
|
+
buttons,
|
220
|
+
config,
|
221
|
+
config !== undefined ? config.split : undefined,
|
222
|
+
(config === undefined || config.split === undefined || config.split.length === 0) &&
|
223
|
+
base !== undefined,
|
224
|
+
false,
|
225
|
+
idx
|
226
|
+
);
|
227
|
+
|
228
|
+
if (draw === undefined || draw === true) {
|
229
|
+
this._draw();
|
230
|
+
}
|
162
231
|
|
163
232
|
return this;
|
164
233
|
},
|
165
234
|
|
235
|
+
/**
|
236
|
+
* Clear buttons from a collection and then insert new buttons
|
237
|
+
*/
|
238
|
+
collectionRebuild: function (node, newButtons) {
|
239
|
+
var button = this._nodeToButton(node);
|
240
|
+
|
241
|
+
if (newButtons !== undefined) {
|
242
|
+
var i;
|
243
|
+
// Need to reverse the array
|
244
|
+
for (i = button.buttons.length - 1; i >= 0; i--) {
|
245
|
+
this.remove(button.buttons[i].node);
|
246
|
+
}
|
247
|
+
|
248
|
+
// If the collection has prefix and / or postfix buttons we need to add them in
|
249
|
+
if (button.conf.prefixButtons) {
|
250
|
+
newButtons.unshift.apply(newButtons, button.conf.prefixButtons);
|
251
|
+
}
|
252
|
+
|
253
|
+
if (button.conf.postfixButtons) {
|
254
|
+
newButtons.push.apply(newButtons, button.conf.postfixButtons);
|
255
|
+
}
|
256
|
+
|
257
|
+
for (i = 0; i < newButtons.length; i++) {
|
258
|
+
var newBtn = newButtons[i];
|
259
|
+
|
260
|
+
this._expandButton(
|
261
|
+
button.buttons,
|
262
|
+
newBtn,
|
263
|
+
newBtn !== undefined &&
|
264
|
+
newBtn.config !== undefined &&
|
265
|
+
newBtn.config.split !== undefined,
|
266
|
+
true,
|
267
|
+
newBtn.parentConf !== undefined && newBtn.parentConf.split !== undefined,
|
268
|
+
null,
|
269
|
+
newBtn.parentConf
|
270
|
+
);
|
271
|
+
}
|
272
|
+
}
|
273
|
+
|
274
|
+
this._draw(button.collection, button.buttons);
|
275
|
+
},
|
276
|
+
|
166
277
|
/**
|
167
278
|
* Get the container node for the buttons
|
168
279
|
* @return {jQuery} Buttons node
|
169
280
|
*/
|
170
|
-
container: function ()
|
171
|
-
{
|
281
|
+
container: function () {
|
172
282
|
return this.dom.container;
|
173
283
|
},
|
174
284
|
|
@@ -177,10 +287,10 @@ $.extend( Buttons.prototype, {
|
|
177
287
|
* @param {node} node Button node
|
178
288
|
* @return {Buttons} Self for chaining
|
179
289
|
*/
|
180
|
-
disable: function (
|
181
|
-
var button = this._nodeToButton(
|
290
|
+
disable: function (node) {
|
291
|
+
var button = this._nodeToButton(node);
|
182
292
|
|
183
|
-
$(button.node).addClass(
|
293
|
+
$(button.node).addClass(this.c.dom.button.disabled).prop('disabled', true);
|
184
294
|
|
185
295
|
return this;
|
186
296
|
},
|
@@ -190,18 +300,17 @@ $.extend( Buttons.prototype, {
|
|
190
300
|
* elements
|
191
301
|
* @return {Buttons} Self for chaining
|
192
302
|
*/
|
193
|
-
destroy: function ()
|
194
|
-
{
|
303
|
+
destroy: function () {
|
195
304
|
// Key event listener
|
196
|
-
$('body').off(
|
305
|
+
$('body').off('keyup.' + this.s.namespace);
|
197
306
|
|
198
307
|
// Individual button destroy (so they can remove their own events if
|
199
308
|
// needed). Take a copy as the array is modified by `remove`
|
200
309
|
var buttons = this.s.buttons.slice();
|
201
310
|
var i, ien;
|
202
311
|
|
203
|
-
for (
|
204
|
-
this.remove(
|
312
|
+
for (i = 0, ien = buttons.length; i < ien; i++) {
|
313
|
+
this.remove(buttons[i].node);
|
205
314
|
}
|
206
315
|
|
207
316
|
// Container
|
@@ -210,9 +319,9 @@ $.extend( Buttons.prototype, {
|
|
210
319
|
// Remove from the settings object collection
|
211
320
|
var buttonInsts = this.s.dt.settings()[0];
|
212
321
|
|
213
|
-
for (
|
214
|
-
if (
|
215
|
-
buttonInsts.splice(
|
322
|
+
for (i = 0, ien = buttonInsts.length; i < ien; i++) {
|
323
|
+
if (buttonInsts.inst === this) {
|
324
|
+
buttonInsts.splice(i, 1);
|
216
325
|
break;
|
217
326
|
}
|
218
327
|
}
|
@@ -226,52 +335,94 @@ $.extend( Buttons.prototype, {
|
|
226
335
|
* @param {boolean} [flag=true] Enable / disable flag
|
227
336
|
* @return {Buttons} Self for chaining
|
228
337
|
*/
|
229
|
-
enable: function (
|
230
|
-
|
231
|
-
|
232
|
-
return this.disable( node );
|
338
|
+
enable: function (node, flag) {
|
339
|
+
if (flag === false) {
|
340
|
+
return this.disable(node);
|
233
341
|
}
|
234
342
|
|
235
|
-
var button = this._nodeToButton(
|
236
|
-
$(button.node).removeClass(
|
343
|
+
var button = this._nodeToButton(node);
|
344
|
+
$(button.node).removeClass(this.c.dom.button.disabled).prop('disabled', false);
|
237
345
|
|
238
346
|
return this;
|
239
347
|
},
|
240
348
|
|
349
|
+
/**
|
350
|
+
* Get a button's index
|
351
|
+
*
|
352
|
+
* This is internally recursive
|
353
|
+
* @param {element} node Button to get the index of
|
354
|
+
* @return {string} Button index
|
355
|
+
*/
|
356
|
+
index: function (node, nested, buttons) {
|
357
|
+
if (!nested) {
|
358
|
+
nested = '';
|
359
|
+
buttons = this.s.buttons;
|
360
|
+
}
|
361
|
+
|
362
|
+
for (var i = 0, ien = buttons.length; i < ien; i++) {
|
363
|
+
var inner = buttons[i].buttons;
|
364
|
+
|
365
|
+
if (buttons[i].node === node) {
|
366
|
+
return nested + i;
|
367
|
+
}
|
368
|
+
|
369
|
+
if (inner && inner.length) {
|
370
|
+
var match = this.index(node, i + '-', inner);
|
371
|
+
|
372
|
+
if (match !== null) {
|
373
|
+
return match;
|
374
|
+
}
|
375
|
+
}
|
376
|
+
}
|
377
|
+
|
378
|
+
return null;
|
379
|
+
},
|
380
|
+
|
241
381
|
/**
|
242
382
|
* Get the instance name for the button set selector
|
243
383
|
* @return {string} Instance name
|
244
384
|
*/
|
245
|
-
name: function ()
|
246
|
-
{
|
385
|
+
name: function () {
|
247
386
|
return this.c.name;
|
248
387
|
},
|
249
388
|
|
250
389
|
/**
|
251
|
-
* Get a button's node
|
252
|
-
* @param {node} node Button node
|
253
|
-
* @return {jQuery} Button element
|
390
|
+
* Get a button's node of the buttons container if no button is given
|
391
|
+
* @param {node} [node] Button node
|
392
|
+
* @return {jQuery} Button element, or container
|
254
393
|
*/
|
255
|
-
node: function (
|
256
|
-
|
257
|
-
|
394
|
+
node: function (node) {
|
395
|
+
if (!node) {
|
396
|
+
return this.dom.container;
|
397
|
+
}
|
398
|
+
|
399
|
+
var button = this._nodeToButton(node);
|
258
400
|
return $(button.node);
|
259
401
|
},
|
260
402
|
|
261
403
|
/**
|
262
404
|
* Set / get a processing class on the selected button
|
405
|
+
* @param {element} node Triggering button node
|
263
406
|
* @param {boolean} flag true to add, false to remove, undefined to get
|
264
407
|
* @return {boolean|Buttons} Getter value or this if a setter.
|
265
408
|
*/
|
266
|
-
processing: function (
|
267
|
-
|
268
|
-
var button = this._nodeToButton(
|
409
|
+
processing: function (node, flag) {
|
410
|
+
var dt = this.s.dt;
|
411
|
+
var button = this._nodeToButton(node);
|
269
412
|
|
270
|
-
if (
|
271
|
-
return $(button.node).hasClass(
|
413
|
+
if (flag === undefined) {
|
414
|
+
return $(button.node).hasClass('processing');
|
272
415
|
}
|
273
416
|
|
274
|
-
$(button.node).toggleClass(
|
417
|
+
$(button.node).toggleClass('processing', flag);
|
418
|
+
|
419
|
+
$(dt.table().node()).triggerHandler('buttons-processing.dt', [
|
420
|
+
flag,
|
421
|
+
dt.button(node),
|
422
|
+
dt,
|
423
|
+
$(node),
|
424
|
+
button.conf
|
425
|
+
]);
|
275
426
|
|
276
427
|
return this;
|
277
428
|
},
|
@@ -281,30 +432,31 @@ $.extend( Buttons.prototype, {
|
|
281
432
|
* @param {node} node Button node
|
282
433
|
* @return {Buttons} Self for chaining
|
283
434
|
*/
|
284
|
-
remove: function (
|
285
|
-
|
286
|
-
var
|
287
|
-
var host = this._nodeToHost( node );
|
435
|
+
remove: function (node) {
|
436
|
+
var button = this._nodeToButton(node);
|
437
|
+
var host = this._nodeToHost(node);
|
288
438
|
var dt = this.s.dt;
|
289
439
|
|
290
440
|
// Remove any child buttons first
|
291
|
-
if (
|
292
|
-
for (
|
293
|
-
this.remove(
|
441
|
+
if (button.buttons.length) {
|
442
|
+
for (var i = button.buttons.length - 1; i >= 0; i--) {
|
443
|
+
this.remove(button.buttons[i].node);
|
294
444
|
}
|
295
445
|
}
|
296
446
|
|
447
|
+
button.conf.destroying = true;
|
448
|
+
|
297
449
|
// Allow the button to remove event handlers, etc
|
298
|
-
if (
|
299
|
-
button.conf.destroy.call(
|
450
|
+
if (button.conf.destroy) {
|
451
|
+
button.conf.destroy.call(dt.button(node), dt, $(node), button.conf);
|
300
452
|
}
|
301
453
|
|
302
|
-
this._removeKey(
|
454
|
+
this._removeKey(button.conf);
|
303
455
|
|
304
456
|
$(button.node).remove();
|
305
457
|
|
306
|
-
var idx = $.inArray(
|
307
|
-
host.splice(
|
458
|
+
var idx = $.inArray(button, host);
|
459
|
+
host.splice(idx, 1);
|
308
460
|
|
309
461
|
return this;
|
310
462
|
},
|
@@ -313,44 +465,31 @@ $.extend( Buttons.prototype, {
|
|
313
465
|
* Get the text for a button
|
314
466
|
* @param {int|string} node Button index
|
315
467
|
* @return {string} Button text
|
316
|
-
|
468
|
+
*/ /**
|
317
469
|
* Set the text for a button
|
318
470
|
* @param {int|string|function} node Button index
|
319
471
|
* @param {string} label Text
|
320
472
|
* @return {Buttons} Self for chaining
|
321
473
|
*/
|
322
|
-
text: function (
|
323
|
-
|
324
|
-
var
|
325
|
-
var buttonLiner = this.c.dom.collection.buttonLiner;
|
326
|
-
var linerTag = button.inCollection && buttonLiner && buttonLiner.tag ?
|
327
|
-
buttonLiner.tag :
|
328
|
-
this.c.dom.buttonLiner.tag;
|
474
|
+
text: function (node, label) {
|
475
|
+
var button = this._nodeToButton(node);
|
476
|
+
var textNode = button.textNode;
|
329
477
|
var dt = this.s.dt;
|
330
478
|
var jqNode = $(button.node);
|
331
|
-
var text = function (
|
332
|
-
return typeof opt === 'function' ?
|
333
|
-
opt( dt, jqNode, button.conf ) :
|
334
|
-
opt;
|
479
|
+
var text = function (opt) {
|
480
|
+
return typeof opt === 'function' ? opt(dt, jqNode, button.conf) : opt;
|
335
481
|
};
|
336
482
|
|
337
|
-
if (
|
338
|
-
return text(
|
483
|
+
if (label === undefined) {
|
484
|
+
return text(button.conf.text);
|
339
485
|
}
|
340
486
|
|
341
487
|
button.conf.text = label;
|
342
|
-
|
343
|
-
if ( linerTag ) {
|
344
|
-
jqNode.children( linerTag ).html( text(label) );
|
345
|
-
}
|
346
|
-
else {
|
347
|
-
jqNode.html( text(label) );
|
348
|
-
}
|
488
|
+
textNode.html(text(label));
|
349
489
|
|
350
490
|
return this;
|
351
491
|
},
|
352
492
|
|
353
|
-
|
354
493
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
355
494
|
* Constructor
|
356
495
|
*/
|
@@ -359,47 +498,45 @@ $.extend( Buttons.prototype, {
|
|
359
498
|
* Buttons constructor
|
360
499
|
* @private
|
361
500
|
*/
|
362
|
-
_constructor: function ()
|
363
|
-
{
|
501
|
+
_constructor: function () {
|
364
502
|
var that = this;
|
365
503
|
var dt = this.s.dt;
|
366
504
|
var dtSettings = dt.settings()[0];
|
367
|
-
var buttons =
|
505
|
+
var buttons = this.c.buttons;
|
368
506
|
|
369
|
-
if (
|
507
|
+
if (!dtSettings._buttons) {
|
370
508
|
dtSettings._buttons = [];
|
371
509
|
}
|
372
510
|
|
373
|
-
dtSettings._buttons.push(
|
511
|
+
dtSettings._buttons.push({
|
374
512
|
inst: this,
|
375
513
|
name: this.c.name
|
376
|
-
}
|
514
|
+
});
|
377
515
|
|
378
|
-
for (
|
379
|
-
this.add(
|
516
|
+
for (var i = 0, ien = buttons.length; i < ien; i++) {
|
517
|
+
this.add(buttons[i]);
|
380
518
|
}
|
381
519
|
|
382
|
-
dt.on(
|
383
|
-
if (
|
520
|
+
dt.on('destroy', function (e, settings) {
|
521
|
+
if (settings === dtSettings) {
|
384
522
|
that.destroy();
|
385
523
|
}
|
386
|
-
}
|
524
|
+
});
|
387
525
|
|
388
526
|
// Global key event binding to listen for button keys
|
389
|
-
$('body').on(
|
390
|
-
if (
|
527
|
+
$('body').on('keyup.' + this.s.namespace, function (e) {
|
528
|
+
if (!document.activeElement || document.activeElement === document.body) {
|
391
529
|
// SUse a string of characters for fast lookup of if we need to
|
392
530
|
// handle this
|
393
531
|
var character = String.fromCharCode(e.keyCode).toLowerCase();
|
394
532
|
|
395
|
-
if (
|
396
|
-
that._keypress(
|
533
|
+
if (that.s.listenKeys.toLowerCase().indexOf(character) !== -1) {
|
534
|
+
that._keypress(character, e);
|
397
535
|
}
|
398
536
|
}
|
399
|
-
}
|
537
|
+
});
|
400
538
|
},
|
401
539
|
|
402
|
-
|
403
540
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
404
541
|
* Private methods
|
405
542
|
*/
|
@@ -409,12 +546,9 @@ $.extend( Buttons.prototype, {
|
|
409
546
|
* @param {object} conf Resolved button configuration object
|
410
547
|
* @private
|
411
548
|
*/
|
412
|
-
_addKey: function (
|
413
|
-
|
414
|
-
|
415
|
-
this.s.listenKeys += $.isPlainObject( conf.key ) ?
|
416
|
-
conf.key.key :
|
417
|
-
conf.key;
|
549
|
+
_addKey: function (conf) {
|
550
|
+
if (conf.key) {
|
551
|
+
this.s.listenKeys += $.isPlainObject(conf.key) ? conf.key.key : conf.key;
|
418
552
|
}
|
419
553
|
},
|
420
554
|
|
@@ -424,21 +558,20 @@ $.extend( Buttons.prototype, {
|
|
424
558
|
* @param {array} [buttons] Recursive only - Buttons array
|
425
559
|
* @private
|
426
560
|
*/
|
427
|
-
_draw: function (
|
428
|
-
|
429
|
-
if ( ! container ) {
|
561
|
+
_draw: function (container, buttons) {
|
562
|
+
if (!container) {
|
430
563
|
container = this.dom.container;
|
431
564
|
buttons = this.s.buttons;
|
432
565
|
}
|
433
566
|
|
434
567
|
container.children().detach();
|
435
568
|
|
436
|
-
for (
|
437
|
-
container.append(
|
438
|
-
container.append(
|
569
|
+
for (var i = 0, ien = buttons.length; i < ien; i++) {
|
570
|
+
container.append(buttons[i].inserter);
|
571
|
+
container.append(' ');
|
439
572
|
|
440
|
-
if (
|
441
|
-
this._draw(
|
573
|
+
if (buttons[i].buttons && buttons[i].buttons.length) {
|
574
|
+
this._draw(buttons[i].collection, buttons[i].buttons);
|
442
575
|
}
|
443
576
|
}
|
444
577
|
},
|
@@ -450,58 +583,128 @@ $.extend( Buttons.prototype, {
|
|
450
583
|
* @param {boolean} inCollection true if the button is in a collection
|
451
584
|
* @private
|
452
585
|
*/
|
453
|
-
_expandButton: function (
|
454
|
-
|
586
|
+
_expandButton: function (
|
587
|
+
attachTo,
|
588
|
+
button,
|
589
|
+
split,
|
590
|
+
inCollection,
|
591
|
+
inSplit,
|
592
|
+
attachPoint,
|
593
|
+
parentConf
|
594
|
+
) {
|
455
595
|
var dt = this.s.dt;
|
456
|
-
var
|
457
|
-
var
|
458
|
-
|
459
|
-
|
596
|
+
var isSplit = false;
|
597
|
+
var domCollection = this.c.dom.collection;
|
598
|
+
var buttons = !Array.isArray(button) ? [button] : button;
|
599
|
+
|
600
|
+
if (button === undefined) {
|
601
|
+
buttons = !Array.isArray(split) ? [split] : split;
|
602
|
+
}
|
460
603
|
|
461
|
-
for (
|
462
|
-
var conf = this._resolveExtends(
|
604
|
+
for (var i = 0, ien = buttons.length; i < ien; i++) {
|
605
|
+
var conf = this._resolveExtends(buttons[i]);
|
463
606
|
|
464
|
-
if (
|
607
|
+
if (!conf) {
|
465
608
|
continue;
|
466
609
|
}
|
467
610
|
|
611
|
+
isSplit = conf.config && conf.config.split ? true : false;
|
612
|
+
|
468
613
|
// If the configuration is an array, then expand the buttons at this
|
469
614
|
// point
|
470
|
-
if (
|
471
|
-
this._expandButton(
|
615
|
+
if (Array.isArray(conf)) {
|
616
|
+
this._expandButton(
|
617
|
+
attachTo,
|
618
|
+
conf,
|
619
|
+
built !== undefined && built.conf !== undefined ? built.conf.split : undefined,
|
620
|
+
inCollection,
|
621
|
+
parentConf !== undefined && parentConf.split !== undefined,
|
622
|
+
attachPoint,
|
623
|
+
parentConf
|
624
|
+
);
|
472
625
|
continue;
|
473
626
|
}
|
474
627
|
|
475
|
-
var built = this._buildButton(
|
476
|
-
|
628
|
+
var built = this._buildButton(
|
629
|
+
conf,
|
630
|
+
inCollection,
|
631
|
+
conf.split !== undefined ||
|
632
|
+
(conf.config !== undefined && conf.config.split !== undefined),
|
633
|
+
inSplit
|
634
|
+
);
|
635
|
+
if (!built) {
|
477
636
|
continue;
|
478
637
|
}
|
479
638
|
|
480
|
-
if (
|
481
|
-
attachTo.splice(
|
639
|
+
if (attachPoint !== undefined && attachPoint !== null) {
|
640
|
+
attachTo.splice(attachPoint, 0, built);
|
482
641
|
attachPoint++;
|
483
642
|
}
|
484
643
|
else {
|
485
|
-
attachTo.push(
|
644
|
+
attachTo.push(built);
|
486
645
|
}
|
487
646
|
|
488
|
-
|
489
|
-
|
490
|
-
built.collection = $('<'+
|
491
|
-
.addClass( collectionDom.className )
|
492
|
-
.attr( 'role', 'menu' ) ;
|
647
|
+
// Create the dropdown for a collection
|
648
|
+
if (built.conf.buttons) {
|
649
|
+
built.collection = $('<' + domCollection.container.content.tag + '/>');
|
493
650
|
built.conf._collection = built.collection;
|
494
651
|
|
495
|
-
|
652
|
+
$(built.node).append(domCollection.action.dropHtml);
|
653
|
+
|
654
|
+
this._expandButton(
|
655
|
+
built.buttons,
|
656
|
+
built.conf.buttons,
|
657
|
+
built.conf.split,
|
658
|
+
!isSplit,
|
659
|
+
isSplit,
|
660
|
+
attachPoint,
|
661
|
+
built.conf
|
662
|
+
);
|
663
|
+
}
|
664
|
+
|
665
|
+
// And the split collection
|
666
|
+
if (built.conf.split) {
|
667
|
+
built.collection = $('<' + domCollection.container.tag + '/>');
|
668
|
+
built.conf._collection = built.collection;
|
669
|
+
|
670
|
+
for (var j = 0; j < built.conf.split.length; j++) {
|
671
|
+
var item = built.conf.split[j];
|
672
|
+
|
673
|
+
if (typeof item === 'object') {
|
674
|
+
item.parent = parentConf;
|
675
|
+
|
676
|
+
if (item.collectionLayout === undefined) {
|
677
|
+
item.collectionLayout = built.conf.collectionLayout;
|
678
|
+
}
|
679
|
+
|
680
|
+
if (item.dropup === undefined) {
|
681
|
+
item.dropup = built.conf.dropup;
|
682
|
+
}
|
683
|
+
|
684
|
+
if (item.fade === undefined) {
|
685
|
+
item.fade = built.conf.fade;
|
686
|
+
}
|
687
|
+
}
|
688
|
+
}
|
689
|
+
|
690
|
+
this._expandButton(
|
691
|
+
built.buttons,
|
692
|
+
built.conf.buttons,
|
693
|
+
built.conf.split,
|
694
|
+
!isSplit,
|
695
|
+
isSplit,
|
696
|
+
attachPoint,
|
697
|
+
built.conf
|
698
|
+
);
|
496
699
|
}
|
497
700
|
|
701
|
+
built.conf.parent = parentConf;
|
702
|
+
|
498
703
|
// init call is made here, rather than buildButton as it needs to
|
499
704
|
// be selectable, and for that it needs to be in the buttons array
|
500
|
-
if (
|
501
|
-
conf.init.call(
|
705
|
+
if (conf.init) {
|
706
|
+
conf.init.call(dt.button(built.node), dt, $(built.node), conf);
|
502
707
|
}
|
503
|
-
|
504
|
-
buttonCounter++;
|
505
708
|
}
|
506
709
|
},
|
507
710
|
|
@@ -509,130 +712,253 @@ $.extend( Buttons.prototype, {
|
|
509
712
|
* Create an individual button
|
510
713
|
* @param {object} config Resolved button configuration
|
511
714
|
* @param {boolean} inCollection `true` if a collection button
|
512
|
-
* @return {
|
715
|
+
* @return {object} Completed button description object
|
513
716
|
* @private
|
514
717
|
*/
|
515
|
-
_buildButton: function (
|
516
|
-
|
517
|
-
var
|
518
|
-
var linerDom = this.c.dom.buttonLiner;
|
519
|
-
var collectionDom = this.c.dom.collection;
|
718
|
+
_buildButton: function (config, inCollection, isSplit, inSplit) {
|
719
|
+
var configDom = this.c.dom;
|
720
|
+
var textNode;
|
520
721
|
var dt = this.s.dt;
|
521
|
-
var text = function (
|
522
|
-
return typeof opt === 'function' ?
|
523
|
-
opt( dt, button, config ) :
|
524
|
-
opt;
|
722
|
+
var text = function (opt) {
|
723
|
+
return typeof opt === 'function' ? opt(dt, button, config) : opt;
|
525
724
|
};
|
526
725
|
|
527
|
-
|
528
|
-
|
726
|
+
// Create an object that describes the button which can be in `dom.button`, or
|
727
|
+
// `dom.collection.button` or `dom.split.button` or `dom.collection.split.button`!
|
728
|
+
// Each should extend from `dom.button`.
|
729
|
+
var dom = $.extend(true, {}, configDom.button);
|
730
|
+
|
731
|
+
if (inCollection && isSplit && configDom.collection.split) {
|
732
|
+
$.extend(true, dom, configDom.collection.split.action);
|
733
|
+
}
|
734
|
+
else if (inSplit || inCollection) {
|
735
|
+
$.extend(true, dom, configDom.collection.button);
|
529
736
|
}
|
737
|
+
else if (isSplit) {
|
738
|
+
$.extend(true, dom, configDom.split.button);
|
739
|
+
}
|
740
|
+
|
741
|
+
// Spacers don't do much other than insert an element into the DOM
|
742
|
+
if (config.spacer) {
|
743
|
+
var spacer = $('<' + dom.spacer.tag + '/>')
|
744
|
+
.addClass('dt-button-spacer ' + config.style + ' ' + dom.spacer.className)
|
745
|
+
.html(text(config.text));
|
530
746
|
|
531
|
-
|
532
|
-
|
747
|
+
return {
|
748
|
+
conf: config,
|
749
|
+
node: spacer,
|
750
|
+
inserter: spacer,
|
751
|
+
buttons: [],
|
752
|
+
inCollection: inCollection,
|
753
|
+
isSplit: isSplit,
|
754
|
+
collection: null,
|
755
|
+
textNode: spacer
|
756
|
+
};
|
533
757
|
}
|
534
758
|
|
535
759
|
// Make sure that the button is available based on whatever requirements
|
536
|
-
// it has. For example,
|
537
|
-
if (
|
760
|
+
// it has. For example, PDF button require pdfmake
|
761
|
+
if (config.available && !config.available(dt, config) && !config.hasOwnProperty('html')) {
|
538
762
|
return false;
|
539
763
|
}
|
540
764
|
|
541
|
-
var
|
542
|
-
config.action.call( dt.button( button ), e, dt, button, config );
|
765
|
+
var button;
|
543
766
|
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
};
|
767
|
+
if (!config.hasOwnProperty('html')) {
|
768
|
+
var action = function (e, dt, button, config) {
|
769
|
+
config.action.call(dt.button(button), e, dt, button, config);
|
548
770
|
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
771
|
+
$(dt.table().node()).triggerHandler('buttons-action.dt', [
|
772
|
+
dt.button(button),
|
773
|
+
dt,
|
774
|
+
button,
|
775
|
+
config
|
776
|
+
]);
|
777
|
+
};
|
556
778
|
|
557
|
-
|
558
|
-
|
559
|
-
}
|
779
|
+
var tag = config.tag || dom.tag;
|
780
|
+
var clickBlurs = config.clickBlurs === undefined ? true : config.clickBlurs;
|
560
781
|
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
782
|
+
button = $('<' + tag + '/>')
|
783
|
+
.addClass(dom.className)
|
784
|
+
.attr('tabindex', this.s.dt.settings()[0].iTabIndex)
|
785
|
+
.attr('aria-controls', this.s.dt.table().node().id)
|
786
|
+
.on('click.dtb', function (e) {
|
787
|
+
e.preventDefault();
|
788
|
+
|
789
|
+
if (!button.hasClass(dom.disabled) && config.action) {
|
790
|
+
action(e, dt, button, config);
|
567
791
|
}
|
568
|
-
}
|
569
|
-
} );
|
570
792
|
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
793
|
+
if (clickBlurs) {
|
794
|
+
button.trigger('blur');
|
795
|
+
}
|
796
|
+
})
|
797
|
+
.on('keypress.dtb', function (e) {
|
798
|
+
if (e.keyCode === 13) {
|
799
|
+
e.preventDefault();
|
575
800
|
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
801
|
+
if (!button.hasClass(dom.disabled) && config.action) {
|
802
|
+
action(e, dt, button, config);
|
803
|
+
}
|
804
|
+
}
|
805
|
+
});
|
580
806
|
|
581
|
-
|
582
|
-
|
583
|
-
.
|
584
|
-
|
807
|
+
// Make `a` tags act like a link
|
808
|
+
if (tag.toLowerCase() === 'a') {
|
809
|
+
button.attr('href', '#');
|
810
|
+
}
|
585
811
|
|
586
|
-
|
587
|
-
|
812
|
+
// Button tags should have `type=button` so they don't have any default behaviour
|
813
|
+
if (tag.toLowerCase() === 'button') {
|
814
|
+
button.attr('type', 'button');
|
588
815
|
}
|
589
816
|
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
}
|
817
|
+
if (dom.liner.tag) {
|
818
|
+
var liner = $('<' + dom.liner.tag + '/>')
|
819
|
+
.html(text(config.text))
|
820
|
+
.addClass(dom.liner.className);
|
595
821
|
|
596
|
-
|
597
|
-
|
598
|
-
|
822
|
+
if (dom.liner.tag.toLowerCase() === 'a') {
|
823
|
+
liner.attr('href', '#');
|
824
|
+
}
|
599
825
|
|
600
|
-
|
601
|
-
|
602
|
-
|
826
|
+
button.append(liner);
|
827
|
+
textNode = liner;
|
828
|
+
}
|
829
|
+
else {
|
830
|
+
button.html(text(config.text));
|
831
|
+
textNode = button;
|
832
|
+
}
|
603
833
|
|
604
|
-
|
605
|
-
|
606
|
-
|
834
|
+
if (config.enabled === false) {
|
835
|
+
button.addClass(dom.disabled);
|
836
|
+
}
|
607
837
|
|
608
|
-
|
609
|
-
|
610
|
-
|
838
|
+
if (config.className) {
|
839
|
+
button.addClass(config.className);
|
840
|
+
}
|
841
|
+
|
842
|
+
if (config.titleAttr) {
|
843
|
+
button.attr('title', text(config.titleAttr));
|
844
|
+
}
|
845
|
+
|
846
|
+
if (config.attr) {
|
847
|
+
button.attr(config.attr);
|
848
|
+
}
|
849
|
+
|
850
|
+
if (!config.namespace) {
|
851
|
+
config.namespace = '.dt-button-' + _buttonCounter++;
|
852
|
+
}
|
611
853
|
|
612
|
-
|
613
|
-
|
854
|
+
if (config.config !== undefined && config.config.split) {
|
855
|
+
config.split = config.config.split;
|
856
|
+
}
|
857
|
+
}
|
858
|
+
else {
|
859
|
+
button = $(config.html);
|
614
860
|
}
|
615
861
|
|
616
862
|
var buttonContainer = this.c.dom.buttonContainer;
|
617
863
|
var inserter;
|
618
|
-
if (
|
619
|
-
inserter = $('<'+buttonContainer.tag+'/>')
|
620
|
-
.addClass(
|
621
|
-
.append(
|
864
|
+
if (buttonContainer && buttonContainer.tag) {
|
865
|
+
inserter = $('<' + buttonContainer.tag + '/>')
|
866
|
+
.addClass(buttonContainer.className)
|
867
|
+
.append(button);
|
622
868
|
}
|
623
869
|
else {
|
624
870
|
inserter = button;
|
625
871
|
}
|
626
872
|
|
627
|
-
this._addKey(
|
873
|
+
this._addKey(config);
|
874
|
+
|
875
|
+
// Style integration callback for DOM manipulation
|
876
|
+
// Note that this is _not_ documented. It is currently
|
877
|
+
// for style integration only
|
878
|
+
if (this.c.buttonCreated) {
|
879
|
+
inserter = this.c.buttonCreated(config, inserter);
|
880
|
+
}
|
881
|
+
|
882
|
+
var splitDiv;
|
883
|
+
|
884
|
+
if (isSplit) {
|
885
|
+
var dropdownConf = inCollection
|
886
|
+
? $.extend(true, this.c.dom.split, this.c.dom.collection.split)
|
887
|
+
: this.c.dom.split;
|
888
|
+
var wrapperConf = dropdownConf.wrapper;
|
889
|
+
|
890
|
+
splitDiv = $('<' + wrapperConf.tag + '/>')
|
891
|
+
.addClass(wrapperConf.className)
|
892
|
+
.append(button);
|
893
|
+
|
894
|
+
var dropButtonConfig = $.extend(config, {
|
895
|
+
align: dropdownConf.dropdown.align,
|
896
|
+
attr: {
|
897
|
+
'aria-haspopup': 'dialog',
|
898
|
+
'aria-expanded': false
|
899
|
+
},
|
900
|
+
className: dropdownConf.dropdown.className,
|
901
|
+
closeButton: false,
|
902
|
+
splitAlignClass: dropdownConf.dropdown.splitAlignClass,
|
903
|
+
text: dropdownConf.dropdown.text
|
904
|
+
});
|
905
|
+
|
906
|
+
this._addKey(dropButtonConfig);
|
907
|
+
|
908
|
+
var splitAction = function (e, dt, button, config) {
|
909
|
+
_dtButtons.split.action.call(dt.button(splitDiv), e, dt, button, config);
|
910
|
+
|
911
|
+
$(dt.table().node()).triggerHandler('buttons-action.dt', [
|
912
|
+
dt.button(button),
|
913
|
+
dt,
|
914
|
+
button,
|
915
|
+
config
|
916
|
+
]);
|
917
|
+
button.attr('aria-expanded', true);
|
918
|
+
};
|
919
|
+
|
920
|
+
var dropButton = $(
|
921
|
+
'<button class="' + dropdownConf.dropdown.className + ' dt-button"></button>'
|
922
|
+
)
|
923
|
+
.html(dropdownConf.dropdown.dropHtml)
|
924
|
+
.on('click.dtb', function (e) {
|
925
|
+
e.preventDefault();
|
926
|
+
e.stopPropagation();
|
927
|
+
|
928
|
+
if (!dropButton.hasClass(dom.disabled)) {
|
929
|
+
splitAction(e, dt, dropButton, dropButtonConfig);
|
930
|
+
}
|
931
|
+
if (clickBlurs) {
|
932
|
+
dropButton.trigger('blur');
|
933
|
+
}
|
934
|
+
})
|
935
|
+
.on('keypress.dtb', function (e) {
|
936
|
+
if (e.keyCode === 13) {
|
937
|
+
e.preventDefault();
|
938
|
+
|
939
|
+
if (!dropButton.hasClass(dom.disabled)) {
|
940
|
+
splitAction(e, dt, dropButton, dropButtonConfig);
|
941
|
+
}
|
942
|
+
}
|
943
|
+
});
|
944
|
+
|
945
|
+
if (config.split.length === 0) {
|
946
|
+
dropButton.addClass('dtb-hide-drop');
|
947
|
+
}
|
948
|
+
|
949
|
+
splitDiv.append(dropButton).attr(dropButtonConfig.attr);
|
950
|
+
}
|
628
951
|
|
629
952
|
return {
|
630
|
-
conf:
|
631
|
-
node:
|
632
|
-
inserter:
|
633
|
-
buttons:
|
953
|
+
conf: config,
|
954
|
+
node: isSplit ? splitDiv.get(0) : button.get(0),
|
955
|
+
inserter: isSplit ? splitDiv : inserter,
|
956
|
+
buttons: [],
|
634
957
|
inCollection: inCollection,
|
635
|
-
|
958
|
+
isSplit: isSplit,
|
959
|
+
inSplit: inSplit,
|
960
|
+
collection: null,
|
961
|
+
textNode: textNode
|
636
962
|
};
|
637
963
|
},
|
638
964
|
|
@@ -643,21 +969,20 @@ $.extend( Buttons.prototype, {
|
|
643
969
|
* @return {object} Button object
|
644
970
|
* @private
|
645
971
|
*/
|
646
|
-
_nodeToButton: function (
|
647
|
-
|
648
|
-
if ( ! buttons ) {
|
972
|
+
_nodeToButton: function (node, buttons) {
|
973
|
+
if (!buttons) {
|
649
974
|
buttons = this.s.buttons;
|
650
975
|
}
|
651
976
|
|
652
|
-
for (
|
653
|
-
if (
|
977
|
+
for (var i = 0, ien = buttons.length; i < ien; i++) {
|
978
|
+
if (buttons[i].node === node) {
|
654
979
|
return buttons[i];
|
655
980
|
}
|
656
981
|
|
657
|
-
if (
|
658
|
-
var ret = this._nodeToButton(
|
982
|
+
if (buttons[i].buttons.length) {
|
983
|
+
var ret = this._nodeToButton(node, buttons[i].buttons);
|
659
984
|
|
660
|
-
if (
|
985
|
+
if (ret) {
|
661
986
|
return ret;
|
662
987
|
}
|
663
988
|
}
|
@@ -671,21 +996,20 @@ $.extend( Buttons.prototype, {
|
|
671
996
|
* @return {array} Button's host array
|
672
997
|
* @private
|
673
998
|
*/
|
674
|
-
_nodeToHost: function (
|
675
|
-
|
676
|
-
if ( ! buttons ) {
|
999
|
+
_nodeToHost: function (node, buttons) {
|
1000
|
+
if (!buttons) {
|
677
1001
|
buttons = this.s.buttons;
|
678
1002
|
}
|
679
1003
|
|
680
|
-
for (
|
681
|
-
if (
|
1004
|
+
for (var i = 0, ien = buttons.length; i < ien; i++) {
|
1005
|
+
if (buttons[i].node === node) {
|
682
1006
|
return buttons;
|
683
1007
|
}
|
684
1008
|
|
685
|
-
if (
|
686
|
-
var ret = this._nodeToHost(
|
1009
|
+
if (buttons[i].buttons.length) {
|
1010
|
+
var ret = this._nodeToHost(node, buttons[i].buttons);
|
687
1011
|
|
688
|
-
if (
|
1012
|
+
if (ret) {
|
689
1013
|
return ret;
|
690
1014
|
}
|
691
1015
|
}
|
@@ -699,40 +1023,39 @@ $.extend( Buttons.prototype, {
|
|
699
1023
|
* @param {object} e Key event that triggered this call
|
700
1024
|
* @private
|
701
1025
|
*/
|
702
|
-
_keypress: function (
|
703
|
-
{
|
1026
|
+
_keypress: function (character, e) {
|
704
1027
|
// Check if this button press already activated on another instance of Buttons
|
705
|
-
if (
|
1028
|
+
if (e._buttonsHandled) {
|
706
1029
|
return;
|
707
1030
|
}
|
708
1031
|
|
709
|
-
var run = function (
|
710
|
-
if (
|
1032
|
+
var run = function (conf, node) {
|
1033
|
+
if (!conf.key) {
|
711
1034
|
return;
|
712
1035
|
}
|
713
1036
|
|
714
|
-
if (
|
1037
|
+
if (conf.key === character) {
|
715
1038
|
e._buttonsHandled = true;
|
716
1039
|
$(node).click();
|
717
1040
|
}
|
718
|
-
else if (
|
719
|
-
if (
|
1041
|
+
else if ($.isPlainObject(conf.key)) {
|
1042
|
+
if (conf.key.key !== character) {
|
720
1043
|
return;
|
721
1044
|
}
|
722
1045
|
|
723
|
-
if (
|
1046
|
+
if (conf.key.shiftKey && !e.shiftKey) {
|
724
1047
|
return;
|
725
1048
|
}
|
726
1049
|
|
727
|
-
if (
|
1050
|
+
if (conf.key.altKey && !e.altKey) {
|
728
1051
|
return;
|
729
1052
|
}
|
730
1053
|
|
731
|
-
if (
|
1054
|
+
if (conf.key.ctrlKey && !e.ctrlKey) {
|
732
1055
|
return;
|
733
1056
|
}
|
734
1057
|
|
735
|
-
if (
|
1058
|
+
if (conf.key.metaKey && !e.metaKey) {
|
736
1059
|
return;
|
737
1060
|
}
|
738
1061
|
|
@@ -742,17 +1065,17 @@ $.extend( Buttons.prototype, {
|
|
742
1065
|
}
|
743
1066
|
};
|
744
1067
|
|
745
|
-
var recurse = function (
|
746
|
-
for (
|
747
|
-
run(
|
1068
|
+
var recurse = function (a) {
|
1069
|
+
for (var i = 0, ien = a.length; i < ien; i++) {
|
1070
|
+
run(a[i].conf, a[i].node);
|
748
1071
|
|
749
|
-
if (
|
750
|
-
recurse(
|
1072
|
+
if (a[i].buttons.length) {
|
1073
|
+
recurse(a[i].buttons);
|
751
1074
|
}
|
752
1075
|
}
|
753
1076
|
};
|
754
1077
|
|
755
|
-
recurse(
|
1078
|
+
recurse(this.s.buttons);
|
756
1079
|
},
|
757
1080
|
|
758
1081
|
/**
|
@@ -761,18 +1084,15 @@ $.extend( Buttons.prototype, {
|
|
761
1084
|
* @param {object} conf Button configuration
|
762
1085
|
* @private
|
763
1086
|
*/
|
764
|
-
_removeKey: function (
|
765
|
-
|
766
|
-
|
767
|
-
var character = $.isPlainObject( conf.key ) ?
|
768
|
-
conf.key.key :
|
769
|
-
conf.key;
|
1087
|
+
_removeKey: function (conf) {
|
1088
|
+
if (conf.key) {
|
1089
|
+
var character = $.isPlainObject(conf.key) ? conf.key.key : conf.key;
|
770
1090
|
|
771
1091
|
// Remove only one character, as multiple buttons could have the
|
772
1092
|
// same listening key
|
773
1093
|
var a = this.s.listenKeys.split('');
|
774
|
-
var idx = $.inArray(
|
775
|
-
a.splice(
|
1094
|
+
var idx = $.inArray(character, a);
|
1095
|
+
a.splice(idx, 1);
|
776
1096
|
this.s.listenKeys = a.join('');
|
777
1097
|
}
|
778
1098
|
},
|
@@ -783,62 +1103,60 @@ $.extend( Buttons.prototype, {
|
|
783
1103
|
* @return {object} Button configuration
|
784
1104
|
* @private
|
785
1105
|
*/
|
786
|
-
_resolveExtends: function (
|
787
|
-
|
1106
|
+
_resolveExtends: function (conf) {
|
1107
|
+
var that = this;
|
788
1108
|
var dt = this.s.dt;
|
789
1109
|
var i, ien;
|
790
|
-
var toConfObject = function (
|
1110
|
+
var toConfObject = function (base) {
|
791
1111
|
var loop = 0;
|
792
1112
|
|
793
1113
|
// Loop until we have resolved to a button configuration, or an
|
794
1114
|
// array of button configurations (which will be iterated
|
795
1115
|
// separately)
|
796
|
-
while (
|
797
|
-
if (
|
1116
|
+
while (!$.isPlainObject(base) && !Array.isArray(base)) {
|
1117
|
+
if (base === undefined) {
|
798
1118
|
return;
|
799
1119
|
}
|
800
1120
|
|
801
|
-
if (
|
802
|
-
base = base( dt, conf
|
1121
|
+
if (typeof base === 'function') {
|
1122
|
+
base = base.call(that, dt, conf);
|
803
1123
|
|
804
|
-
if (
|
1124
|
+
if (!base) {
|
805
1125
|
return false;
|
806
1126
|
}
|
807
1127
|
}
|
808
|
-
else if (
|
809
|
-
if (
|
810
|
-
|
1128
|
+
else if (typeof base === 'string') {
|
1129
|
+
if (!_dtButtons[base]) {
|
1130
|
+
return { html: base };
|
811
1131
|
}
|
812
1132
|
|
813
|
-
base = _dtButtons[
|
1133
|
+
base = _dtButtons[base];
|
814
1134
|
}
|
815
1135
|
|
816
1136
|
loop++;
|
817
|
-
if (
|
1137
|
+
if (loop > 30) {
|
818
1138
|
// Protect against misconfiguration killing the browser
|
819
1139
|
throw 'Buttons: Too many iterations';
|
820
1140
|
}
|
821
1141
|
}
|
822
1142
|
|
823
|
-
return
|
824
|
-
base :
|
825
|
-
$.extend( {}, base );
|
1143
|
+
return Array.isArray(base) ? base : $.extend({}, base);
|
826
1144
|
};
|
827
1145
|
|
828
|
-
conf = toConfObject(
|
1146
|
+
conf = toConfObject(conf);
|
829
1147
|
|
830
|
-
while (
|
1148
|
+
while (conf && conf.extend) {
|
831
1149
|
// Use `toConfObject` in case the button definition being extended
|
832
1150
|
// is itself a string or a function
|
833
|
-
if (
|
834
|
-
throw 'Cannot extend unknown button type: '+conf.extend;
|
1151
|
+
if (!_dtButtons[conf.extend]) {
|
1152
|
+
throw 'Cannot extend unknown button type: ' + conf.extend;
|
835
1153
|
}
|
836
1154
|
|
837
|
-
var objArray = toConfObject(
|
838
|
-
if (
|
1155
|
+
var objArray = toConfObject(_dtButtons[conf.extend]);
|
1156
|
+
if (Array.isArray(objArray)) {
|
839
1157
|
return objArray;
|
840
1158
|
}
|
841
|
-
else if (
|
1159
|
+
else if (!objArray) {
|
842
1160
|
// This is a little brutal as it might be possible to have a
|
843
1161
|
// valid button without the extend, but if there is no extend
|
844
1162
|
// then the host button would be acting in an undefined state
|
@@ -848,54 +1166,387 @@ $.extend( Buttons.prototype, {
|
|
848
1166
|
// Stash the current class name
|
849
1167
|
var originalClassName = objArray.className;
|
850
1168
|
|
851
|
-
conf
|
1169
|
+
if (conf.config !== undefined && objArray.config !== undefined) {
|
1170
|
+
conf.config = $.extend({}, objArray.config, conf.config);
|
1171
|
+
}
|
1172
|
+
|
1173
|
+
conf = $.extend({}, objArray, conf);
|
852
1174
|
|
853
1175
|
// The extend will have overwritten the original class name if the
|
854
1176
|
// `conf` object also assigned a class, but we want to concatenate
|
855
1177
|
// them so they are list that is combined from all extended buttons
|
856
|
-
if (
|
857
|
-
conf.className = originalClassName+' '+conf.className;
|
1178
|
+
if (originalClassName && conf.className !== originalClassName) {
|
1179
|
+
conf.className = originalClassName + ' ' + conf.className;
|
858
1180
|
}
|
859
1181
|
|
860
|
-
//
|
861
|
-
//
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
conf.buttons = [];
|
866
|
-
}
|
1182
|
+
// Although we want the `conf` object to overwrite almost all of
|
1183
|
+
// the properties of the object being extended, the `extend`
|
1184
|
+
// property should come from the object being extended
|
1185
|
+
conf.extend = objArray.extend;
|
1186
|
+
}
|
867
1187
|
|
868
|
-
|
869
|
-
|
870
|
-
|
1188
|
+
// Buttons to be added to a collection -gives the ability to define
|
1189
|
+
// if buttons should be added to the start or end of a collection
|
1190
|
+
var postfixButtons = conf.postfixButtons;
|
1191
|
+
if (postfixButtons) {
|
1192
|
+
if (!conf.buttons) {
|
1193
|
+
conf.buttons = [];
|
1194
|
+
}
|
1195
|
+
|
1196
|
+
for (i = 0, ien = postfixButtons.length; i < ien; i++) {
|
1197
|
+
conf.buttons.push(postfixButtons[i]);
|
1198
|
+
}
|
1199
|
+
}
|
1200
|
+
|
1201
|
+
var prefixButtons = conf.prefixButtons;
|
1202
|
+
if (prefixButtons) {
|
1203
|
+
if (!conf.buttons) {
|
1204
|
+
conf.buttons = [];
|
1205
|
+
}
|
1206
|
+
|
1207
|
+
for (i = 0, ien = prefixButtons.length; i < ien; i++) {
|
1208
|
+
conf.buttons.splice(i, 0, prefixButtons[i]);
|
1209
|
+
}
|
1210
|
+
}
|
1211
|
+
|
1212
|
+
return conf;
|
1213
|
+
},
|
1214
|
+
|
1215
|
+
/**
|
1216
|
+
* Display (and replace if there is an existing one) a popover attached to a button
|
1217
|
+
* @param {string|node} content Content to show
|
1218
|
+
* @param {DataTable.Api} hostButton DT API instance of the button
|
1219
|
+
* @param {object} inOpts Options (see object below for all options)
|
1220
|
+
*/
|
1221
|
+
_popover: function (content, hostButton, inOpts, e) {
|
1222
|
+
var dt = hostButton;
|
1223
|
+
var c = this.c;
|
1224
|
+
var closed = false;
|
1225
|
+
var options = $.extend(
|
1226
|
+
{
|
1227
|
+
align: 'button-left', // button-right, dt-container, split-left, split-right
|
1228
|
+
autoClose: false,
|
1229
|
+
background: true,
|
1230
|
+
backgroundClassName: 'dt-button-background',
|
1231
|
+
closeButton: true,
|
1232
|
+
containerClassName: c.dom.collection.container.className,
|
1233
|
+
contentClassName: c.dom.collection.container.content.className,
|
1234
|
+
collectionLayout: '',
|
1235
|
+
collectionTitle: '',
|
1236
|
+
dropup: false,
|
1237
|
+
fade: 400,
|
1238
|
+
popoverTitle: '',
|
1239
|
+
rightAlignClassName: 'dt-button-right',
|
1240
|
+
tag: c.dom.collection.container.tag
|
1241
|
+
},
|
1242
|
+
inOpts
|
1243
|
+
);
|
1244
|
+
|
1245
|
+
var containerSelector = options.tag + '.' + options.containerClassName.replace(/ /g, '.');
|
1246
|
+
var hostNode = hostButton.node();
|
871
1247
|
|
872
|
-
|
1248
|
+
var close = function () {
|
1249
|
+
closed = true;
|
1250
|
+
|
1251
|
+
_fadeOut($(containerSelector), options.fade, function () {
|
1252
|
+
$(this).detach();
|
1253
|
+
});
|
1254
|
+
|
1255
|
+
$(dt.buttons('[aria-haspopup="dialog"][aria-expanded="true"]').nodes()).attr(
|
1256
|
+
'aria-expanded',
|
1257
|
+
'false'
|
1258
|
+
);
|
1259
|
+
|
1260
|
+
$('div.dt-button-background').off('click.dtb-collection');
|
1261
|
+
Buttons.background(false, options.backgroundClassName, options.fade, hostNode);
|
1262
|
+
|
1263
|
+
$(window).off('resize.resize.dtb-collection');
|
1264
|
+
$('body').off('.dtb-collection');
|
1265
|
+
dt.off('buttons-action.b-internal');
|
1266
|
+
dt.off('destroy');
|
1267
|
+
};
|
1268
|
+
|
1269
|
+
if (content === false) {
|
1270
|
+
close();
|
1271
|
+
return;
|
1272
|
+
}
|
1273
|
+
|
1274
|
+
var existingExpanded = $(
|
1275
|
+
dt.buttons('[aria-haspopup="dialog"][aria-expanded="true"]').nodes()
|
1276
|
+
);
|
1277
|
+
if (existingExpanded.length) {
|
1278
|
+
// Reuse the current position if the button that was triggered is inside an existing collection
|
1279
|
+
if (hostNode.closest(containerSelector).length) {
|
1280
|
+
hostNode = existingExpanded.eq(0);
|
873
1281
|
}
|
874
1282
|
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
1283
|
+
close();
|
1284
|
+
}
|
1285
|
+
|
1286
|
+
// Try to be smart about the layout
|
1287
|
+
var cnt = $('.dt-button', content).length;
|
1288
|
+
var mod = '';
|
1289
|
+
|
1290
|
+
if (cnt === 3) {
|
1291
|
+
mod = 'dtb-b3';
|
1292
|
+
}
|
1293
|
+
else if (cnt === 2) {
|
1294
|
+
mod = 'dtb-b2';
|
1295
|
+
}
|
1296
|
+
else if (cnt === 1) {
|
1297
|
+
mod = 'dtb-b1';
|
1298
|
+
}
|
1299
|
+
|
1300
|
+
var display = $('<' + options.tag + '/>')
|
1301
|
+
.addClass(options.containerClassName)
|
1302
|
+
.addClass(options.collectionLayout)
|
1303
|
+
.addClass(options.splitAlignClass)
|
1304
|
+
.addClass(mod)
|
1305
|
+
.css('display', 'none')
|
1306
|
+
.attr({
|
1307
|
+
'aria-modal': true,
|
1308
|
+
role: 'dialog'
|
1309
|
+
});
|
1310
|
+
|
1311
|
+
content = $(content)
|
1312
|
+
.addClass(options.contentClassName)
|
1313
|
+
.attr('role', 'menu')
|
1314
|
+
.appendTo(display);
|
1315
|
+
|
1316
|
+
hostNode.attr('aria-expanded', 'true');
|
1317
|
+
|
1318
|
+
if (hostNode.parents('body')[0] !== document.body) {
|
1319
|
+
hostNode = document.body.lastChild;
|
1320
|
+
}
|
1321
|
+
|
1322
|
+
if (options.popoverTitle) {
|
1323
|
+
display.prepend(
|
1324
|
+
'<div class="dt-button-collection-title">' + options.popoverTitle + '</div>'
|
1325
|
+
);
|
1326
|
+
}
|
1327
|
+
else if (options.collectionTitle) {
|
1328
|
+
display.prepend(
|
1329
|
+
'<div class="dt-button-collection-title">' + options.collectionTitle + '</div>'
|
1330
|
+
);
|
1331
|
+
}
|
1332
|
+
|
1333
|
+
if (options.closeButton) {
|
1334
|
+
display
|
1335
|
+
.prepend('<div class="dtb-popover-close">×</div>')
|
1336
|
+
.addClass('dtb-collection-closeable');
|
1337
|
+
}
|
1338
|
+
|
1339
|
+
_fadeIn(display.insertAfter(hostNode), options.fade);
|
1340
|
+
|
1341
|
+
var tableContainer = $(hostButton.table().container());
|
1342
|
+
var position = display.css('position');
|
1343
|
+
|
1344
|
+
if (options.span === 'container' || options.align === 'dt-container') {
|
1345
|
+
hostNode = hostNode.parent();
|
1346
|
+
display.css('width', tableContainer.width());
|
1347
|
+
}
|
1348
|
+
|
1349
|
+
// Align the popover relative to the DataTables container
|
1350
|
+
// Useful for wide popovers such as SearchPanes
|
1351
|
+
if (position === 'absolute') {
|
1352
|
+
// Align relative to the host button
|
1353
|
+
var offsetParent = $(hostNode[0].offsetParent);
|
1354
|
+
var buttonPosition = hostNode.position();
|
1355
|
+
var buttonOffset = hostNode.offset();
|
1356
|
+
var tableSizes = offsetParent.offset();
|
1357
|
+
var containerPosition = offsetParent.position();
|
1358
|
+
var computed = window.getComputedStyle(offsetParent[0]);
|
1359
|
+
|
1360
|
+
tableSizes.height = offsetParent.outerHeight();
|
1361
|
+
tableSizes.width = offsetParent.width() + parseFloat(computed.paddingLeft);
|
1362
|
+
tableSizes.right = tableSizes.left + tableSizes.width;
|
1363
|
+
tableSizes.bottom = tableSizes.top + tableSizes.height;
|
1364
|
+
|
1365
|
+
// Set the initial position so we can read height / width
|
1366
|
+
var top = buttonPosition.top + hostNode.outerHeight();
|
1367
|
+
var left = buttonPosition.left;
|
1368
|
+
|
1369
|
+
display.css({
|
1370
|
+
top: top,
|
1371
|
+
left: left
|
1372
|
+
});
|
1373
|
+
|
1374
|
+
// Get the popover position
|
1375
|
+
computed = window.getComputedStyle(display[0]);
|
1376
|
+
var popoverSizes = display.offset();
|
1377
|
+
|
1378
|
+
popoverSizes.height = display.outerHeight();
|
1379
|
+
popoverSizes.width = display.outerWidth();
|
1380
|
+
popoverSizes.right = popoverSizes.left + popoverSizes.width;
|
1381
|
+
popoverSizes.bottom = popoverSizes.top + popoverSizes.height;
|
1382
|
+
popoverSizes.marginTop = parseFloat(computed.marginTop);
|
1383
|
+
popoverSizes.marginBottom = parseFloat(computed.marginBottom);
|
1384
|
+
|
1385
|
+
// First position per the class requirements - pop up and right align
|
1386
|
+
if (options.dropup) {
|
1387
|
+
top =
|
1388
|
+
buttonPosition.top -
|
1389
|
+
popoverSizes.height -
|
1390
|
+
popoverSizes.marginTop -
|
1391
|
+
popoverSizes.marginBottom;
|
1392
|
+
}
|
1393
|
+
|
1394
|
+
if (options.align === 'button-right' || display.hasClass(options.rightAlignClassName)) {
|
1395
|
+
left = buttonPosition.left - popoverSizes.width + hostNode.outerWidth();
|
1396
|
+
}
|
1397
|
+
|
1398
|
+
// Container alignment - make sure it doesn't overflow the table container
|
1399
|
+
if (options.align === 'dt-container' || options.align === 'container') {
|
1400
|
+
if (left < buttonPosition.left) {
|
1401
|
+
left = -buttonPosition.left;
|
879
1402
|
}
|
880
1403
|
|
881
|
-
|
882
|
-
|
1404
|
+
if (left + popoverSizes.width > tableSizes.width) {
|
1405
|
+
left = tableSizes.width - popoverSizes.width;
|
883
1406
|
}
|
1407
|
+
}
|
884
1408
|
|
885
|
-
|
1409
|
+
// Window adjustment
|
1410
|
+
if (containerPosition.left + left + popoverSizes.width > $(window).width()) {
|
1411
|
+
// Overflowing the document to the right
|
1412
|
+
left = $(window).width() - popoverSizes.width - containerPosition.left;
|
886
1413
|
}
|
887
1414
|
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
1415
|
+
if (buttonOffset.left + left < 0) {
|
1416
|
+
// Off to the left of the document
|
1417
|
+
left = -buttonOffset.left;
|
1418
|
+
}
|
1419
|
+
|
1420
|
+
if (
|
1421
|
+
containerPosition.top + top + popoverSizes.height >
|
1422
|
+
$(window).height() + $(window).scrollTop()
|
1423
|
+
) {
|
1424
|
+
// Pop up if otherwise we'd need the user to scroll down
|
1425
|
+
top =
|
1426
|
+
buttonPosition.top -
|
1427
|
+
popoverSizes.height -
|
1428
|
+
popoverSizes.marginTop -
|
1429
|
+
popoverSizes.marginBottom;
|
1430
|
+
}
|
1431
|
+
|
1432
|
+
if (containerPosition.top + top < $(window).scrollTop()) {
|
1433
|
+
// Correction for when the top is beyond the top of the page
|
1434
|
+
top = buttonPosition.top + hostNode.outerHeight();
|
1435
|
+
}
|
1436
|
+
|
1437
|
+
// Calculations all done - now set it
|
1438
|
+
display.css({
|
1439
|
+
top: top,
|
1440
|
+
left: left
|
1441
|
+
});
|
892
1442
|
}
|
1443
|
+
else {
|
1444
|
+
// Fix position - centre on screen
|
1445
|
+
var position = function () {
|
1446
|
+
var half = $(window).height() / 2;
|
893
1447
|
|
894
|
-
|
895
|
-
|
896
|
-
|
1448
|
+
var top = display.height() / 2;
|
1449
|
+
if (top > half) {
|
1450
|
+
top = half;
|
1451
|
+
}
|
1452
|
+
|
1453
|
+
display.css('marginTop', top * -1);
|
1454
|
+
};
|
1455
|
+
|
1456
|
+
position();
|
897
1457
|
|
1458
|
+
$(window).on('resize.dtb-collection', function () {
|
1459
|
+
position();
|
1460
|
+
});
|
1461
|
+
}
|
1462
|
+
|
1463
|
+
if (options.background) {
|
1464
|
+
Buttons.background(
|
1465
|
+
true,
|
1466
|
+
options.backgroundClassName,
|
1467
|
+
options.fade,
|
1468
|
+
options.backgroundHost || hostNode
|
1469
|
+
);
|
1470
|
+
}
|
1471
|
+
|
1472
|
+
// This is bonkers, but if we don't have a click listener on the
|
1473
|
+
// background element, iOS Safari will ignore the body click
|
1474
|
+
// listener below. An empty function here is all that is
|
1475
|
+
// required to make it work...
|
1476
|
+
$('div.dt-button-background').on('click.dtb-collection', function () {});
|
1477
|
+
|
1478
|
+
if (options.autoClose) {
|
1479
|
+
setTimeout(function () {
|
1480
|
+
dt.on('buttons-action.b-internal', function (e, btn, dt, node) {
|
1481
|
+
if (node[0] === hostNode[0]) {
|
1482
|
+
return;
|
1483
|
+
}
|
1484
|
+
close();
|
1485
|
+
});
|
1486
|
+
}, 0);
|
1487
|
+
}
|
1488
|
+
|
1489
|
+
$(display).trigger('buttons-popover.dt');
|
1490
|
+
|
1491
|
+
dt.on('destroy', close);
|
1492
|
+
|
1493
|
+
setTimeout(function () {
|
1494
|
+
closed = false;
|
1495
|
+
$('body')
|
1496
|
+
.on('click.dtb-collection', function (e) {
|
1497
|
+
if (closed) {
|
1498
|
+
return;
|
1499
|
+
}
|
898
1500
|
|
1501
|
+
// andSelf is deprecated in jQ1.8, but we want 1.7 compat
|
1502
|
+
var back = $.fn.addBack ? 'addBack' : 'andSelf';
|
1503
|
+
var parent = $(e.target).parent()[0];
|
1504
|
+
|
1505
|
+
if (
|
1506
|
+
(!$(e.target).parents()[back]().filter(content).length &&
|
1507
|
+
!$(parent).hasClass('dt-buttons')) ||
|
1508
|
+
$(e.target).hasClass('dt-button-background')
|
1509
|
+
) {
|
1510
|
+
close();
|
1511
|
+
}
|
1512
|
+
})
|
1513
|
+
.on('keyup.dtb-collection', function (e) {
|
1514
|
+
if (e.keyCode === 27) {
|
1515
|
+
close();
|
1516
|
+
}
|
1517
|
+
})
|
1518
|
+
.on('keydown.dtb-collection', function (e) {
|
1519
|
+
// Focus trap for tab key
|
1520
|
+
var elements = $('a, button', content);
|
1521
|
+
var active = document.activeElement;
|
1522
|
+
|
1523
|
+
if (e.keyCode !== 9) {
|
1524
|
+
// tab
|
1525
|
+
return;
|
1526
|
+
}
|
1527
|
+
|
1528
|
+
if (elements.index(active) === -1) {
|
1529
|
+
// If current focus is not inside the popover
|
1530
|
+
elements.first().focus();
|
1531
|
+
e.preventDefault();
|
1532
|
+
}
|
1533
|
+
else if (e.shiftKey) {
|
1534
|
+
// Reverse tabbing order when shift key is pressed
|
1535
|
+
if (active === elements[0]) {
|
1536
|
+
elements.last().focus();
|
1537
|
+
e.preventDefault();
|
1538
|
+
}
|
1539
|
+
}
|
1540
|
+
else {
|
1541
|
+
if (active === elements.last()[0]) {
|
1542
|
+
elements.first().focus();
|
1543
|
+
e.preventDefault();
|
1544
|
+
}
|
1545
|
+
}
|
1546
|
+
});
|
1547
|
+
}, 0);
|
1548
|
+
}
|
1549
|
+
});
|
899
1550
|
|
900
1551
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
901
1552
|
* Statics
|
@@ -908,28 +1559,24 @@ $.extend( Buttons.prototype, {
|
|
908
1559
|
* @param {string} Class to assign to the background
|
909
1560
|
* @static
|
910
1561
|
*/
|
911
|
-
Buttons.background = function (
|
912
|
-
if (
|
1562
|
+
Buttons.background = function (show, className, fade, insertPoint) {
|
1563
|
+
if (fade === undefined) {
|
913
1564
|
fade = 400;
|
914
1565
|
}
|
915
|
-
if (
|
1566
|
+
if (!insertPoint) {
|
916
1567
|
insertPoint = document.body;
|
917
1568
|
}
|
918
1569
|
|
919
|
-
if (
|
920
|
-
|
921
|
-
.addClass(
|
922
|
-
|
923
|
-
|
924
|
-
.fadeIn( fade );
|
1570
|
+
if (show) {
|
1571
|
+
_fadeIn(
|
1572
|
+
$('<div/>').addClass(className).css('display', 'none').insertAfter(insertPoint),
|
1573
|
+
fade
|
1574
|
+
);
|
925
1575
|
}
|
926
1576
|
else {
|
927
|
-
$('div.'+className)
|
928
|
-
.
|
929
|
-
|
930
|
-
.removeClass( className )
|
931
|
-
.remove();
|
932
|
-
} );
|
1577
|
+
_fadeOut($('div.' + className), fade, function () {
|
1578
|
+
$(this).removeClass(className).remove();
|
1579
|
+
});
|
933
1580
|
}
|
934
1581
|
};
|
935
1582
|
|
@@ -944,49 +1591,52 @@ Buttons.background = function ( show, className, fade, insertPoint ) {
|
|
944
1591
|
* @return {array} Buttons instances
|
945
1592
|
* @static
|
946
1593
|
*/
|
947
|
-
Buttons.instanceSelector = function (
|
948
|
-
{
|
949
|
-
|
950
|
-
return $.map( buttons, function ( v ) {
|
1594
|
+
Buttons.instanceSelector = function (group, buttons) {
|
1595
|
+
if (group === undefined || group === null) {
|
1596
|
+
return $.map(buttons, function (v) {
|
951
1597
|
return v.inst;
|
952
|
-
}
|
1598
|
+
});
|
953
1599
|
}
|
954
1600
|
|
955
1601
|
var ret = [];
|
956
|
-
var names = $.map(
|
1602
|
+
var names = $.map(buttons, function (v) {
|
957
1603
|
return v.name;
|
958
|
-
}
|
1604
|
+
});
|
959
1605
|
|
960
1606
|
// Flatten the group selector into an array of single options
|
961
|
-
var process = function (
|
962
|
-
if (
|
963
|
-
for (
|
964
|
-
process(
|
1607
|
+
var process = function (input) {
|
1608
|
+
if (Array.isArray(input)) {
|
1609
|
+
for (var i = 0, ien = input.length; i < ien; i++) {
|
1610
|
+
process(input[i]);
|
965
1611
|
}
|
966
1612
|
return;
|
967
1613
|
}
|
968
1614
|
|
969
|
-
if (
|
970
|
-
if (
|
1615
|
+
if (typeof input === 'string') {
|
1616
|
+
if (input.indexOf(',') !== -1) {
|
971
1617
|
// String selector, list of names
|
972
|
-
process(
|
1618
|
+
process(input.split(','));
|
973
1619
|
}
|
974
1620
|
else {
|
975
1621
|
// String selector individual name
|
976
|
-
var idx = $.inArray(
|
1622
|
+
var idx = $.inArray(input.trim(), names);
|
977
1623
|
|
978
|
-
if (
|
979
|
-
ret.push(
|
1624
|
+
if (idx !== -1) {
|
1625
|
+
ret.push(buttons[idx].inst);
|
980
1626
|
}
|
981
1627
|
}
|
982
1628
|
}
|
983
|
-
else if (
|
1629
|
+
else if (typeof input === 'number') {
|
984
1630
|
// Index selector
|
985
|
-
ret.push(
|
1631
|
+
ret.push(buttons[input].inst);
|
1632
|
+
}
|
1633
|
+
else if (typeof input === 'object') {
|
1634
|
+
// Actual instance selector
|
1635
|
+
ret.push(input);
|
986
1636
|
}
|
987
1637
|
};
|
988
1638
|
|
989
|
-
process(
|
1639
|
+
process(group);
|
990
1640
|
|
991
1641
|
return ret;
|
992
1642
|
};
|
@@ -1001,132 +1651,166 @@ Buttons.instanceSelector = function ( group, buttons )
|
|
1001
1651
|
* the selected buttons so you know which instance each button belongs to.
|
1002
1652
|
* @static
|
1003
1653
|
*/
|
1004
|
-
Buttons.buttonSelector = function (
|
1005
|
-
{
|
1654
|
+
Buttons.buttonSelector = function (insts, selector) {
|
1006
1655
|
var ret = [];
|
1007
|
-
var nodeBuilder = function (
|
1656
|
+
var nodeBuilder = function (a, buttons, baseIdx) {
|
1008
1657
|
var button;
|
1009
1658
|
var idx;
|
1010
1659
|
|
1011
|
-
for (
|
1660
|
+
for (var i = 0, ien = buttons.length; i < ien; i++) {
|
1012
1661
|
button = buttons[i];
|
1013
1662
|
|
1014
|
-
if (
|
1015
|
-
idx = baseIdx !== undefined ?
|
1016
|
-
baseIdx+i :
|
1017
|
-
i+'';
|
1663
|
+
if (button) {
|
1664
|
+
idx = baseIdx !== undefined ? baseIdx + i : i + '';
|
1018
1665
|
|
1019
|
-
a.push(
|
1666
|
+
a.push({
|
1020
1667
|
node: button.node,
|
1021
1668
|
name: button.conf.name,
|
1022
|
-
idx:
|
1023
|
-
}
|
1669
|
+
idx: idx
|
1670
|
+
});
|
1024
1671
|
|
1025
|
-
if (
|
1026
|
-
nodeBuilder(
|
1672
|
+
if (button.buttons) {
|
1673
|
+
nodeBuilder(a, button.buttons, idx + '-');
|
1027
1674
|
}
|
1028
1675
|
}
|
1029
1676
|
}
|
1030
1677
|
};
|
1031
1678
|
|
1032
|
-
var run = function (
|
1679
|
+
var run = function (selector, inst) {
|
1033
1680
|
var i, ien;
|
1034
1681
|
var buttons = [];
|
1035
|
-
nodeBuilder(
|
1682
|
+
nodeBuilder(buttons, inst.s.buttons);
|
1036
1683
|
|
1037
|
-
var nodes = $.map(
|
1684
|
+
var nodes = $.map(buttons, function (v) {
|
1038
1685
|
return v.node;
|
1039
|
-
}
|
1686
|
+
});
|
1040
1687
|
|
1041
|
-
if (
|
1042
|
-
for (
|
1043
|
-
run(
|
1688
|
+
if (Array.isArray(selector) || selector instanceof $) {
|
1689
|
+
for (i = 0, ien = selector.length; i < ien; i++) {
|
1690
|
+
run(selector[i], inst);
|
1044
1691
|
}
|
1045
1692
|
return;
|
1046
1693
|
}
|
1047
1694
|
|
1048
|
-
if (
|
1695
|
+
if (selector === null || selector === undefined || selector === '*') {
|
1049
1696
|
// Select all
|
1050
|
-
for (
|
1051
|
-
ret.push(
|
1697
|
+
for (i = 0, ien = buttons.length; i < ien; i++) {
|
1698
|
+
ret.push({
|
1052
1699
|
inst: inst,
|
1053
1700
|
node: buttons[i].node
|
1054
|
-
}
|
1701
|
+
});
|
1055
1702
|
}
|
1056
1703
|
}
|
1057
|
-
else if (
|
1704
|
+
else if (typeof selector === 'number') {
|
1058
1705
|
// Main button index selector
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1706
|
+
if (inst.s.buttons[selector]) {
|
1707
|
+
ret.push({
|
1708
|
+
inst: inst,
|
1709
|
+
node: inst.s.buttons[selector].node
|
1710
|
+
});
|
1711
|
+
}
|
1063
1712
|
}
|
1064
|
-
else if (
|
1065
|
-
if (
|
1713
|
+
else if (typeof selector === 'string') {
|
1714
|
+
if (selector.indexOf(',') !== -1) {
|
1066
1715
|
// Split
|
1067
1716
|
var a = selector.split(',');
|
1068
1717
|
|
1069
|
-
for (
|
1070
|
-
run(
|
1718
|
+
for (i = 0, ien = a.length; i < ien; i++) {
|
1719
|
+
run(a[i].trim(), inst);
|
1071
1720
|
}
|
1072
1721
|
}
|
1073
|
-
else if (
|
1722
|
+
else if (selector.match(/^\d+(\-\d+)*$/)) {
|
1074
1723
|
// Sub-button index selector
|
1075
|
-
var indexes = $.map(
|
1724
|
+
var indexes = $.map(buttons, function (v) {
|
1076
1725
|
return v.idx;
|
1077
|
-
}
|
1726
|
+
});
|
1078
1727
|
|
1079
|
-
ret.push(
|
1728
|
+
ret.push({
|
1080
1729
|
inst: inst,
|
1081
|
-
node: buttons[
|
1082
|
-
}
|
1730
|
+
node: buttons[$.inArray(selector, indexes)].node
|
1731
|
+
});
|
1083
1732
|
}
|
1084
|
-
else if (
|
1733
|
+
else if (selector.indexOf(':name') !== -1) {
|
1085
1734
|
// Button name selector
|
1086
|
-
var name = selector.replace(
|
1735
|
+
var name = selector.replace(':name', '');
|
1087
1736
|
|
1088
|
-
for (
|
1089
|
-
if (
|
1090
|
-
ret.push(
|
1737
|
+
for (i = 0, ien = buttons.length; i < ien; i++) {
|
1738
|
+
if (buttons[i].name === name) {
|
1739
|
+
ret.push({
|
1091
1740
|
inst: inst,
|
1092
1741
|
node: buttons[i].node
|
1093
|
-
}
|
1742
|
+
});
|
1094
1743
|
}
|
1095
1744
|
}
|
1096
1745
|
}
|
1097
1746
|
else {
|
1098
1747
|
// jQuery selector on the nodes
|
1099
|
-
$(
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1748
|
+
$(nodes)
|
1749
|
+
.filter(selector)
|
1750
|
+
.each(function () {
|
1751
|
+
ret.push({
|
1752
|
+
inst: inst,
|
1753
|
+
node: this
|
1754
|
+
});
|
1755
|
+
});
|
1105
1756
|
}
|
1106
1757
|
}
|
1107
|
-
else if (
|
1758
|
+
else if (typeof selector === 'object' && selector.nodeName) {
|
1108
1759
|
// Node selector
|
1109
|
-
var idx = $.inArray(
|
1760
|
+
var idx = $.inArray(selector, nodes);
|
1110
1761
|
|
1111
|
-
if (
|
1112
|
-
ret.push(
|
1762
|
+
if (idx !== -1) {
|
1763
|
+
ret.push({
|
1113
1764
|
inst: inst,
|
1114
|
-
node: nodes[
|
1115
|
-
}
|
1765
|
+
node: nodes[idx]
|
1766
|
+
});
|
1116
1767
|
}
|
1117
1768
|
}
|
1118
1769
|
};
|
1119
1770
|
|
1120
|
-
|
1121
|
-
for ( var i=0, ien=insts.length ; i<ien ; i++ ) {
|
1771
|
+
for (var i = 0, ien = insts.length; i < ien; i++) {
|
1122
1772
|
var inst = insts[i];
|
1123
1773
|
|
1124
|
-
run(
|
1774
|
+
run(selector, inst);
|
1125
1775
|
}
|
1126
1776
|
|
1127
1777
|
return ret;
|
1128
1778
|
};
|
1129
1779
|
|
1780
|
+
/**
|
1781
|
+
* Default function used for formatting output data.
|
1782
|
+
* @param {*} str Data to strip
|
1783
|
+
*/
|
1784
|
+
Buttons.stripData = function (str, config) {
|
1785
|
+
if (typeof str !== 'string') {
|
1786
|
+
return str;
|
1787
|
+
}
|
1788
|
+
|
1789
|
+
// Always remove script tags
|
1790
|
+
str = str.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
|
1791
|
+
|
1792
|
+
// Always remove comments
|
1793
|
+
str = str.replace(/<!\-\-.*?\-\->/g, '');
|
1794
|
+
|
1795
|
+
if (!config || config.stripHtml) {
|
1796
|
+
str = str.replace(/<[^>]*>/g, '');
|
1797
|
+
}
|
1798
|
+
|
1799
|
+
if (!config || config.trim) {
|
1800
|
+
str = str.replace(/^\s+|\s+$/g, '');
|
1801
|
+
}
|
1802
|
+
|
1803
|
+
if (!config || config.stripNewlines) {
|
1804
|
+
str = str.replace(/\n/g, ' ');
|
1805
|
+
}
|
1806
|
+
|
1807
|
+
if (!config || config.decodeEntities) {
|
1808
|
+
_exportTextarea.innerHTML = str;
|
1809
|
+
str = _exportTextarea.value;
|
1810
|
+
}
|
1811
|
+
|
1812
|
+
return str;
|
1813
|
+
};
|
1130
1814
|
|
1131
1815
|
/**
|
1132
1816
|
* Buttons defaults. For full documentation, please refer to the docs/option
|
@@ -1135,7 +1819,7 @@ Buttons.buttonSelector = function ( insts, selector )
|
|
1135
1819
|
* @static
|
1136
1820
|
*/
|
1137
1821
|
Buttons.defaults = {
|
1138
|
-
buttons: [
|
1822
|
+
buttons: ['copy', 'excel', 'csv', 'pdf', 'print'],
|
1139
1823
|
name: 'main',
|
1140
1824
|
tabIndex: 0,
|
1141
1825
|
dom: {
|
@@ -1144,21 +1828,56 @@ Buttons.defaults = {
|
|
1144
1828
|
className: 'dt-buttons'
|
1145
1829
|
},
|
1146
1830
|
collection: {
|
1147
|
-
|
1148
|
-
|
1831
|
+
action: {
|
1832
|
+
// action button
|
1833
|
+
dropHtml: '<span class="dt-button-down-arrow">▼</span>'
|
1834
|
+
},
|
1835
|
+
container: {
|
1836
|
+
// The element used for the dropdown
|
1837
|
+
className: 'dt-button-collection',
|
1838
|
+
content: {
|
1839
|
+
className: '',
|
1840
|
+
tag: 'div'
|
1841
|
+
},
|
1842
|
+
tag: 'div'
|
1843
|
+
}
|
1844
|
+
// optionally
|
1845
|
+
// , button: IButton - buttons inside the collection container
|
1846
|
+
// , split: ISplit - splits inside the collection container
|
1149
1847
|
},
|
1150
1848
|
button: {
|
1151
|
-
|
1152
|
-
tag: 'ActiveXObject' in window ?
|
1153
|
-
'a' :
|
1154
|
-
'button',
|
1849
|
+
tag: 'button',
|
1155
1850
|
className: 'dt-button',
|
1156
|
-
active: 'active',
|
1157
|
-
disabled: 'disabled'
|
1851
|
+
active: 'dt-button-active', // class name
|
1852
|
+
disabled: 'disabled', // class name
|
1853
|
+
spacer: {
|
1854
|
+
className: 'dt-button-spacer',
|
1855
|
+
tag: 'span'
|
1856
|
+
},
|
1857
|
+
liner: {
|
1858
|
+
tag: 'span',
|
1859
|
+
className: ''
|
1860
|
+
}
|
1158
1861
|
},
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1862
|
+
split: {
|
1863
|
+
action: {
|
1864
|
+
// action button
|
1865
|
+
className: 'dt-button-split-drop-button dt-button',
|
1866
|
+
tag: 'button'
|
1867
|
+
},
|
1868
|
+
dropdown: {
|
1869
|
+
// button to trigger the dropdown
|
1870
|
+
align: 'split-right',
|
1871
|
+
className: 'dt-button-split-drop',
|
1872
|
+
dropHtml: '<span class="dt-button-down-arrow">▼</span>',
|
1873
|
+
splitAlignClass: 'dt-button-split-left',
|
1874
|
+
tag: 'button'
|
1875
|
+
},
|
1876
|
+
wrapper: {
|
1877
|
+
// wrap around both
|
1878
|
+
className: 'dt-button-split',
|
1879
|
+
tag: 'div'
|
1880
|
+
}
|
1162
1881
|
}
|
1163
1882
|
}
|
1164
1883
|
};
|
@@ -1168,245 +1887,155 @@ Buttons.defaults = {
|
|
1168
1887
|
* @type {string}
|
1169
1888
|
* @static
|
1170
1889
|
*/
|
1171
|
-
Buttons.version = '
|
1172
|
-
|
1890
|
+
Buttons.version = '2.4.1';
|
1173
1891
|
|
1174
|
-
$.extend(
|
1892
|
+
$.extend(_dtButtons, {
|
1175
1893
|
collection: {
|
1176
|
-
text: function (
|
1177
|
-
return dt.i18n(
|
1894
|
+
text: function (dt) {
|
1895
|
+
return dt.i18n('buttons.collection', 'Collection');
|
1178
1896
|
},
|
1179
1897
|
className: 'buttons-collection',
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
// Remove any old collection
|
1189
|
-
if ( collectionParent.length ) {
|
1190
|
-
multiLevel = $('.dt-button-collection').position();
|
1191
|
-
insertPoint = collectionParent;
|
1192
|
-
$('body').trigger( 'click.dtb-collection' );
|
1193
|
-
}
|
1194
|
-
|
1195
|
-
if ( insertPoint.parents('body')[0] !== document.body ) {
|
1196
|
-
insertPoint = document.body.lastChild;
|
1197
|
-
}
|
1198
|
-
|
1199
|
-
config._collection.find('.dt-button-collection-title').remove();
|
1200
|
-
config._collection.prepend('<div class="dt-button-collection-title">'+config.collectionTitle+'</div>');
|
1201
|
-
|
1202
|
-
config._collection
|
1203
|
-
.addClass( config.collectionLayout )
|
1204
|
-
.css( 'display', 'none' )
|
1205
|
-
.insertAfter( insertPoint )
|
1206
|
-
.fadeIn( config.fade );
|
1207
|
-
|
1208
|
-
var position = config._collection.css( 'position' );
|
1209
|
-
|
1210
|
-
if ( multiLevel && position === 'absolute' ) {
|
1211
|
-
config._collection.css( {
|
1212
|
-
top: multiLevel.top,
|
1213
|
-
left: multiLevel.left
|
1214
|
-
} );
|
1215
|
-
}
|
1216
|
-
else if ( position === 'absolute' ) {
|
1217
|
-
config._collection.css( {
|
1218
|
-
top: hostPosition.top + host.outerHeight(),
|
1219
|
-
left: hostPosition.left
|
1220
|
-
} );
|
1221
|
-
|
1222
|
-
// calculate overflow when positioned beneath
|
1223
|
-
var tableBottom = tableContainer.offset().top + tableContainer.height();
|
1224
|
-
var listBottom = hostPosition.top + host.outerHeight() + config._collection.outerHeight();
|
1225
|
-
var bottomOverflow = listBottom - tableBottom;
|
1226
|
-
|
1227
|
-
// calculate overflow when positioned above
|
1228
|
-
var listTop = hostPosition.top - config._collection.outerHeight();
|
1229
|
-
var tableTop = tableContainer.offset().top;
|
1230
|
-
var topOverflow = tableTop - listTop;
|
1231
|
-
|
1232
|
-
// if bottom overflow is larger, move to the top because it fits better, or if dropup is requested
|
1233
|
-
if (bottomOverflow > topOverflow || config.dropup) {
|
1234
|
-
config._collection.css( 'top', hostPosition.top - config._collection.outerHeight() - 5);
|
1235
|
-
}
|
1236
|
-
|
1237
|
-
// Right alignment is enabled on a class, e.g. bootstrap:
|
1238
|
-
// $.fn.dataTable.Buttons.defaults.dom.collection.className += " dropdown-menu-right";
|
1239
|
-
if ( config._collection.hasClass( config.rightAlignClassName ) ) {
|
1240
|
-
config._collection.css( 'left', hostPosition.left + host.outerWidth() - config._collection.outerWidth() );
|
1241
|
-
}
|
1242
|
-
|
1243
|
-
// Right alignment in table container
|
1244
|
-
var listRight = hostPosition.left + config._collection.outerWidth();
|
1245
|
-
var tableRight = tableContainer.offset().left + tableContainer.width();
|
1246
|
-
if ( listRight > tableRight ) {
|
1247
|
-
config._collection.css( 'left', hostPosition.left - ( listRight - tableRight ) );
|
1248
|
-
}
|
1249
|
-
|
1250
|
-
// Right alignment to window
|
1251
|
-
var listOffsetRight = host.offset().left + config._collection.outerWidth();
|
1252
|
-
if ( listOffsetRight > $(window).width() ) {
|
1253
|
-
config._collection.css( 'left', hostPosition.left - (listOffsetRight-$(window).width()) );
|
1254
|
-
}
|
1898
|
+
closeButton: false,
|
1899
|
+
init: function (dt, button, config) {
|
1900
|
+
button.attr('aria-expanded', false);
|
1901
|
+
},
|
1902
|
+
action: function (e, dt, button, config) {
|
1903
|
+
if (config._collection.parents('body').length) {
|
1904
|
+
this.popover(false, config);
|
1255
1905
|
}
|
1256
1906
|
else {
|
1257
|
-
|
1258
|
-
var top = config._collection.height() / 2;
|
1259
|
-
if ( top > $(window).height() / 2 ) {
|
1260
|
-
top = $(window).height() / 2;
|
1261
|
-
}
|
1262
|
-
|
1263
|
-
config._collection.css( 'marginTop', top*-1 );
|
1907
|
+
this.popover(config._collection, config);
|
1264
1908
|
}
|
1265
1909
|
|
1266
|
-
|
1267
|
-
|
1910
|
+
// When activated using a key - auto focus on the
|
1911
|
+
// first item in the popover
|
1912
|
+
if (e.type === 'keypress') {
|
1913
|
+
$('a, button', config._collection).eq(0).focus();
|
1268
1914
|
}
|
1269
|
-
|
1270
|
-
var close = function () {
|
1271
|
-
config._collection
|
1272
|
-
.fadeOut( config.fade, function () {
|
1273
|
-
config._collection.detach();
|
1274
|
-
} );
|
1275
|
-
|
1276
|
-
$('div.dt-button-background').off( 'click.dtb-collection' );
|
1277
|
-
Buttons.background( false, config.backgroundClassName, config.fade, insertPoint );
|
1278
|
-
|
1279
|
-
$('body').off( '.dtb-collection' );
|
1280
|
-
dt.off( 'buttons-action.b-internal' );
|
1281
|
-
};
|
1282
|
-
|
1283
|
-
// Need to break the 'thread' for the collection button being
|
1284
|
-
// activated by a click - it would also trigger this event
|
1285
|
-
setTimeout( function () {
|
1286
|
-
// This is bonkers, but if we don't have a click listener on the
|
1287
|
-
// background element, iOS Safari will ignore the body click
|
1288
|
-
// listener below. An empty function here is all that is
|
1289
|
-
// required to make it work...
|
1290
|
-
$('div.dt-button-background').on( 'click.dtb-collection', function () {} );
|
1291
|
-
|
1292
|
-
$('body')
|
1293
|
-
.on( 'click.dtb-collection', function (e) {
|
1294
|
-
// andSelf is deprecated in jQ1.8, but we want 1.7 compat
|
1295
|
-
var back = $.fn.addBack ? 'addBack' : 'andSelf';
|
1296
|
-
|
1297
|
-
if ( ! $(e.target).parents()[back]().filter( config._collection ).length ) {
|
1298
|
-
close();
|
1299
|
-
}
|
1300
|
-
} )
|
1301
|
-
.on( 'keyup.dtb-collection', function (e) {
|
1302
|
-
if ( e.keyCode === 27 ) {
|
1303
|
-
close();
|
1304
|
-
}
|
1305
|
-
} );
|
1306
|
-
|
1307
|
-
if ( config.autoClose ) {
|
1308
|
-
dt.on( 'buttons-action.b-internal', function () {
|
1309
|
-
close();
|
1310
|
-
} );
|
1311
|
-
}
|
1312
|
-
}, 10 );
|
1313
1915
|
},
|
1314
|
-
background: true,
|
1315
|
-
collectionLayout: '',
|
1316
|
-
collectionTitle: '',
|
1317
|
-
backgroundClassName: 'dt-button-background',
|
1318
|
-
rightAlignClassName: 'dt-button-right',
|
1319
|
-
autoClose: false,
|
1320
|
-
fade: 400,
|
1321
1916
|
attr: {
|
1322
|
-
'aria-haspopup':
|
1917
|
+
'aria-haspopup': 'dialog'
|
1323
1918
|
}
|
1919
|
+
// Also the popover options, defined in Buttons.popover
|
1324
1920
|
},
|
1325
|
-
|
1326
|
-
|
1327
|
-
return '
|
1921
|
+
split: {
|
1922
|
+
text: function (dt) {
|
1923
|
+
return dt.i18n('buttons.split', 'Split');
|
1924
|
+
},
|
1925
|
+
className: 'buttons-split',
|
1926
|
+
closeButton: false,
|
1927
|
+
init: function (dt, button, config) {
|
1928
|
+
return button.attr('aria-expanded', false);
|
1929
|
+
},
|
1930
|
+
action: function (e, dt, button, config) {
|
1931
|
+
this.popover(config._collection, config);
|
1932
|
+
},
|
1933
|
+
attr: {
|
1934
|
+
'aria-haspopup': 'dialog'
|
1328
1935
|
}
|
1329
|
-
|
1330
|
-
|
1936
|
+
// Also the popover options, defined in Buttons.popover
|
1937
|
+
},
|
1938
|
+
copy: function (dt, conf) {
|
1939
|
+
if (_dtButtons.copyHtml5) {
|
1940
|
+
return 'copyHtml5';
|
1331
1941
|
}
|
1332
1942
|
},
|
1333
|
-
csv: function (
|
1334
|
-
|
1335
|
-
if ( _dtButtons.csvHtml5 && _dtButtons.csvHtml5.available( dt, conf ) ) {
|
1943
|
+
csv: function (dt, conf) {
|
1944
|
+
if (_dtButtons.csvHtml5 && _dtButtons.csvHtml5.available(dt, conf)) {
|
1336
1945
|
return 'csvHtml5';
|
1337
1946
|
}
|
1338
|
-
if ( _dtButtons.csvFlash && _dtButtons.csvFlash.available( dt, conf ) ) {
|
1339
|
-
return 'csvFlash';
|
1340
|
-
}
|
1341
1947
|
},
|
1342
|
-
excel: function (
|
1343
|
-
|
1344
|
-
if ( _dtButtons.excelHtml5 && _dtButtons.excelHtml5.available( dt, conf ) ) {
|
1948
|
+
excel: function (dt, conf) {
|
1949
|
+
if (_dtButtons.excelHtml5 && _dtButtons.excelHtml5.available(dt, conf)) {
|
1345
1950
|
return 'excelHtml5';
|
1346
1951
|
}
|
1347
|
-
if ( _dtButtons.excelFlash && _dtButtons.excelFlash.available( dt, conf ) ) {
|
1348
|
-
return 'excelFlash';
|
1349
|
-
}
|
1350
1952
|
},
|
1351
|
-
pdf: function (
|
1352
|
-
|
1353
|
-
if ( _dtButtons.pdfHtml5 && _dtButtons.pdfHtml5.available( dt, conf ) ) {
|
1953
|
+
pdf: function (dt, conf) {
|
1954
|
+
if (_dtButtons.pdfHtml5 && _dtButtons.pdfHtml5.available(dt, conf)) {
|
1354
1955
|
return 'pdfHtml5';
|
1355
1956
|
}
|
1356
|
-
if ( _dtButtons.pdfFlash && _dtButtons.pdfFlash.available( dt, conf ) ) {
|
1357
|
-
return 'pdfFlash';
|
1358
|
-
}
|
1359
1957
|
},
|
1360
|
-
pageLength: function (
|
1958
|
+
pageLength: function (dt) {
|
1361
1959
|
var lengthMenu = dt.settings()[0].aLengthMenu;
|
1362
|
-
var vals =
|
1363
|
-
var lang =
|
1364
|
-
var text = function (
|
1365
|
-
return dt.i18n(
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1960
|
+
var vals = [];
|
1961
|
+
var lang = [];
|
1962
|
+
var text = function (dt) {
|
1963
|
+
return dt.i18n(
|
1964
|
+
'buttons.pageLength',
|
1965
|
+
{
|
1966
|
+
'-1': 'Show all rows',
|
1967
|
+
_: 'Show %d rows'
|
1968
|
+
},
|
1969
|
+
dt.page.len()
|
1970
|
+
);
|
1369
1971
|
};
|
1370
1972
|
|
1973
|
+
// Support for DataTables 1.x 2D array
|
1974
|
+
if (Array.isArray(lengthMenu[0])) {
|
1975
|
+
vals = lengthMenu[0];
|
1976
|
+
lang = lengthMenu[1];
|
1977
|
+
}
|
1978
|
+
else {
|
1979
|
+
for (var i = 0; i < lengthMenu.length; i++) {
|
1980
|
+
var option = lengthMenu[i];
|
1981
|
+
|
1982
|
+
// Support for DataTables 2 object in the array
|
1983
|
+
if ($.isPlainObject(option)) {
|
1984
|
+
vals.push(option.value);
|
1985
|
+
lang.push(option.label);
|
1986
|
+
}
|
1987
|
+
else {
|
1988
|
+
vals.push(option);
|
1989
|
+
lang.push(option);
|
1990
|
+
}
|
1991
|
+
}
|
1992
|
+
}
|
1993
|
+
|
1371
1994
|
return {
|
1372
1995
|
extend: 'collection',
|
1373
1996
|
text: text,
|
1374
1997
|
className: 'buttons-page-length',
|
1375
1998
|
autoClose: true,
|
1376
|
-
buttons: $.map(
|
1999
|
+
buttons: $.map(vals, function (val, i) {
|
1377
2000
|
return {
|
1378
2001
|
text: lang[i],
|
1379
2002
|
className: 'button-page-length',
|
1380
|
-
action: function (
|
1381
|
-
dt.page.len(
|
2003
|
+
action: function (e, dt) {
|
2004
|
+
dt.page.len(val).draw();
|
1382
2005
|
},
|
1383
|
-
init: function (
|
2006
|
+
init: function (dt, node, conf) {
|
1384
2007
|
var that = this;
|
1385
2008
|
var fn = function () {
|
1386
|
-
that.active(
|
2009
|
+
that.active(dt.page.len() === val);
|
1387
2010
|
};
|
1388
2011
|
|
1389
|
-
dt.on(
|
2012
|
+
dt.on('length.dt' + conf.namespace, fn);
|
1390
2013
|
fn();
|
1391
2014
|
},
|
1392
|
-
destroy: function (
|
1393
|
-
dt.off(
|
2015
|
+
destroy: function (dt, node, conf) {
|
2016
|
+
dt.off('length.dt' + conf.namespace);
|
1394
2017
|
}
|
1395
2018
|
};
|
1396
|
-
}
|
1397
|
-
init: function (
|
2019
|
+
}),
|
2020
|
+
init: function (dt, node, conf) {
|
1398
2021
|
var that = this;
|
1399
|
-
dt.on(
|
1400
|
-
that.text(
|
1401
|
-
}
|
2022
|
+
dt.on('length.dt' + conf.namespace, function () {
|
2023
|
+
that.text(conf.text);
|
2024
|
+
});
|
1402
2025
|
},
|
1403
|
-
destroy: function (
|
1404
|
-
dt.off(
|
2026
|
+
destroy: function (dt, node, conf) {
|
2027
|
+
dt.off('length.dt' + conf.namespace);
|
1405
2028
|
}
|
1406
2029
|
};
|
2030
|
+
},
|
2031
|
+
spacer: {
|
2032
|
+
style: 'empty',
|
2033
|
+
spacer: true,
|
2034
|
+
text: function (dt) {
|
2035
|
+
return dt.i18n('buttons.spacer', '');
|
2036
|
+
}
|
1407
2037
|
}
|
1408
|
-
}
|
1409
|
-
|
2038
|
+
});
|
1410
2039
|
|
1411
2040
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
1412
2041
|
* DataTables API
|
@@ -1416,244 +2045,300 @@ $.extend( _dtButtons, {
|
|
1416
2045
|
*/
|
1417
2046
|
|
1418
2047
|
// Buttons group and individual button selector
|
1419
|
-
DataTable.Api.register(
|
2048
|
+
DataTable.Api.register('buttons()', function (group, selector) {
|
1420
2049
|
// Argument shifting
|
1421
|
-
if (
|
2050
|
+
if (selector === undefined) {
|
1422
2051
|
selector = group;
|
1423
2052
|
group = undefined;
|
1424
2053
|
}
|
1425
2054
|
|
1426
2055
|
this.selector.buttonGroup = group;
|
1427
2056
|
|
1428
|
-
var res = this.iterator(
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
2057
|
+
var res = this.iterator(
|
2058
|
+
true,
|
2059
|
+
'table',
|
2060
|
+
function (ctx) {
|
2061
|
+
if (ctx._buttons) {
|
2062
|
+
return Buttons.buttonSelector(
|
2063
|
+
Buttons.instanceSelector(group, ctx._buttons),
|
2064
|
+
selector
|
2065
|
+
);
|
2066
|
+
}
|
2067
|
+
},
|
2068
|
+
true
|
2069
|
+
);
|
1436
2070
|
|
1437
2071
|
res._groupSelector = group;
|
1438
2072
|
return res;
|
1439
|
-
}
|
2073
|
+
});
|
1440
2074
|
|
1441
2075
|
// Individual button selector
|
1442
|
-
DataTable.Api.register(
|
2076
|
+
DataTable.Api.register('button()', function (group, selector) {
|
1443
2077
|
// just run buttons() and truncate
|
1444
|
-
var buttons = this.buttons(
|
2078
|
+
var buttons = this.buttons(group, selector);
|
1445
2079
|
|
1446
|
-
if (
|
1447
|
-
buttons.splice(
|
2080
|
+
if (buttons.length > 1) {
|
2081
|
+
buttons.splice(1, buttons.length);
|
1448
2082
|
}
|
1449
2083
|
|
1450
2084
|
return buttons;
|
1451
|
-
}
|
2085
|
+
});
|
1452
2086
|
|
1453
2087
|
// Active buttons
|
1454
|
-
DataTable.Api.registerPlural(
|
1455
|
-
if (
|
1456
|
-
return this.map(
|
1457
|
-
return set.inst.active(
|
1458
|
-
}
|
2088
|
+
DataTable.Api.registerPlural('buttons().active()', 'button().active()', function (flag) {
|
2089
|
+
if (flag === undefined) {
|
2090
|
+
return this.map(function (set) {
|
2091
|
+
return set.inst.active(set.node);
|
2092
|
+
});
|
1459
2093
|
}
|
1460
2094
|
|
1461
|
-
return this.each(
|
1462
|
-
set.inst.active(
|
1463
|
-
}
|
1464
|
-
}
|
2095
|
+
return this.each(function (set) {
|
2096
|
+
set.inst.active(set.node, flag);
|
2097
|
+
});
|
2098
|
+
});
|
1465
2099
|
|
1466
2100
|
// Get / set button action
|
1467
|
-
DataTable.Api.registerPlural(
|
1468
|
-
if (
|
1469
|
-
return this.map(
|
1470
|
-
return set.inst.action(
|
1471
|
-
}
|
2101
|
+
DataTable.Api.registerPlural('buttons().action()', 'button().action()', function (action) {
|
2102
|
+
if (action === undefined) {
|
2103
|
+
return this.map(function (set) {
|
2104
|
+
return set.inst.action(set.node);
|
2105
|
+
});
|
1472
2106
|
}
|
1473
2107
|
|
1474
|
-
return this.each(
|
1475
|
-
set.inst.action(
|
1476
|
-
}
|
1477
|
-
}
|
2108
|
+
return this.each(function (set) {
|
2109
|
+
set.inst.action(set.node, action);
|
2110
|
+
});
|
2111
|
+
});
|
2112
|
+
|
2113
|
+
// Collection control
|
2114
|
+
DataTable.Api.registerPlural(
|
2115
|
+
'buttons().collectionRebuild()',
|
2116
|
+
'button().collectionRebuild()',
|
2117
|
+
function (buttons) {
|
2118
|
+
return this.each(function (set) {
|
2119
|
+
for (var i = 0; i < buttons.length; i++) {
|
2120
|
+
if (typeof buttons[i] === 'object') {
|
2121
|
+
buttons[i].parentConf = set;
|
2122
|
+
}
|
2123
|
+
}
|
2124
|
+
set.inst.collectionRebuild(set.node, buttons);
|
2125
|
+
});
|
2126
|
+
}
|
2127
|
+
);
|
1478
2128
|
|
1479
2129
|
// Enable / disable buttons
|
1480
|
-
DataTable.Api.register(
|
1481
|
-
return this.each(
|
1482
|
-
set.inst.enable(
|
1483
|
-
}
|
1484
|
-
}
|
2130
|
+
DataTable.Api.register(['buttons().enable()', 'button().enable()'], function (flag) {
|
2131
|
+
return this.each(function (set) {
|
2132
|
+
set.inst.enable(set.node, flag);
|
2133
|
+
});
|
2134
|
+
});
|
1485
2135
|
|
1486
2136
|
// Disable buttons
|
1487
|
-
DataTable.Api.register(
|
1488
|
-
return this.each(
|
1489
|
-
set.inst.disable(
|
1490
|
-
}
|
1491
|
-
}
|
2137
|
+
DataTable.Api.register(['buttons().disable()', 'button().disable()'], function () {
|
2138
|
+
return this.each(function (set) {
|
2139
|
+
set.inst.disable(set.node);
|
2140
|
+
});
|
2141
|
+
});
|
2142
|
+
|
2143
|
+
// Button index
|
2144
|
+
DataTable.Api.register('button().index()', function () {
|
2145
|
+
var idx = null;
|
2146
|
+
|
2147
|
+
this.each(function (set) {
|
2148
|
+
var res = set.inst.index(set.node);
|
2149
|
+
|
2150
|
+
if (res !== null) {
|
2151
|
+
idx = res;
|
2152
|
+
}
|
2153
|
+
});
|
2154
|
+
|
2155
|
+
return idx;
|
2156
|
+
});
|
1492
2157
|
|
1493
2158
|
// Get button nodes
|
1494
|
-
DataTable.Api.registerPlural(
|
2159
|
+
DataTable.Api.registerPlural('buttons().nodes()', 'button().node()', function () {
|
1495
2160
|
var jq = $();
|
1496
2161
|
|
1497
2162
|
// jQuery will automatically reduce duplicates to a single entry
|
1498
|
-
$(
|
1499
|
-
|
1500
|
-
|
2163
|
+
$(
|
2164
|
+
this.each(function (set) {
|
2165
|
+
jq = jq.add(set.inst.node(set.node));
|
2166
|
+
})
|
2167
|
+
);
|
1501
2168
|
|
1502
2169
|
return jq;
|
1503
|
-
}
|
2170
|
+
});
|
1504
2171
|
|
1505
2172
|
// Get / set button processing state
|
1506
|
-
DataTable.Api.registerPlural(
|
1507
|
-
if (
|
1508
|
-
return this.map(
|
1509
|
-
return set.inst.processing(
|
1510
|
-
}
|
2173
|
+
DataTable.Api.registerPlural('buttons().processing()', 'button().processing()', function (flag) {
|
2174
|
+
if (flag === undefined) {
|
2175
|
+
return this.map(function (set) {
|
2176
|
+
return set.inst.processing(set.node);
|
2177
|
+
});
|
1511
2178
|
}
|
1512
2179
|
|
1513
|
-
return this.each(
|
1514
|
-
set.inst.processing(
|
1515
|
-
}
|
1516
|
-
}
|
2180
|
+
return this.each(function (set) {
|
2181
|
+
set.inst.processing(set.node, flag);
|
2182
|
+
});
|
2183
|
+
});
|
1517
2184
|
|
1518
2185
|
// Get / set button text (i.e. the button labels)
|
1519
|
-
DataTable.Api.registerPlural(
|
1520
|
-
if (
|
1521
|
-
return this.map(
|
1522
|
-
return set.inst.text(
|
1523
|
-
}
|
2186
|
+
DataTable.Api.registerPlural('buttons().text()', 'button().text()', function (label) {
|
2187
|
+
if (label === undefined) {
|
2188
|
+
return this.map(function (set) {
|
2189
|
+
return set.inst.text(set.node);
|
2190
|
+
});
|
1524
2191
|
}
|
1525
2192
|
|
1526
|
-
return this.each(
|
1527
|
-
set.inst.text(
|
1528
|
-
}
|
1529
|
-
}
|
2193
|
+
return this.each(function (set) {
|
2194
|
+
set.inst.text(set.node, label);
|
2195
|
+
});
|
2196
|
+
});
|
1530
2197
|
|
1531
2198
|
// Trigger a button's action
|
1532
|
-
DataTable.Api.registerPlural(
|
1533
|
-
return this.each(
|
1534
|
-
set.inst.node(
|
1535
|
-
}
|
1536
|
-
}
|
2199
|
+
DataTable.Api.registerPlural('buttons().trigger()', 'button().trigger()', function () {
|
2200
|
+
return this.each(function (set) {
|
2201
|
+
set.inst.node(set.node).trigger('click');
|
2202
|
+
});
|
2203
|
+
});
|
2204
|
+
|
2205
|
+
// Button resolver to the popover
|
2206
|
+
DataTable.Api.register('button().popover()', function (content, options) {
|
2207
|
+
return this.map(function (set) {
|
2208
|
+
return set.inst._popover(content, this.button(this[0].node), options);
|
2209
|
+
});
|
2210
|
+
});
|
1537
2211
|
|
1538
2212
|
// Get the container elements
|
1539
|
-
DataTable.Api.
|
2213
|
+
DataTable.Api.register('buttons().containers()', function () {
|
1540
2214
|
var jq = $();
|
1541
2215
|
var groupSelector = this._groupSelector;
|
1542
2216
|
|
1543
2217
|
// We need to use the group selector directly, since if there are no buttons
|
1544
2218
|
// the result set will be empty
|
1545
|
-
this.iterator(
|
1546
|
-
if (
|
1547
|
-
var insts = Buttons.instanceSelector(
|
2219
|
+
this.iterator(true, 'table', function (ctx) {
|
2220
|
+
if (ctx._buttons) {
|
2221
|
+
var insts = Buttons.instanceSelector(groupSelector, ctx._buttons);
|
1548
2222
|
|
1549
|
-
for (
|
1550
|
-
jq = jq.add(
|
2223
|
+
for (var i = 0, ien = insts.length; i < ien; i++) {
|
2224
|
+
jq = jq.add(insts[i].container());
|
1551
2225
|
}
|
1552
2226
|
}
|
1553
|
-
}
|
2227
|
+
});
|
1554
2228
|
|
1555
2229
|
return jq;
|
1556
|
-
}
|
2230
|
+
});
|
2231
|
+
|
2232
|
+
DataTable.Api.register('buttons().container()', function () {
|
2233
|
+
// API level of nesting is `buttons()` so we can zip into the containers method
|
2234
|
+
return this.containers().eq(0);
|
2235
|
+
});
|
1557
2236
|
|
1558
2237
|
// Add a new button
|
1559
|
-
DataTable.Api.register(
|
2238
|
+
DataTable.Api.register('button().add()', function (idx, conf, draw) {
|
1560
2239
|
var ctx = this.context;
|
1561
2240
|
|
1562
2241
|
// Don't use `this` as it could be empty - select the instances directly
|
1563
|
-
if (
|
1564
|
-
var inst = Buttons.instanceSelector(
|
2242
|
+
if (ctx.length) {
|
2243
|
+
var inst = Buttons.instanceSelector(this._groupSelector, ctx[0]._buttons);
|
1565
2244
|
|
1566
|
-
if (
|
1567
|
-
inst[0].add(
|
2245
|
+
if (inst.length) {
|
2246
|
+
inst[0].add(conf, idx, draw);
|
1568
2247
|
}
|
1569
2248
|
}
|
1570
2249
|
|
1571
|
-
return this.button(
|
1572
|
-
}
|
2250
|
+
return this.button(this._groupSelector, idx);
|
2251
|
+
});
|
1573
2252
|
|
1574
2253
|
// Destroy the button sets selected
|
1575
|
-
DataTable.Api.register(
|
1576
|
-
this.pluck(
|
1577
|
-
|
1578
|
-
|
2254
|
+
DataTable.Api.register('buttons().destroy()', function () {
|
2255
|
+
this.pluck('inst')
|
2256
|
+
.unique()
|
2257
|
+
.each(function (inst) {
|
2258
|
+
inst.destroy();
|
2259
|
+
});
|
1579
2260
|
|
1580
2261
|
return this;
|
1581
|
-
}
|
2262
|
+
});
|
1582
2263
|
|
1583
2264
|
// Remove a button
|
1584
|
-
DataTable.Api.registerPlural(
|
1585
|
-
this.each(
|
1586
|
-
set.inst.remove(
|
1587
|
-
}
|
2265
|
+
DataTable.Api.registerPlural('buttons().remove()', 'buttons().remove()', function () {
|
2266
|
+
this.each(function (set) {
|
2267
|
+
set.inst.remove(set.node);
|
2268
|
+
});
|
1588
2269
|
|
1589
2270
|
return this;
|
1590
|
-
}
|
2271
|
+
});
|
1591
2272
|
|
1592
2273
|
// Information box that can be used by buttons
|
1593
2274
|
var _infoTimer;
|
1594
|
-
DataTable.Api.register(
|
2275
|
+
DataTable.Api.register('buttons.info()', function (title, message, time) {
|
1595
2276
|
var that = this;
|
1596
2277
|
|
1597
|
-
if (
|
1598
|
-
|
2278
|
+
if (title === false) {
|
2279
|
+
this.off('destroy.btn-info');
|
2280
|
+
_fadeOut($('#datatables_buttons_info'), 400, function () {
|
1599
2281
|
$(this).remove();
|
1600
|
-
}
|
1601
|
-
clearTimeout(
|
2282
|
+
});
|
2283
|
+
clearTimeout(_infoTimer);
|
1602
2284
|
_infoTimer = null;
|
1603
2285
|
|
1604
2286
|
return this;
|
1605
2287
|
}
|
1606
2288
|
|
1607
|
-
if (
|
1608
|
-
clearTimeout(
|
2289
|
+
if (_infoTimer) {
|
2290
|
+
clearTimeout(_infoTimer);
|
1609
2291
|
}
|
1610
2292
|
|
1611
|
-
if (
|
2293
|
+
if ($('#datatables_buttons_info').length) {
|
1612
2294
|
$('#datatables_buttons_info').remove();
|
1613
2295
|
}
|
1614
2296
|
|
1615
|
-
title = title ? '<h2>'+title+'</h2>' : '';
|
2297
|
+
title = title ? '<h2>' + title + '</h2>' : '';
|
1616
2298
|
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
2299
|
+
_fadeIn(
|
2300
|
+
$('<div id="datatables_buttons_info" class="dt-button-info"/>')
|
2301
|
+
.html(title)
|
2302
|
+
.append($('<div/>')[typeof message === 'string' ? 'html' : 'append'](message))
|
2303
|
+
.css('display', 'none')
|
2304
|
+
.appendTo('body')
|
2305
|
+
);
|
1623
2306
|
|
1624
|
-
if (
|
1625
|
-
_infoTimer = setTimeout(
|
1626
|
-
that.buttons.info(
|
1627
|
-
}, time
|
2307
|
+
if (time !== undefined && time !== 0) {
|
2308
|
+
_infoTimer = setTimeout(function () {
|
2309
|
+
that.buttons.info(false);
|
2310
|
+
}, time);
|
1628
2311
|
}
|
1629
2312
|
|
2313
|
+
this.on('destroy.btn-info', function () {
|
2314
|
+
that.buttons.info(false);
|
2315
|
+
});
|
2316
|
+
|
1630
2317
|
return this;
|
1631
|
-
}
|
2318
|
+
});
|
1632
2319
|
|
1633
2320
|
// Get data from the table for export - this is common to a number of plug-in
|
1634
2321
|
// buttons so it is included in the Buttons core library
|
1635
|
-
DataTable.Api.register(
|
1636
|
-
if (
|
1637
|
-
return _exportData(
|
2322
|
+
DataTable.Api.register('buttons.exportData()', function (options) {
|
2323
|
+
if (this.context.length) {
|
2324
|
+
return _exportData(new DataTable.Api(this.context[0]), options);
|
1638
2325
|
}
|
1639
|
-
}
|
2326
|
+
});
|
1640
2327
|
|
1641
2328
|
// Get information about the export that is common to many of the export data
|
1642
2329
|
// types (DRY)
|
1643
|
-
DataTable.Api.register(
|
1644
|
-
if (
|
2330
|
+
DataTable.Api.register('buttons.exportInfo()', function (conf) {
|
2331
|
+
if (!conf) {
|
1645
2332
|
conf = {};
|
1646
2333
|
}
|
1647
2334
|
|
1648
2335
|
return {
|
1649
|
-
filename: _filename(
|
1650
|
-
title: _title(
|
2336
|
+
filename: _filename(conf),
|
2337
|
+
title: _title(conf),
|
1651
2338
|
messageTop: _message(this, conf.message || conf.messageTop, 'top'),
|
1652
2339
|
messageBottom: _message(this, conf.messageBottom, 'bottom')
|
1653
2340
|
};
|
1654
|
-
}
|
1655
|
-
|
1656
|
-
|
2341
|
+
});
|
1657
2342
|
|
1658
2343
|
/**
|
1659
2344
|
* Get the file name for an exported file.
|
@@ -1661,30 +2346,34 @@ DataTable.Api.register( 'buttons.exportInfo()', function ( conf ) {
|
|
1661
2346
|
* @param {object} config Button configuration
|
1662
2347
|
* @param {boolean} incExtension Include the file name extension
|
1663
2348
|
*/
|
1664
|
-
var _filename = function (
|
1665
|
-
{
|
2349
|
+
var _filename = function (config) {
|
1666
2350
|
// Backwards compatibility
|
1667
|
-
var filename =
|
1668
|
-
config.
|
1669
|
-
config.
|
1670
|
-
|
1671
|
-
|
2351
|
+
var filename =
|
2352
|
+
config.filename === '*' &&
|
2353
|
+
config.title !== '*' &&
|
2354
|
+
config.title !== undefined &&
|
2355
|
+
config.title !== null &&
|
2356
|
+
config.title !== ''
|
2357
|
+
? config.title
|
2358
|
+
: config.filename;
|
2359
|
+
|
2360
|
+
if (typeof filename === 'function') {
|
1672
2361
|
filename = filename();
|
1673
2362
|
}
|
1674
2363
|
|
1675
|
-
if (
|
2364
|
+
if (filename === undefined || filename === null) {
|
1676
2365
|
return null;
|
1677
2366
|
}
|
1678
2367
|
|
1679
|
-
if (
|
1680
|
-
filename =
|
2368
|
+
if (filename.indexOf('*') !== -1) {
|
2369
|
+
filename = filename.replace('*', $('head > title').text()).trim();
|
1681
2370
|
}
|
1682
2371
|
|
1683
2372
|
// Strip characters which the OS will object to
|
1684
|
-
filename = filename.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g,
|
2373
|
+
filename = filename.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g, '');
|
1685
2374
|
|
1686
|
-
var extension = _stringOrFunction(
|
1687
|
-
if (
|
2375
|
+
var extension = _stringOrFunction(config.extension);
|
2376
|
+
if (!extension) {
|
1688
2377
|
extension = '';
|
1689
2378
|
}
|
1690
2379
|
|
@@ -1697,12 +2386,11 @@ var _filename = function ( config )
|
|
1697
2386
|
* @param {undefined|string|function} option Option
|
1698
2387
|
* @return {null|string} Resolved value
|
1699
2388
|
*/
|
1700
|
-
var _stringOrFunction = function (
|
1701
|
-
{
|
1702
|
-
if ( option === null || option === undefined ) {
|
2389
|
+
var _stringOrFunction = function (option) {
|
2390
|
+
if (option === null || option === undefined) {
|
1703
2391
|
return null;
|
1704
2392
|
}
|
1705
|
-
else if (
|
2393
|
+
else if (typeof option === 'function') {
|
1706
2394
|
return option();
|
1707
2395
|
}
|
1708
2396
|
return option;
|
@@ -1713,146 +2401,113 @@ var _stringOrFunction = function ( option )
|
|
1713
2401
|
*
|
1714
2402
|
* @param {object} config Button configuration
|
1715
2403
|
*/
|
1716
|
-
var _title = function (
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
2404
|
+
var _title = function (config) {
|
2405
|
+
var title = _stringOrFunction(config.title);
|
2406
|
+
|
2407
|
+
return title === null
|
2408
|
+
? null
|
2409
|
+
: title.indexOf('*') !== -1
|
2410
|
+
? title.replace('*', $('head > title').text() || 'Exported data')
|
2411
|
+
: title;
|
1724
2412
|
};
|
1725
2413
|
|
1726
|
-
var _message = function (
|
1727
|
-
|
1728
|
-
|
1729
|
-
if ( message === null ) {
|
2414
|
+
var _message = function (dt, option, position) {
|
2415
|
+
var message = _stringOrFunction(option);
|
2416
|
+
if (message === null) {
|
1730
2417
|
return null;
|
1731
2418
|
}
|
1732
2419
|
|
1733
2420
|
var caption = $('caption', dt.table().container()).eq(0);
|
1734
|
-
if (
|
1735
|
-
var side = caption.css(
|
1736
|
-
if (
|
2421
|
+
if (message === '*') {
|
2422
|
+
var side = caption.css('caption-side');
|
2423
|
+
if (side !== position) {
|
1737
2424
|
return null;
|
1738
2425
|
}
|
1739
2426
|
|
1740
|
-
return caption.length ?
|
1741
|
-
caption.text() :
|
1742
|
-
'';
|
2427
|
+
return caption.length ? caption.text() : '';
|
1743
2428
|
}
|
1744
2429
|
|
1745
2430
|
return message;
|
1746
2431
|
};
|
1747
2432
|
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
2433
|
var _exportTextarea = $('<textarea/>')[0];
|
1755
|
-
var _exportData = function (
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
|
1765
|
-
stripHtml: true,
|
1766
|
-
stripNewlines: true,
|
1767
|
-
decodeEntities: true,
|
1768
|
-
trim: true,
|
1769
|
-
format: {
|
1770
|
-
header: function ( d ) {
|
1771
|
-
return strip( d );
|
2434
|
+
var _exportData = function (dt, inOpts) {
|
2435
|
+
var config = $.extend(
|
2436
|
+
true,
|
2437
|
+
{},
|
2438
|
+
{
|
2439
|
+
rows: null,
|
2440
|
+
columns: '',
|
2441
|
+
modifier: {
|
2442
|
+
search: 'applied',
|
2443
|
+
order: 'applied'
|
1772
2444
|
},
|
1773
|
-
|
1774
|
-
|
2445
|
+
orthogonal: 'display',
|
2446
|
+
stripHtml: true,
|
2447
|
+
stripNewlines: true,
|
2448
|
+
decodeEntities: true,
|
2449
|
+
trim: true,
|
2450
|
+
format: {
|
2451
|
+
header: function (d) {
|
2452
|
+
return Buttons.stripData(d, config);
|
2453
|
+
},
|
2454
|
+
footer: function (d) {
|
2455
|
+
return Buttons.stripData(d, config);
|
2456
|
+
},
|
2457
|
+
body: function (d) {
|
2458
|
+
return Buttons.stripData(d, config);
|
2459
|
+
}
|
1775
2460
|
},
|
1776
|
-
|
1777
|
-
return strip( d );
|
1778
|
-
}
|
2461
|
+
customizeData: null
|
1779
2462
|
},
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
var
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1791
|
-
// Always remove comments
|
1792
|
-
str = str.replace( /<!\-\-.*?\-\->/g, '' );
|
1793
|
-
|
1794
|
-
if ( config.stripHtml ) {
|
1795
|
-
str = str.replace( /<[^>]*>/g, '' );
|
1796
|
-
}
|
1797
|
-
|
1798
|
-
if ( config.trim ) {
|
1799
|
-
str = str.replace( /^\s+|\s+$/g, '' );
|
1800
|
-
}
|
1801
|
-
|
1802
|
-
if ( config.stripNewlines ) {
|
1803
|
-
str = str.replace( /\n/g, ' ' );
|
1804
|
-
}
|
1805
|
-
|
1806
|
-
if ( config.decodeEntities ) {
|
1807
|
-
_exportTextarea.innerHTML = str;
|
1808
|
-
str = _exportTextarea.value;
|
1809
|
-
}
|
1810
|
-
|
1811
|
-
return str;
|
1812
|
-
};
|
1813
|
-
|
1814
|
-
|
1815
|
-
var header = dt.columns( config.columns ).indexes().map( function (idx) {
|
1816
|
-
var el = dt.column( idx ).header();
|
1817
|
-
return config.format.header( el.innerHTML, idx, el );
|
1818
|
-
} ).toArray();
|
2463
|
+
inOpts
|
2464
|
+
);
|
2465
|
+
|
2466
|
+
var header = dt
|
2467
|
+
.columns(config.columns)
|
2468
|
+
.indexes()
|
2469
|
+
.map(function (idx) {
|
2470
|
+
var el = dt.column(idx).header();
|
2471
|
+
return config.format.header(el.innerHTML, idx, el);
|
2472
|
+
})
|
2473
|
+
.toArray();
|
1819
2474
|
|
1820
|
-
var footer = dt.table().footer()
|
1821
|
-
dt
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
2475
|
+
var footer = dt.table().footer()
|
2476
|
+
? dt
|
2477
|
+
.columns(config.columns)
|
2478
|
+
.indexes()
|
2479
|
+
.map(function (idx) {
|
2480
|
+
var el = dt.column(idx).footer();
|
2481
|
+
return config.format.footer(el ? el.innerHTML : '', idx, el);
|
2482
|
+
})
|
2483
|
+
.toArray()
|
2484
|
+
: null;
|
1826
2485
|
|
1827
2486
|
// If Select is available on this table, and any rows are selected, limit the export
|
1828
2487
|
// to the selected rows. If no rows are selected, all rows will be exported. Specify
|
1829
2488
|
// a `selected` modifier to control directly.
|
1830
|
-
var modifier = $.extend(
|
1831
|
-
if (
|
1832
|
-
if (
|
1833
|
-
$.extend(
|
2489
|
+
var modifier = $.extend({}, config.modifier);
|
2490
|
+
if (dt.select && typeof dt.select.info === 'function' && modifier.selected === undefined) {
|
2491
|
+
if (dt.rows(config.rows, $.extend({ selected: true }, modifier)).any()) {
|
2492
|
+
$.extend(modifier, { selected: true });
|
1834
2493
|
}
|
1835
2494
|
}
|
1836
2495
|
|
1837
|
-
var rowIndexes = dt.rows(
|
1838
|
-
var selectedCells = dt.cells(
|
1839
|
-
var cells = selectedCells
|
1840
|
-
|
1841
|
-
.toArray();
|
1842
|
-
var cellNodes = selectedCells
|
1843
|
-
.nodes()
|
1844
|
-
.toArray();
|
2496
|
+
var rowIndexes = dt.rows(config.rows, modifier).indexes().toArray();
|
2497
|
+
var selectedCells = dt.cells(rowIndexes, config.columns);
|
2498
|
+
var cells = selectedCells.render(config.orthogonal).toArray();
|
2499
|
+
var cellNodes = selectedCells.nodes().toArray();
|
1845
2500
|
|
1846
2501
|
var columns = header.length;
|
1847
2502
|
var rows = columns > 0 ? cells.length / columns : 0;
|
1848
2503
|
var body = [];
|
1849
2504
|
var cellCounter = 0;
|
1850
2505
|
|
1851
|
-
for (
|
1852
|
-
var row = [
|
2506
|
+
for (var i = 0, ien = rows; i < ien; i++) {
|
2507
|
+
var row = [columns];
|
1853
2508
|
|
1854
|
-
for (
|
1855
|
-
row[j] = config.format.body(
|
2509
|
+
for (var j = 0; j < columns; j++) {
|
2510
|
+
row[j] = config.format.body(cells[cellCounter], i, j, cellNodes[cellCounter]);
|
1856
2511
|
cellCounter++;
|
1857
2512
|
}
|
1858
2513
|
|
@@ -1862,17 +2517,16 @@ var _exportData = function ( dt, inOpts )
|
|
1862
2517
|
var data = {
|
1863
2518
|
header: header,
|
1864
2519
|
footer: footer,
|
1865
|
-
body:
|
2520
|
+
body: body
|
1866
2521
|
};
|
1867
2522
|
|
1868
|
-
if (
|
1869
|
-
config.customizeData(
|
2523
|
+
if (config.customizeData) {
|
2524
|
+
config.customizeData(data);
|
1870
2525
|
}
|
1871
2526
|
|
1872
2527
|
return data;
|
1873
2528
|
};
|
1874
2529
|
|
1875
|
-
|
1876
2530
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
1877
2531
|
* DataTables interface
|
1878
2532
|
*/
|
@@ -1881,36 +2535,41 @@ var _exportData = function ( dt, inOpts )
|
|
1881
2535
|
$.fn.dataTable.Buttons = Buttons;
|
1882
2536
|
$.fn.DataTable.Buttons = Buttons;
|
1883
2537
|
|
1884
|
-
|
1885
|
-
|
1886
2538
|
// DataTables creation - check if the buttons have been defined for this table,
|
1887
2539
|
// they will have been if the `B` option was used in `dom`, otherwise we should
|
1888
2540
|
// create the buttons instance here so they can be inserted into the document
|
1889
2541
|
// using the API. Listen for `init` for compatibility with pre 1.10.10, but to
|
1890
2542
|
// be removed in future.
|
1891
|
-
$(document).on(
|
1892
|
-
if (
|
2543
|
+
$(document).on('init.dt plugin-init.dt', function (e, settings) {
|
2544
|
+
if (e.namespace !== 'dt') {
|
1893
2545
|
return;
|
1894
2546
|
}
|
1895
2547
|
|
1896
2548
|
var opts = settings.oInit.buttons || DataTable.defaults.buttons;
|
1897
2549
|
|
1898
|
-
if (
|
1899
|
-
new Buttons(
|
2550
|
+
if (opts && !settings._buttons) {
|
2551
|
+
new Buttons(settings, opts).container();
|
1900
2552
|
}
|
1901
|
-
}
|
2553
|
+
});
|
2554
|
+
|
2555
|
+
function _init(settings, options) {
|
2556
|
+
var api = new DataTable.Api(settings);
|
2557
|
+
var opts = options ? options : api.init().buttons || DataTable.defaults.buttons;
|
2558
|
+
|
2559
|
+
return new Buttons(api, opts).container();
|
2560
|
+
}
|
1902
2561
|
|
1903
2562
|
// DataTables `dom` feature option
|
1904
|
-
DataTable.ext.feature.push(
|
1905
|
-
fnInit:
|
1906
|
-
|
1907
|
-
|
2563
|
+
DataTable.ext.feature.push({
|
2564
|
+
fnInit: _init,
|
2565
|
+
cFeature: 'B'
|
2566
|
+
});
|
1908
2567
|
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
}
|
2568
|
+
// DataTables 2 layout feature
|
2569
|
+
if (DataTable.ext.features) {
|
2570
|
+
DataTable.ext.features.register('buttons', _init);
|
2571
|
+
}
|
1913
2572
|
|
1914
2573
|
|
1915
|
-
return
|
2574
|
+
return DataTable;
|
1916
2575
|
}));
|