jquery-datatables-rails 3.3.0 → 3.4.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/bootstrap/3/jquery.dataTables.bootstrap.js +64 -29
- data/app/assets/javascripts/dataTables/extras/dataTables.autoFill.js +806 -648
- data/app/assets/javascripts/dataTables/extras/dataTables.buttons.js +1607 -0
- data/app/assets/javascripts/dataTables/extras/dataTables.colReorder.js +220 -267
- data/app/assets/javascripts/dataTables/extras/dataTables.fixedColumns.js +164 -69
- data/app/assets/javascripts/dataTables/extras/dataTables.fixedHeader.js +469 -870
- data/app/assets/javascripts/dataTables/extras/dataTables.keyTable.js +636 -972
- data/app/assets/javascripts/dataTables/extras/dataTables.responsive.js +472 -187
- data/app/assets/javascripts/dataTables/extras/dataTables.rowReorder.js +619 -0
- data/app/assets/javascripts/dataTables/extras/dataTables.scroller.js +146 -111
- data/app/assets/javascripts/dataTables/extras/dataTables.select.js +1038 -0
- data/app/assets/javascripts/dataTables/jquery.dataTables.api.fnGetColumnData.js +0 -0
- data/app/assets/javascripts/dataTables/jquery.dataTables.api.fnReloadAjax.js +0 -0
- data/app/assets/javascripts/dataTables/jquery.dataTables.foundation.js +37 -61
- data/app/assets/javascripts/dataTables/jquery.dataTables.js +720 -387
- data/app/assets/javascripts/dataTables/jquery.dataTables.sorting.ipAddress.js +44 -0
- data/app/assets/javascripts/dataTables/jquery.dataTables.sorting.numbersHtml.js +0 -0
- data/app/assets/javascripts/dataTables/jquery.dataTables.typeDetection.numbersHtml.js +0 -0
- data/app/assets/stylesheets/dataTables/jquery.dataTables.scss +34 -66
- data/app/assets/stylesheets/dataTables/src/demo_table.css +1 -1
- data/app/assets/stylesheets/dataTables/src/demo_table_jui.css.scss +4 -4
- data/lib/jquery/datatables/rails/version.rb +1 -1
- metadata +24 -19
@@ -1,11 +1,11 @@
|
|
1
|
-
/*! Responsive
|
1
|
+
/*! Responsive 2.0.0
|
2
2
|
* 2014-2015 SpryMedia Ltd - datatables.net/license
|
3
3
|
*/
|
4
4
|
|
5
5
|
/**
|
6
6
|
* @summary Responsive
|
7
7
|
* @description Responsive tables plug-in for DataTables
|
8
|
-
* @version
|
8
|
+
* @version 2.0.0
|
9
9
|
* @file dataTables.responsive.js
|
10
10
|
* @author SpryMedia Ltd (www.sprymedia.co.uk)
|
11
11
|
* @contact www.sprymedia.co.uk/contact
|
@@ -20,12 +20,35 @@
|
|
20
20
|
*
|
21
21
|
* For details please refer to: http://www.datatables.net
|
22
22
|
*/
|
23
|
+
(function( factory ){
|
24
|
+
if ( typeof define === 'function' && define.amd ) {
|
25
|
+
// AMD
|
26
|
+
define( ['jquery', 'datatables.net'], function ( $ ) {
|
27
|
+
return factory( $, window, document );
|
28
|
+
} );
|
29
|
+
}
|
30
|
+
else if ( typeof exports === 'object' ) {
|
31
|
+
// CommonJS
|
32
|
+
module.exports = function (root, $) {
|
33
|
+
if ( ! root ) {
|
34
|
+
root = window;
|
35
|
+
}
|
23
36
|
|
24
|
-
(
|
37
|
+
if ( ! $ || ! $.fn.dataTable ) {
|
38
|
+
$ = require('datatables.net')(root, $).$;
|
39
|
+
}
|
25
40
|
|
41
|
+
return factory( $, root, root.document );
|
42
|
+
};
|
43
|
+
}
|
44
|
+
else {
|
45
|
+
// Browser
|
46
|
+
factory( jQuery, window, document );
|
47
|
+
}
|
48
|
+
}(function( $, window, document, undefined ) {
|
49
|
+
'use strict';
|
50
|
+
var DataTable = $.fn.dataTable;
|
26
51
|
|
27
|
-
var factory = function( $, DataTable ) {
|
28
|
-
"use strict";
|
29
52
|
|
30
53
|
/**
|
31
54
|
* Responsive is a plug-in for the DataTables library that makes use of
|
@@ -64,7 +87,7 @@ var factory = function( $, DataTable ) {
|
|
64
87
|
* @param {object} settings DataTables settings object for the host table
|
65
88
|
* @param {object} [opts] Configuration options
|
66
89
|
* @requires jQuery 1.7+
|
67
|
-
* @requires DataTables 1.10.
|
90
|
+
* @requires DataTables 1.10.3+
|
68
91
|
*
|
69
92
|
* @example
|
70
93
|
* $('#example').DataTable( {
|
@@ -74,13 +97,14 @@ var factory = function( $, DataTable ) {
|
|
74
97
|
*/
|
75
98
|
var Responsive = function ( settings, opts ) {
|
76
99
|
// Sanity check that we are using DataTables 1.10 or newer
|
77
|
-
if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.
|
78
|
-
throw 'DataTables Responsive requires DataTables 1.10.
|
100
|
+
if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.3' ) ) {
|
101
|
+
throw 'DataTables Responsive requires DataTables 1.10.3 or newer';
|
79
102
|
}
|
80
103
|
|
81
104
|
this.s = {
|
82
105
|
dt: new DataTable.Api( settings ),
|
83
|
-
columns: []
|
106
|
+
columns: [],
|
107
|
+
current: []
|
84
108
|
};
|
85
109
|
|
86
110
|
// Check if responsive has already been initialised on this table
|
@@ -98,7 +122,7 @@ var Responsive = function ( settings, opts ) {
|
|
98
122
|
this._constructor();
|
99
123
|
};
|
100
124
|
|
101
|
-
Responsive.prototype
|
125
|
+
$.extend( Responsive.prototype, {
|
102
126
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
103
127
|
* Constructor
|
104
128
|
*/
|
@@ -112,17 +136,43 @@ Responsive.prototype = {
|
|
112
136
|
{
|
113
137
|
var that = this;
|
114
138
|
var dt = this.s.dt;
|
139
|
+
var dtPrivateSettings = dt.settings()[0];
|
115
140
|
|
116
141
|
dt.settings()[0]._responsive = this;
|
117
142
|
|
118
|
-
// Use DataTables'
|
119
|
-
|
143
|
+
// Use DataTables' throttle function to avoid processor thrashing on
|
144
|
+
// resize
|
145
|
+
$(window).on( 'resize.dtr orientationchange.dtr', DataTable.util.throttle( function () {
|
120
146
|
that._resize();
|
121
147
|
} ) );
|
122
148
|
|
149
|
+
// DataTables doesn't currently trigger an event when a row is added, so
|
150
|
+
// we need to hook into its private API to enforce the hidden rows when
|
151
|
+
// new data is added
|
152
|
+
dtPrivateSettings.oApi._fnCallbackReg( dtPrivateSettings, 'aoRowCreatedCallback', function (tr, data, idx) {
|
153
|
+
if ( $.inArray( false, that.s.current ) !== -1 ) {
|
154
|
+
$('td, th', tr).each( function ( i ) {
|
155
|
+
var idx = dt.column.index( 'toData', i );
|
156
|
+
|
157
|
+
if ( that.s.current[idx] === false ) {
|
158
|
+
$(this).css('display', 'none');
|
159
|
+
}
|
160
|
+
} );
|
161
|
+
}
|
162
|
+
} );
|
163
|
+
|
123
164
|
// Destroy event handler
|
124
165
|
dt.on( 'destroy.dtr', function () {
|
125
|
-
|
166
|
+
dt.off( '.dtr' );
|
167
|
+
$( dt.table().body() ).off( '.dtr' );
|
168
|
+
$(window).off( 'resize.dtr orientationchange.dtr' );
|
169
|
+
|
170
|
+
// Restore the columns that we've hidden
|
171
|
+
$.each( that.s.current, function ( i, val ) {
|
172
|
+
if ( val === false ) {
|
173
|
+
that._setColumnVis( i, true );
|
174
|
+
}
|
175
|
+
} );
|
126
176
|
} );
|
127
177
|
|
128
178
|
// Reorder the breakpoints array here in case they have been added out
|
@@ -132,40 +182,41 @@ Responsive.prototype = {
|
|
132
182
|
a.width > b.width ? -1 : 0;
|
133
183
|
} );
|
134
184
|
|
135
|
-
// Determine which columns are already hidden, and should therefore
|
136
|
-
// remain hidden. todo - should this be done? See thread 22677
|
137
|
-
//
|
138
|
-
// this.s.alwaysHidden = dt.columns(':hidden').indexes();
|
139
|
-
|
140
185
|
this._classLogic();
|
141
186
|
this._resizeAuto();
|
142
187
|
|
143
188
|
// Details handler
|
144
189
|
var details = this.c.details;
|
145
|
-
if ( details.type ) {
|
190
|
+
if ( details.type !== false ) {
|
146
191
|
that._detailsInit();
|
147
|
-
this._detailsVis();
|
148
192
|
|
149
|
-
|
150
|
-
|
193
|
+
// DataTables will trigger this event on every column it shows and
|
194
|
+
// hides individually
|
195
|
+
dt.on( 'column-visibility.dtr', function (e, ctx, col, vis) {
|
196
|
+
that._classLogic();
|
197
|
+
that._resizeAuto();
|
198
|
+
that._resize();
|
151
199
|
} );
|
152
200
|
|
153
|
-
// Redraw the details box on each draw
|
154
|
-
// DataTables implements a native
|
201
|
+
// Redraw the details box on each draw which will happen if the data
|
202
|
+
// has changed. This is used until DataTables implements a native
|
203
|
+
// `updated` event for rows
|
155
204
|
dt.on( 'draw.dtr', function () {
|
156
|
-
|
157
|
-
var row = dt.row( idx );
|
158
|
-
|
159
|
-
if ( row.child.isShown() ) {
|
160
|
-
var info = that.c.details.renderer( dt, idx );
|
161
|
-
row.child( info, 'child' ).show();
|
162
|
-
}
|
163
|
-
} );
|
205
|
+
that._redrawChildren();
|
164
206
|
} );
|
165
207
|
|
166
208
|
$(dt.table().node()).addClass( 'dtr-'+details.type );
|
167
209
|
}
|
168
210
|
|
211
|
+
dt.on( 'column-reorder.dtr', function (e, settings, details) {
|
212
|
+
// This requires ColReorder 1.2.1 or newer
|
213
|
+
if ( details.drop ) {
|
214
|
+
that._classLogic();
|
215
|
+
that._resizeAuto();
|
216
|
+
that._resize();
|
217
|
+
}
|
218
|
+
} );
|
219
|
+
|
169
220
|
// First pass - draw the table for the current viewport size
|
170
221
|
this._resize();
|
171
222
|
},
|
@@ -193,6 +244,24 @@ Responsive.prototype = {
|
|
193
244
|
var columns = this.s.columns;
|
194
245
|
var i, ien;
|
195
246
|
|
247
|
+
// Create an array that defines the column ordering based first on the
|
248
|
+
// column's priority, and secondly the column index. This allows the
|
249
|
+
// columns to be removed from the right if the priority matches
|
250
|
+
var order = columns
|
251
|
+
.map( function ( col, idx ) {
|
252
|
+
return {
|
253
|
+
columnIdx: idx,
|
254
|
+
priority: col.priority
|
255
|
+
};
|
256
|
+
} )
|
257
|
+
.sort( function ( a, b ) {
|
258
|
+
if ( a.priority !== b.priority ) {
|
259
|
+
return a.priority - b.priority;
|
260
|
+
}
|
261
|
+
return a.columnIdx - b.columnIdx;
|
262
|
+
} );
|
263
|
+
|
264
|
+
|
196
265
|
// Class logic - determine which columns are in this breakpoint based
|
197
266
|
// on the classes. If no class control (i.e. `auto`) then `-` is used
|
198
267
|
// to indicate this to the rest of the function
|
@@ -234,23 +303,25 @@ Responsive.prototype = {
|
|
234
303
|
}
|
235
304
|
}
|
236
305
|
|
237
|
-
// Allow columns to be shown (counting
|
238
|
-
// of room
|
306
|
+
// Allow columns to be shown (counting by priority and then right to
|
307
|
+
// left) until we run out of room
|
239
308
|
var empty = false;
|
240
|
-
for ( i=0, ien=
|
241
|
-
|
309
|
+
for ( i=0, ien=order.length ; i<ien ; i++ ) {
|
310
|
+
var colIdx = order[i].columnIdx;
|
311
|
+
|
312
|
+
if ( display[colIdx] === '-' && ! columns[colIdx].control && columns[colIdx].minWidth ) {
|
242
313
|
// Once we've found a column that won't fit we don't let any
|
243
314
|
// others display either, or columns might disappear in the
|
244
315
|
// middle of the table
|
245
|
-
if ( empty || usedWidth - columns[
|
316
|
+
if ( empty || usedWidth - columns[colIdx].minWidth < 0 ) {
|
246
317
|
empty = true;
|
247
|
-
display[
|
318
|
+
display[colIdx] = false;
|
248
319
|
}
|
249
320
|
else {
|
250
|
-
display[
|
321
|
+
display[colIdx] = true;
|
251
322
|
}
|
252
323
|
|
253
|
-
usedWidth -= columns[
|
324
|
+
usedWidth -= columns[colIdx].minWidth;
|
254
325
|
}
|
255
326
|
}
|
256
327
|
|
@@ -297,15 +368,25 @@ Responsive.prototype = {
|
|
297
368
|
var that = this;
|
298
369
|
var calc = {};
|
299
370
|
var breakpoints = this.c.breakpoints;
|
300
|
-
var
|
301
|
-
|
371
|
+
var dt = this.s.dt;
|
372
|
+
var columns = dt.columns().eq(0).map( function (i) {
|
373
|
+
var column = this.column(i);
|
374
|
+
var className = column.header().className;
|
375
|
+
var priority = dt.settings()[0].aoColumns[i].responsivePriority;
|
376
|
+
|
377
|
+
if ( priority === undefined ) {
|
378
|
+
priority = $(column.header).data('priority') !== undefined ?
|
379
|
+
$(column.header).data('priority') * 1 :
|
380
|
+
10000;
|
381
|
+
}
|
302
382
|
|
303
383
|
return {
|
304
384
|
className: className,
|
305
385
|
includeIn: [],
|
306
386
|
auto: false,
|
307
387
|
control: false,
|
308
|
-
never: className.match(/\bnever\b/) ? true : false
|
388
|
+
never: className.match(/\bnever\b/) ? true : false,
|
389
|
+
priority: priority
|
309
390
|
};
|
310
391
|
} );
|
311
392
|
|
@@ -346,8 +427,7 @@ Responsive.prototype = {
|
|
346
427
|
}
|
347
428
|
}
|
348
429
|
else if ( operator === 'not-' ) {
|
349
|
-
// Add all but this breakpoint
|
350
|
-
|
430
|
+
// Add all but this breakpoint
|
351
431
|
for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
|
352
432
|
if ( breakpoints[i].name.indexOf( matched ) === -1 ) {
|
353
433
|
add( colIdx, breakpoints[i].name );
|
@@ -374,7 +454,7 @@ Responsive.prototype = {
|
|
374
454
|
} );
|
375
455
|
return;
|
376
456
|
}
|
377
|
-
else if ( className === 'none' ||
|
457
|
+
else if ( className === 'none' || col.never ) {
|
378
458
|
// Include in none (default) and no auto
|
379
459
|
hasClass = true;
|
380
460
|
return;
|
@@ -418,6 +498,30 @@ Responsive.prototype = {
|
|
418
498
|
},
|
419
499
|
|
420
500
|
|
501
|
+
/**
|
502
|
+
* Show the details for the child row
|
503
|
+
*
|
504
|
+
* @param {DataTables.Api} row API instance for the row
|
505
|
+
* @param {boolean} update Update flag
|
506
|
+
* @private
|
507
|
+
*/
|
508
|
+
_detailsDisplay: function ( row, update )
|
509
|
+
{
|
510
|
+
var that = this;
|
511
|
+
var dt = this.s.dt;
|
512
|
+
|
513
|
+
var res = this.c.details.display( row, update, function () {
|
514
|
+
return that.c.details.renderer(
|
515
|
+
dt, row[0], that._detailsObj(row[0])
|
516
|
+
);
|
517
|
+
} );
|
518
|
+
|
519
|
+
if ( res === true || res === false ) {
|
520
|
+
$(dt.table().node()).triggerHandler( 'responsive-display.dt', [dt, row, res, update] );
|
521
|
+
}
|
522
|
+
},
|
523
|
+
|
524
|
+
|
421
525
|
/**
|
422
526
|
* Initialisation for the details handler
|
423
527
|
*
|
@@ -434,109 +538,93 @@ Responsive.prototype = {
|
|
434
538
|
details.target = 'td:first-child';
|
435
539
|
}
|
436
540
|
|
541
|
+
// Keyboard accessibility
|
542
|
+
dt.on( 'draw.dtr', function () {
|
543
|
+
that._tabIndexes();
|
544
|
+
} );
|
545
|
+
that._tabIndexes(); // Initial draw has already happened
|
546
|
+
|
547
|
+
$( dt.table().body() ).on( 'keyup.dtr', 'td', function (e) {
|
548
|
+
if ( e.keyCode === 13 && $(this).data('dtr-keyboard') ) {
|
549
|
+
$(this).click();
|
550
|
+
}
|
551
|
+
} );
|
552
|
+
|
437
553
|
// type.target can be a string jQuery selector or a column index
|
438
554
|
var target = details.target;
|
439
555
|
var selector = typeof target === 'string' ? target : 'td';
|
440
556
|
|
441
557
|
// Click handler to show / hide the details rows when they are available
|
442
|
-
$( dt.table().body() )
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
558
|
+
$( dt.table().body() )
|
559
|
+
.on( 'mousedown.dtr', selector, function (e) {
|
560
|
+
// For mouse users, prevent the focus ring from showing
|
561
|
+
e.preventDefault();
|
562
|
+
} )
|
563
|
+
.on( 'click.dtr', selector, function () {
|
564
|
+
// If the table is not collapsed (i.e. there is no hidden columns)
|
565
|
+
// then take no action
|
566
|
+
if ( ! $(dt.table().node()).hasClass('collapsed' ) ) {
|
567
|
+
return;
|
568
|
+
}
|
448
569
|
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
570
|
+
// Check that the row is actually a DataTable's controlled node
|
571
|
+
if ( ! dt.row( $(this).closest('tr') ).length ) {
|
572
|
+
return;
|
573
|
+
}
|
453
574
|
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
575
|
+
// For column index, we determine if we should act or not in the
|
576
|
+
// handler - otherwise it is already okay
|
577
|
+
if ( typeof target === 'number' ) {
|
578
|
+
var targetIdx = target < 0 ?
|
579
|
+
dt.columns().eq(0).length + target :
|
580
|
+
target;
|
460
581
|
|
461
|
-
|
462
|
-
|
582
|
+
if ( dt.cell( this ).index().column !== targetIdx ) {
|
583
|
+
return;
|
584
|
+
}
|
463
585
|
}
|
464
|
-
}
|
465
586
|
|
466
|
-
|
467
|
-
|
587
|
+
// $().closest() includes itself in its check
|
588
|
+
var row = dt.row( $(this).closest('tr') );
|
468
589
|
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
var info = that.c.details.renderer( dt, row[0] );
|
475
|
-
row.child( info, 'child' ).show();
|
476
|
-
$( row.node() ).addClass( 'parent' );
|
477
|
-
}
|
478
|
-
} );
|
590
|
+
// The renderer is given as a function so the caller can execute it
|
591
|
+
// only when they need (i.e. if hiding there is no point is running
|
592
|
+
// the renderer)
|
593
|
+
that._detailsDisplay( row, false );
|
594
|
+
} );
|
479
595
|
},
|
480
596
|
|
481
597
|
|
482
598
|
/**
|
483
|
-
*
|
484
|
-
*
|
599
|
+
* Get the details to pass to a renderer for a row
|
600
|
+
* @param {int} rowIdx Row index
|
485
601
|
* @private
|
486
602
|
*/
|
487
|
-
|
603
|
+
_detailsObj: function ( rowIdx )
|
488
604
|
{
|
489
605
|
var that = this;
|
490
606
|
var dt = this.s.dt;
|
491
607
|
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
if ( col.visible() ) {
|
497
|
-
return null;
|
608
|
+
return $.map( this.s.columns, function( col, i ) {
|
609
|
+
if ( col.never ) {
|
610
|
+
return;
|
498
611
|
}
|
499
612
|
|
500
|
-
|
501
|
-
|
613
|
+
return {
|
614
|
+
title: dt.settings()[0].aoColumns[ i ].sTitle,
|
615
|
+
data: dt.cell( rowIdx, i ).render( that.c.orthogonal ),
|
616
|
+
hidden: dt.column( i ).visible() && !that.s.current[ i ]
|
617
|
+
};
|
502
618
|
} );
|
503
|
-
var haveHidden = true;
|
504
|
-
|
505
|
-
if ( hiddenColumns.length === 0 || ( hiddenColumns.length === 1 && this.s.columns[ hiddenColumns[0] ].control ) ) {
|
506
|
-
haveHidden = false;
|
507
|
-
}
|
508
|
-
|
509
|
-
if ( haveHidden ) {
|
510
|
-
// Show all existing child rows
|
511
|
-
dt.rows( { page: 'current' } ).eq(0).each( function (idx) {
|
512
|
-
var row = dt.row( idx );
|
513
|
-
|
514
|
-
if ( row.child() ) {
|
515
|
-
var info = that.c.details.renderer( dt, row[0] );
|
516
|
-
|
517
|
-
// The renderer can return false to have no child row
|
518
|
-
if ( info === false ) {
|
519
|
-
row.child.hide();
|
520
|
-
}
|
521
|
-
else {
|
522
|
-
row.child( info, 'child' ).show();
|
523
|
-
}
|
524
|
-
}
|
525
|
-
} );
|
526
|
-
}
|
527
|
-
else {
|
528
|
-
// Hide all existing child rows
|
529
|
-
dt.rows( { page: 'current' } ).eq(0).each( function (idx) {
|
530
|
-
dt.row( idx ).child.hide();
|
531
|
-
} );
|
532
|
-
}
|
533
619
|
},
|
534
620
|
|
535
621
|
|
536
622
|
/**
|
537
623
|
* Find a breakpoint object from a name
|
624
|
+
*
|
538
625
|
* @param {string} name Breakpoint name to find
|
539
626
|
* @return {object} Breakpoint description object
|
627
|
+
* @private
|
540
628
|
*/
|
541
629
|
_find: function ( name )
|
542
630
|
{
|
@@ -550,6 +638,25 @@ Responsive.prototype = {
|
|
550
638
|
},
|
551
639
|
|
552
640
|
|
641
|
+
/**
|
642
|
+
* Re-create the contents of the child rows as the display has changed in
|
643
|
+
* some way.
|
644
|
+
*
|
645
|
+
* @private
|
646
|
+
*/
|
647
|
+
_redrawChildren: function ()
|
648
|
+
{
|
649
|
+
var that = this;
|
650
|
+
var dt = this.s.dt;
|
651
|
+
|
652
|
+
dt.rows( {page: 'current'} ).iterator( 'row', function ( settings, idx ) {
|
653
|
+
var row = dt.row( idx );
|
654
|
+
|
655
|
+
that._detailsDisplay( dt.row( idx ), true );
|
656
|
+
} );
|
657
|
+
},
|
658
|
+
|
659
|
+
|
553
660
|
/**
|
554
661
|
* Alter the table display for a resized viewport. This involves first
|
555
662
|
* determining what breakpoint the window currently is in, getting the
|
@@ -559,12 +666,14 @@ Responsive.prototype = {
|
|
559
666
|
*/
|
560
667
|
_resize: function ()
|
561
668
|
{
|
669
|
+
var that = this;
|
562
670
|
var dt = this.s.dt;
|
563
671
|
var width = $(window).width();
|
564
672
|
var breakpoints = this.c.breakpoints;
|
565
673
|
var breakpoint = breakpoints[0].name;
|
566
674
|
var columns = this.s.columns;
|
567
675
|
var i, ien;
|
676
|
+
var oldVis = this.s.current.slice();
|
568
677
|
|
569
678
|
// Determine what breakpoint we are currently at
|
570
679
|
for ( i=breakpoints.length-1 ; i>=0 ; i-- ) {
|
@@ -576,6 +685,7 @@ Responsive.prototype = {
|
|
576
685
|
|
577
686
|
// Show the columns for that break point
|
578
687
|
var columnsVis = this._columnsVisiblity( breakpoint );
|
688
|
+
this.s.current = columnsVis;
|
579
689
|
|
580
690
|
// Set the class before the column visibility is changed so event
|
581
691
|
// listeners know what the state is. Need to determine if there are
|
@@ -588,11 +698,20 @@ Responsive.prototype = {
|
|
588
698
|
}
|
589
699
|
}
|
590
700
|
|
591
|
-
$( dt.table().node() ).toggleClass('collapsed', collapsedClass );
|
701
|
+
$( dt.table().node() ).toggleClass( 'collapsed', collapsedClass );
|
702
|
+
|
703
|
+
var changed = false;
|
592
704
|
|
593
705
|
dt.columns().eq(0).each( function ( colIdx, i ) {
|
594
|
-
|
706
|
+
if ( columnsVis[i] !== oldVis[i] ) {
|
707
|
+
changed = true;
|
708
|
+
that._setColumnVis( colIdx, columnsVis[i] );
|
709
|
+
}
|
595
710
|
} );
|
711
|
+
|
712
|
+
if ( changed ) {
|
713
|
+
this._redrawChildren();
|
714
|
+
}
|
596
715
|
},
|
597
716
|
|
598
717
|
|
@@ -627,42 +746,120 @@ Responsive.prototype = {
|
|
627
746
|
var clonedHeader = $( dt.table().header().cloneNode( false ) ).appendTo( clonedTable );
|
628
747
|
var clonedBody = $( dt.table().body().cloneNode( false ) ).appendTo( clonedTable );
|
629
748
|
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
749
|
+
// Header
|
750
|
+
var headerCells = dt.columns()
|
751
|
+
.header()
|
752
|
+
.filter( function (idx) {
|
753
|
+
return dt.column(idx).visible();
|
754
|
+
} )
|
755
|
+
.to$()
|
756
|
+
.clone( false )
|
757
|
+
.css( 'display', 'table-cell' );
|
758
|
+
|
759
|
+
// Body rows - we don't need to take account of DataTables' column
|
760
|
+
// visibility since we implement our own here (hence the `display` set)
|
761
|
+
$(clonedBody)
|
762
|
+
.append( $(dt.rows( { page: 'current' } ).nodes()).clone( false ) )
|
763
|
+
.find( 'th, td' ).css( 'display', '' );
|
764
|
+
|
765
|
+
// Footer
|
766
|
+
var footer = dt.table().footer();
|
767
|
+
if ( footer ) {
|
768
|
+
var clonedFooter = $( footer.cloneNode( false ) ).appendTo( clonedTable );
|
769
|
+
var footerCells = dt.columns()
|
770
|
+
.header()
|
771
|
+
.filter( function (idx) {
|
772
|
+
return dt.column(idx).visible();
|
773
|
+
} )
|
774
|
+
.to$()
|
775
|
+
.clone( false )
|
776
|
+
.css( 'display', 'table-cell' );
|
777
|
+
|
778
|
+
$('<tr/>')
|
779
|
+
.append( footerCells )
|
780
|
+
.appendTo( clonedFooter );
|
781
|
+
}
|
643
782
|
|
644
|
-
var cells = dt.columns().header().to$().clone( false );
|
645
783
|
$('<tr/>')
|
646
|
-
.append(
|
784
|
+
.append( headerCells )
|
647
785
|
.appendTo( clonedHeader );
|
648
786
|
|
787
|
+
// In the inline case extra padding is applied to the first column to
|
788
|
+
// give space for the show / hide icon. We need to use this in the
|
789
|
+
// calculation
|
790
|
+
if ( this.c.details.type === 'inline' ) {
|
791
|
+
$(clonedTable).addClass( 'dtr-inline collapsed' );
|
792
|
+
}
|
793
|
+
|
649
794
|
var inserted = $('<div/>')
|
650
795
|
.css( {
|
651
796
|
width: 1,
|
652
797
|
height: 1,
|
653
798
|
overflow: 'hidden'
|
654
799
|
} )
|
655
|
-
.append( clonedTable )
|
656
|
-
|
800
|
+
.append( clonedTable );
|
801
|
+
|
802
|
+
inserted.insertBefore( dt.table().node() );
|
657
803
|
|
658
804
|
// The cloned header now contains the smallest that each column can be
|
659
|
-
|
660
|
-
|
805
|
+
headerCells.each( function (i) {
|
806
|
+
var idx = dt.column.index( 'fromVisible', i );
|
807
|
+
columns[ idx ].minWidth = this.offsetWidth || 0;
|
661
808
|
} );
|
662
809
|
|
663
810
|
inserted.remove();
|
811
|
+
},
|
812
|
+
|
813
|
+
/**
|
814
|
+
* Set a column's visibility.
|
815
|
+
*
|
816
|
+
* We don't use DataTables' column visibility controls in order to ensure
|
817
|
+
* that column visibility can Responsive can no-exist. Since only IE8+ is
|
818
|
+
* supported (and all evergreen browsers of course) the control of the
|
819
|
+
* display attribute works well.
|
820
|
+
*
|
821
|
+
* @param {integer} col Column index
|
822
|
+
* @param {boolean} showHide Show or hide (true or false)
|
823
|
+
* @private
|
824
|
+
*/
|
825
|
+
_setColumnVis: function ( col, showHide )
|
826
|
+
{
|
827
|
+
var dt = this.s.dt;
|
828
|
+
var display = showHide ? '' : 'none'; // empty string will remove the attr
|
829
|
+
|
830
|
+
$( dt.column( col ).header() ).css( 'display', display );
|
831
|
+
$( dt.column( col ).footer() ).css( 'display', display );
|
832
|
+
dt.column( col ).nodes().to$().css( 'display', display );
|
833
|
+
},
|
834
|
+
|
835
|
+
|
836
|
+
/**
|
837
|
+
* Update the cell tab indexes for keyboard accessibility. This is called on
|
838
|
+
* every table draw - that is potentially inefficient, but also the least
|
839
|
+
* complex option given that column visibility can change on the fly. Its a
|
840
|
+
* shame user-focus was removed from CSS 3 UI, as it would have solved this
|
841
|
+
* issue with a single CSS statement.
|
842
|
+
*
|
843
|
+
* @private
|
844
|
+
*/
|
845
|
+
_tabIndexes: function ()
|
846
|
+
{
|
847
|
+
var dt = this.s.dt;
|
848
|
+
var cells = dt.cells( { page: 'current' } ).nodes().to$();
|
849
|
+
var ctx = dt.settings()[0];
|
850
|
+
var target = this.c.details.target;
|
851
|
+
|
852
|
+
cells.filter( '[data-dtr-keyboard]' ).removeData( '[data-dtr-keyboard]' );
|
853
|
+
|
854
|
+
var selector = typeof target === 'number' ?
|
855
|
+
':eq('+target+')' :
|
856
|
+
target;
|
857
|
+
|
858
|
+
$( selector, dt.rows( { page: 'current' } ).nodes() )
|
859
|
+
.attr( 'tabIndex', ctx.iTabIndex )
|
860
|
+
.data( 'dtr-keyboard', 1 );
|
664
861
|
}
|
665
|
-
};
|
862
|
+
} );
|
666
863
|
|
667
864
|
|
668
865
|
/**
|
@@ -684,6 +881,110 @@ Responsive.breakpoints = [
|
|
684
881
|
];
|
685
882
|
|
686
883
|
|
884
|
+
/**
|
885
|
+
* Display methods - functions which define how the hidden data should be shown
|
886
|
+
* in the table.
|
887
|
+
*
|
888
|
+
* @namespace
|
889
|
+
* @name Responsive.defaults
|
890
|
+
* @static
|
891
|
+
*/
|
892
|
+
Responsive.display = {
|
893
|
+
childRow: function ( row, update, render ) {
|
894
|
+
if ( update ) {
|
895
|
+
if ( $(row.node()).hasClass('parent') ) {
|
896
|
+
row.child( render(), 'child' ).show();
|
897
|
+
|
898
|
+
return true;
|
899
|
+
}
|
900
|
+
}
|
901
|
+
else {
|
902
|
+
if ( ! row.child.isShown() ) {
|
903
|
+
row.child( render(), 'child' ).show();
|
904
|
+
$( row.node() ).addClass( 'parent' );
|
905
|
+
|
906
|
+
return true;
|
907
|
+
}
|
908
|
+
else {
|
909
|
+
row.child( false );
|
910
|
+
$( row.node() ).removeClass( 'parent' );
|
911
|
+
|
912
|
+
return false;
|
913
|
+
}
|
914
|
+
}
|
915
|
+
},
|
916
|
+
|
917
|
+
childRowImmediate: function ( row, update, render ) {
|
918
|
+
if ( (! update && row.child.isShown()) || ! row.responsive.hasHidden() ) {
|
919
|
+
// User interaction and the row is show, or nothing to show
|
920
|
+
row.child( false );
|
921
|
+
$( row.node() ).removeClass( 'parent' );
|
922
|
+
|
923
|
+
return false;
|
924
|
+
}
|
925
|
+
else {
|
926
|
+
// Display
|
927
|
+
row.child( render(), 'child' ).show();
|
928
|
+
$( row.node() ).addClass( 'parent' );
|
929
|
+
|
930
|
+
return true;
|
931
|
+
}
|
932
|
+
},
|
933
|
+
|
934
|
+
// This is a wrapper so the modal options for Bootstrap and jQuery UI can
|
935
|
+
// have options passed into them. This specific one doesn't need to be a
|
936
|
+
// function but it is for consistency in the `modal` name
|
937
|
+
modal: function ( options ) {
|
938
|
+
return function ( row, update, render ) {
|
939
|
+
if ( ! update ) {
|
940
|
+
// Show a modal
|
941
|
+
var close = function () {
|
942
|
+
modal.remove(); // will tidy events for us
|
943
|
+
$(document).off( 'keypress.dtr' );
|
944
|
+
};
|
945
|
+
|
946
|
+
var modal = $('<div class="dtr-modal"/>')
|
947
|
+
.append( $('<div class="dtr-modal-display"/>')
|
948
|
+
.append( $('<div class="dtr-modal-content"/>')
|
949
|
+
.append( render() )
|
950
|
+
)
|
951
|
+
.append( $('<div class="dtr-modal-close">×</div>' )
|
952
|
+
.click( function () {
|
953
|
+
close();
|
954
|
+
} )
|
955
|
+
)
|
956
|
+
)
|
957
|
+
.append( $('<div class="dtr-modal-background"/>')
|
958
|
+
.click( function () {
|
959
|
+
close();
|
960
|
+
} )
|
961
|
+
)
|
962
|
+
.appendTo( 'body' );
|
963
|
+
|
964
|
+
if ( options && options.header ) {
|
965
|
+
modal.find( 'div.dtr-modal-content' ).prepend(
|
966
|
+
'<h2>'+options.header( row )+'</h2>'
|
967
|
+
);
|
968
|
+
}
|
969
|
+
|
970
|
+
$(document).on( 'keyup.dtr', function (e) {
|
971
|
+
if ( e.keyCode === 27 ) {
|
972
|
+
e.stopPropagation();
|
973
|
+
|
974
|
+
close();
|
975
|
+
}
|
976
|
+
} );
|
977
|
+
}
|
978
|
+
else {
|
979
|
+
$('div.dtr-modal-content')
|
980
|
+
.empty()
|
981
|
+
.append( render() );
|
982
|
+
}
|
983
|
+
};
|
984
|
+
}
|
985
|
+
};
|
986
|
+
|
987
|
+
|
687
988
|
/**
|
688
989
|
* Responsive default settings for initialisation
|
689
990
|
*
|
@@ -719,6 +1020,7 @@ Responsive.defaults = {
|
|
719
1020
|
*
|
720
1021
|
* The object consists of the following properties:
|
721
1022
|
*
|
1023
|
+
* * `display` - A function that is used to show and hide the hidden details
|
722
1024
|
* * `renderer` - function that is called for display of the child row data.
|
723
1025
|
* The default function will show the data from the hidden columns
|
724
1026
|
* * `target` - Used as the selector for what objects to attach the child
|
@@ -729,36 +1031,21 @@ Responsive.defaults = {
|
|
729
1031
|
* @type {Object|string}
|
730
1032
|
*/
|
731
1033
|
details: {
|
732
|
-
|
733
|
-
var data = api.cells( rowIdx, ':hidden' ).eq(0).map( function ( cell ) {
|
734
|
-
var header = $( api.column( cell.column ).header() );
|
735
|
-
var idx = api.cell( cell ).index();
|
1034
|
+
display: Responsive.display.childRow,
|
736
1035
|
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
// Use a non-public DT API method to render the data for display
|
742
|
-
// This needs to be updated when DT adds a suitable method for
|
743
|
-
// this type of data retrieval
|
744
|
-
var dtPrivate = api.settings()[0];
|
745
|
-
var cellData = dtPrivate.oApi._fnGetCellData(
|
746
|
-
dtPrivate, idx.row, idx.column, 'display'
|
747
|
-
);
|
748
|
-
var title = header.text();
|
749
|
-
if ( title ) {
|
750
|
-
title = title + ':';
|
751
|
-
}
|
752
|
-
|
753
|
-
return '<li data-dtr-index="'+idx.column+'">'+
|
1036
|
+
renderer: function ( api, rowIdx, columns ) {
|
1037
|
+
var data = $.map( columns, function ( col, i ) {
|
1038
|
+
return col.hidden ?
|
1039
|
+
'<li data-dtr-index="'+i+'">'+
|
754
1040
|
'<span class="dtr-title">'+
|
755
|
-
title+
|
1041
|
+
col.title+
|
756
1042
|
'</span> '+
|
757
1043
|
'<span class="dtr-data">'+
|
758
|
-
|
1044
|
+
col.data+
|
759
1045
|
'</span>'+
|
760
|
-
'</li>'
|
761
|
-
|
1046
|
+
'</li>' :
|
1047
|
+
'';
|
1048
|
+
} ).join('');
|
762
1049
|
|
763
1050
|
return data ?
|
764
1051
|
$('<ul data-dtr-index="'+rowIdx+'"/>').append( data ) :
|
@@ -768,7 +1055,15 @@ Responsive.defaults = {
|
|
768
1055
|
target: 0,
|
769
1056
|
|
770
1057
|
type: 'inline'
|
771
|
-
}
|
1058
|
+
},
|
1059
|
+
|
1060
|
+
/**
|
1061
|
+
* Orthogonal data request option. This is used to define the data type
|
1062
|
+
* requested when Responsive gets the data to show in the child row.
|
1063
|
+
*
|
1064
|
+
* @type {String}
|
1065
|
+
*/
|
1066
|
+
orthogonal: 'display'
|
772
1067
|
};
|
773
1068
|
|
774
1069
|
|
@@ -808,6 +1103,14 @@ Api.register( 'responsive.recalc()', function () {
|
|
808
1103
|
} );
|
809
1104
|
} );
|
810
1105
|
|
1106
|
+
Api.register( 'responsive.hasHidden()', function () {
|
1107
|
+
var ctx = this.context[0];
|
1108
|
+
|
1109
|
+
return ctx._responsive ?
|
1110
|
+
$.inArray( false, ctx._responsive.s.current ) !== -1 :
|
1111
|
+
false;
|
1112
|
+
} );
|
1113
|
+
|
811
1114
|
|
812
1115
|
/**
|
813
1116
|
* Version information
|
@@ -815,7 +1118,7 @@ Api.register( 'responsive.recalc()', function () {
|
|
815
1118
|
* @name Responsive.version
|
816
1119
|
* @static
|
817
1120
|
*/
|
818
|
-
Responsive.version = '
|
1121
|
+
Responsive.version = '2.0.0';
|
819
1122
|
|
820
1123
|
|
821
1124
|
$.fn.dataTable.Responsive = Responsive;
|
@@ -833,8 +1136,6 @@ $(document).on( 'init.dt.dtr', function (e, settings, json) {
|
|
833
1136
|
settings.oInit.responsive ||
|
834
1137
|
DataTable.defaults.responsive
|
835
1138
|
) {
|
836
|
-
console.log( e.namespace );
|
837
|
-
|
838
1139
|
var init = settings.oInit.responsive;
|
839
1140
|
|
840
1141
|
if ( init !== false ) {
|
@@ -843,22 +1144,6 @@ $(document).on( 'init.dt.dtr', function (e, settings, json) {
|
|
843
1144
|
}
|
844
1145
|
} );
|
845
1146
|
|
846
|
-
return Responsive;
|
847
|
-
}; // /factory
|
848
|
-
|
849
1147
|
|
850
|
-
|
851
|
-
|
852
|
-
define( ['jquery', 'datatables'], factory );
|
853
|
-
}
|
854
|
-
else if ( typeof exports === 'object' ) {
|
855
|
-
// Node/CommonJS
|
856
|
-
factory( require('jquery'), require('datatables') );
|
857
|
-
}
|
858
|
-
else if ( jQuery && !jQuery.fn.dataTable.Responsive ) {
|
859
|
-
// Otherwise simply initialise as normal, stopping multiple evaluation
|
860
|
-
factory( jQuery, jQuery.fn.dataTable );
|
861
|
-
}
|
862
|
-
|
863
|
-
|
864
|
-
})(window, document);
|
1148
|
+
return Responsive;
|
1149
|
+
}));
|