jquery-datatables-rails 2.2.1 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/dataTables/extras/dataTables.autoFill.js +8 -4
- data/app/assets/javascripts/dataTables/extras/dataTables.colReorder.js +75 -21
- data/app/assets/javascripts/dataTables/extras/dataTables.colVis.js +22 -11
- data/app/assets/javascripts/dataTables/extras/dataTables.fixedColumns.js +32 -13
- data/app/assets/javascripts/dataTables/extras/dataTables.fixedHeader.js +8 -4
- data/app/assets/javascripts/dataTables/extras/dataTables.keyTable.js +8 -4
- data/app/assets/javascripts/dataTables/extras/dataTables.responsive.js +699 -613
- data/app/assets/javascripts/dataTables/extras/dataTables.scroller.js +119 -42
- data/app/assets/javascripts/dataTables/extras/dataTables.tableTools.js +114 -33
- data/app/assets/stylesheets/dataTables/extras/dataTables.autoFill.css.scss +6 -6
- data/app/assets/stylesheets/dataTables/extras/dataTables.colVis.css.scss +1 -0
- data/app/assets/stylesheets/dataTables/extras/dataTables.responsive.css.scss +88 -22
- data/app/assets/stylesheets/dataTables/jquery.dataTables.css.scss +91 -14
- data/lib/jquery/datatables/rails/version.rb +1 -1
- metadata +2 -2
@@ -1,11 +1,11 @@
|
|
1
|
-
/*! KeyTable 1.2.
|
1
|
+
/*! KeyTable 1.2.1
|
2
2
|
* ©2010-2014 SpryMedia Ltd - datatables.net/license
|
3
3
|
*/
|
4
4
|
|
5
5
|
/**
|
6
6
|
* @summary KeyTable
|
7
7
|
* @description Spreadsheet like keyboard navigation for DataTables
|
8
|
-
* @version 1.2.
|
8
|
+
* @version 1.2.1
|
9
9
|
* @file dataTables.keyTable.js
|
10
10
|
* @author SpryMedia Ltd (www.sprymedia.co.uk)
|
11
11
|
* @contact www.sprymedia.co.uk/contact
|
@@ -1147,7 +1147,7 @@ KeyTable = function ( oInit )
|
|
1147
1147
|
};
|
1148
1148
|
|
1149
1149
|
|
1150
|
-
KeyTable.version = "1.2.
|
1150
|
+
KeyTable.version = "1.2.1";
|
1151
1151
|
|
1152
1152
|
|
1153
1153
|
$.fn.dataTable.KeyTable = KeyTable;
|
@@ -1160,7 +1160,11 @@ return KeyTable;
|
|
1160
1160
|
|
1161
1161
|
// Define as an AMD module if possible
|
1162
1162
|
if ( typeof define === 'function' && define.amd ) {
|
1163
|
-
define(
|
1163
|
+
define( ['jquery', 'datatables'], factory );
|
1164
|
+
}
|
1165
|
+
else if ( typeof exports === 'object' ) {
|
1166
|
+
// Node/CommonJS
|
1167
|
+
factory( require('jquery'), require('datatables') );
|
1164
1168
|
}
|
1165
1169
|
else if ( jQuery && !jQuery.fn.dataTable.KeyTable ) {
|
1166
1170
|
// Otherwise simply initialise as normal, stopping multiple evaluation
|
@@ -1,665 +1,751 @@
|
|
1
|
+
/*! Responsive 1.0.1
|
2
|
+
* 2014 SpryMedia Ltd - datatables.net/license
|
3
|
+
*/
|
4
|
+
|
1
5
|
/**
|
2
|
-
*
|
3
|
-
*
|
4
|
-
*
|
5
|
-
*
|
6
|
+
* @summary Responsive
|
7
|
+
* @description Responsive tables plug-in for DataTables
|
8
|
+
* @version 1.0.1
|
9
|
+
* @file dataTables.responsive.js
|
10
|
+
* @author SpryMedia Ltd (www.sprymedia.co.uk)
|
11
|
+
* @contact www.sprymedia.co.uk/contact
|
12
|
+
* @copyright Copyright 2014 SpryMedia Ltd.
|
6
13
|
*
|
7
|
-
*
|
8
|
-
*
|
9
|
-
* This source file is free software, under either the GPL v2 license or a
|
10
|
-
* BSD style license.
|
14
|
+
* This source file is free software, available under the following license:
|
15
|
+
* MIT license - http://datatables.net/license/mit
|
11
16
|
*
|
12
17
|
* This source file is distributed in the hope that it will be useful, but
|
13
18
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
14
19
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
|
15
20
|
*
|
16
|
-
*
|
17
|
-
* BSD license along with this program. These licenses are also available at:
|
18
|
-
* https://raw.github.com/Comanche/datatables-responsive/master/license-gpl2.txt
|
19
|
-
* https://raw.github.com/Comanche/datatables-responsive/master/license-bsd.txt
|
21
|
+
* For details please refer to: http://www.datatables.net
|
20
22
|
*/
|
21
23
|
|
22
|
-
|
24
|
+
(function(window, document, undefined) {
|
25
|
+
|
26
|
+
|
27
|
+
var factory = function( $, DataTable ) {
|
28
|
+
"use strict";
|
23
29
|
|
24
30
|
/**
|
25
|
-
*
|
26
|
-
*
|
27
|
-
*
|
31
|
+
* Responsive is a plug-in for the DataTables library that makes use of
|
32
|
+
* DataTables' ability to change the visibility of columns, changing the
|
33
|
+
* visibility of columns so the displayed columns fit into the table container.
|
34
|
+
* The end result is that complex tables will be dynamically adjusted to fit
|
35
|
+
* into the viewport, be it on a desktop, tablet or mobile browser.
|
28
36
|
*
|
29
|
-
*
|
30
|
-
*
|
37
|
+
* Responsive for DataTables has two modes of operation, which can used
|
38
|
+
* individually or combined:
|
31
39
|
*
|
32
|
-
*
|
40
|
+
* * Class name based control - columns assigned class names that match the
|
41
|
+
* breakpoint logic can be shown / hidden as required for each breakpoint.
|
42
|
+
* * Automatic control - columns are automatically hidden when there is no
|
43
|
+
* room left to display them. Columns removed from the right.
|
33
44
|
*
|
34
|
-
*
|
35
|
-
*
|
36
|
-
*
|
37
|
-
*
|
45
|
+
* In additional to column visibility control, Responsive also has built into
|
46
|
+
* options to use DataTables' child row display to show / hide the information
|
47
|
+
* from the table that has been hidden. There are also two modes of operation
|
48
|
+
* for this child row display:
|
38
49
|
*
|
39
|
-
*
|
40
|
-
*
|
41
|
-
*
|
50
|
+
* * Inline - when the control element that the user can use to show / hide
|
51
|
+
* child rows is displayed inside the first column of the table.
|
52
|
+
* * Column - where a whole column is dedicated to be the show / hide control.
|
42
53
|
*
|
43
|
-
*
|
44
|
-
* helper. The following options are supported:
|
54
|
+
* Initialisation of Responsive is performed by:
|
45
55
|
*
|
46
|
-
*
|
47
|
-
*
|
48
|
-
*
|
49
|
-
*
|
50
|
-
*
|
51
|
-
*
|
52
|
-
*
|
53
|
-
* @param {Object|string} tableSelector jQuery wrapped set or selector for
|
54
|
-
* datatables container element.
|
55
|
-
* @param {Object} breakpoints Object defining the responsive
|
56
|
-
* breakpoint for datatables.
|
57
|
-
* @param {Object} options Object of options.
|
58
|
-
*/
|
59
|
-
function ResponsiveDatatablesHelper(tableSelector, breakpoints, options) {
|
60
|
-
if (typeof tableSelector === 'string') {
|
61
|
-
this.tableElement = $(tableSelector);
|
62
|
-
} else {
|
63
|
-
this.tableElement = tableSelector;
|
64
|
-
}
|
65
|
-
|
66
|
-
// Get data table API.
|
67
|
-
this.api = this.tableElement.dataTable().api();
|
68
|
-
|
69
|
-
// State of column indexes and which are shown or hidden.
|
70
|
-
this.columnIndexes = [];
|
71
|
-
this.columnsShownIndexes = [];
|
72
|
-
this.columnsHiddenIndexes = [];
|
73
|
-
this.currentBreakpoint = '';
|
74
|
-
this.lastBreakpoint = '';
|
75
|
-
this.lastColumnsHiddenIndexes = [];
|
76
|
-
|
77
|
-
// Save state
|
78
|
-
var fileName = window.location.pathname.split("/").pop();
|
79
|
-
var context = this.api.settings().context[0];
|
80
|
-
|
81
|
-
this.tableId = context.sTableId;
|
82
|
-
this.saveState = context.oInit.bStateSave;
|
83
|
-
this.cookieName = 'DataTablesResponsiveHelper_' + this.tableId + (fileName ? '_' + fileName : '');
|
84
|
-
this.lastStateExists = false;
|
85
|
-
|
86
|
-
// Index of the th in the header tr that stores where the attribute
|
87
|
-
// data-class="expand"
|
88
|
-
// is defined.
|
89
|
-
this.expandColumn = undefined;
|
90
|
-
// Stores original breakpoint defitions
|
91
|
-
this.origBreakpointsDefs = undefined;
|
92
|
-
// Stores the break points defined in the table header.
|
93
|
-
// Each th in the header tr may contain an optional attribute like
|
94
|
-
// data-hide="phone,tablet"
|
95
|
-
// These attributes and the breakpoints object will be used to create this
|
96
|
-
// object.
|
97
|
-
this.breakpoints = {
|
98
|
-
/**
|
99
|
-
* We will be generating data in the following format:
|
100
|
-
* phone : {
|
101
|
-
* lowerLimit : undefined,
|
102
|
-
* upperLimit : 320,
|
103
|
-
* columnsToHide: []
|
104
|
-
* },
|
105
|
-
* tablet: {
|
106
|
-
* lowerLimit : 320,
|
107
|
-
* upperLimit : 724,
|
108
|
-
* columnsToHide: []
|
109
|
-
* }
|
110
|
-
*/
|
111
|
-
};
|
112
|
-
|
113
|
-
// Store default options
|
114
|
-
this.options = {
|
115
|
-
hideEmptyColumnsInRowDetail: false,
|
116
|
-
clickOn: 'icon',
|
117
|
-
showDetail: null,
|
118
|
-
hideDetail: null
|
119
|
-
};
|
120
|
-
|
121
|
-
// Expand icon template
|
122
|
-
this.expandIconTemplate = '<span class="responsiveExpander"></span>';
|
123
|
-
|
124
|
-
// Row template
|
125
|
-
this.rowTemplate = '<tr class="row-detail"><td><ul><!--column item--></ul></td></tr>';
|
126
|
-
this.rowLiTemplate = '<li><span class="columnTitle"><!--column title--></span>: <span class="columnValue"><!--column value--></span></li>';
|
127
|
-
|
128
|
-
// Responsive behavior on/off flag
|
129
|
-
this.disabled = true;
|
130
|
-
|
131
|
-
// Skip next windows width change flag
|
132
|
-
this.skipNextWindowsWidthChange = false;
|
133
|
-
|
134
|
-
// Initialize settings
|
135
|
-
this.init(breakpoints, options);
|
136
|
-
}
|
137
|
-
|
138
|
-
/**
|
139
|
-
* Responsive datatables helper init function.
|
140
|
-
* Builds breakpoint limits for columns and begins to listen to window resize
|
141
|
-
* event.
|
56
|
+
* * Adding the class `responsive` or `dt-responsive` to the table. In this case
|
57
|
+
* Responsive will automatically be initialised with the default configuration
|
58
|
+
* options when the DataTable is created.
|
59
|
+
* * Using the `responsive` option in the DataTables configuration options. This
|
60
|
+
* can also be used to specify the configuration options, or simply set to
|
61
|
+
* `true` to use the defaults.
|
142
62
|
*
|
143
|
-
*
|
63
|
+
* @class
|
64
|
+
* @param {object} settings DataTables settings object for the host table
|
65
|
+
* @param {object} [opts] Configuration options
|
66
|
+
* @requires jQuery 1.7+
|
67
|
+
* @requires DataTables 1.10.1+
|
144
68
|
*
|
145
|
-
*
|
146
|
-
*
|
69
|
+
* @example
|
70
|
+
* $('#example').DataTable( {
|
71
|
+
* responsive: true
|
72
|
+
* } );
|
73
|
+
* } );
|
147
74
|
*/
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
75
|
+
var Responsive = function ( settings, opts ) {
|
76
|
+
// Sanity check that we are using DataTables 1.10 or newer
|
77
|
+
if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.1' ) ) {
|
78
|
+
throw 'DataTables Responsive requires DataTables 1.10.1 or newer';
|
79
|
+
}
|
80
|
+
else if ( settings.responsive ) {
|
81
|
+
return;
|
82
|
+
}
|
83
|
+
|
84
|
+
this.s = {
|
85
|
+
dt: new DataTable.Api( settings ),
|
86
|
+
columns: []
|
87
|
+
};
|
88
|
+
|
89
|
+
// details is an object, but for simplicity the user can give it as a string
|
90
|
+
if ( opts && typeof opts.details === 'string' ) {
|
91
|
+
opts.details = { type: opts.details };
|
92
|
+
}
|
93
|
+
|
94
|
+
this.c = $.extend( true, {}, Responsive.defaults, opts );
|
95
|
+
settings.responsive = this;
|
96
|
+
this._constructor();
|
157
97
|
};
|
158
98
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
99
|
+
Responsive.prototype = {
|
100
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
101
|
+
* Constructor
|
102
|
+
*/
|
103
|
+
|
104
|
+
/**
|
105
|
+
* Initialise the Responsive instance
|
106
|
+
*
|
107
|
+
* @private
|
108
|
+
*/
|
109
|
+
_constructor: function ()
|
110
|
+
{
|
111
|
+
var that = this;
|
112
|
+
var dt = this.s.dt;
|
113
|
+
|
114
|
+
dt.settings()[0]._responsive = this;
|
115
|
+
|
116
|
+
// Use DataTables' private throttle function to avoid processor thrashing
|
117
|
+
$(window).on( 'resize.dtr orientationchange.dtr', dt.settings()[0].oApi._fnThrottle( function () {
|
118
|
+
that._resize();
|
119
|
+
} ) );
|
120
|
+
|
121
|
+
// Destroy event handler
|
122
|
+
dt.on( 'destroy.dtr', function () {
|
123
|
+
$(window).off( 'resize.dtr orientationchange.dtr' );
|
124
|
+
} );
|
125
|
+
|
126
|
+
// Reorder the breakpoints array here in case they have been added out
|
127
|
+
// of order
|
128
|
+
this.c.breakpoints.sort( function (a, b) {
|
129
|
+
return a.width < b.width ? 1 :
|
130
|
+
a.width > b.width ? -1 : 0;
|
131
|
+
} );
|
132
|
+
|
133
|
+
this._classLogic();
|
134
|
+
this._resizeAuto();
|
135
|
+
|
136
|
+
// First pass - draw the table for the current viewport size
|
137
|
+
this._resize();
|
138
|
+
|
139
|
+
// Details handler
|
140
|
+
var details = this.c.details;
|
141
|
+
if ( details.type ) {
|
142
|
+
that._detailsInit();
|
143
|
+
this._detailsVis();
|
144
|
+
|
145
|
+
dt.on( 'column-visibility.dtr', function () {
|
146
|
+
that._detailsVis();
|
147
|
+
} );
|
148
|
+
|
149
|
+
$(dt.table().node()).addClass( 'dtr-'+details.type );
|
150
|
+
}
|
151
|
+
},
|
152
|
+
|
153
|
+
|
154
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
155
|
+
* Private methods
|
156
|
+
*/
|
157
|
+
|
158
|
+
/**
|
159
|
+
* Calculate the visibility for the columns in a table for a given
|
160
|
+
* breakpoint. The result is pre-determined based on the class logic if
|
161
|
+
* class names are used to control all columns, but the width of the table
|
162
|
+
* is also used if there are columns which are to be automatically shown
|
163
|
+
* and hidden.
|
164
|
+
*
|
165
|
+
* @param {string} breakpoint Breakpoint name to use for the calculation
|
166
|
+
* @return {array} Array of boolean values initiating the visibility of each
|
167
|
+
* column.
|
168
|
+
* @private
|
169
|
+
*/
|
170
|
+
_columnsVisiblity: function ( breakpoint )
|
171
|
+
{
|
172
|
+
var dt = this.s.dt;
|
173
|
+
var columns = this.s.columns;
|
174
|
+
var i, ien;
|
175
|
+
|
176
|
+
// Class logic - determine which columns are in this breakpoint based
|
177
|
+
// on the classes. If no class control (i.e. `auto`) then `-` is used
|
178
|
+
// to indicate this to the rest of the function
|
179
|
+
var display = $.map( columns, function ( col ) {
|
180
|
+
return col.auto && col.minWidth === null ?
|
181
|
+
false :
|
182
|
+
col.auto === true ?
|
183
|
+
'-' :
|
184
|
+
col.includeIn.indexOf( breakpoint ) !== -1;
|
185
|
+
} );
|
186
|
+
|
187
|
+
// Auto column control - first pass: how much width is taken by the
|
188
|
+
// ones that must be included from the non-auto columns
|
189
|
+
var requiredWidth = 0;
|
190
|
+
for ( i=0, ien=display.length ; i<ien ; i++ ) {
|
191
|
+
if ( display[i] === true ) {
|
192
|
+
requiredWidth += columns[i].minWidth;
|
193
|
+
}
|
194
|
+
}
|
195
|
+
|
196
|
+
// Second pass, use up any remaining width for other columns
|
197
|
+
var widthAvailable = dt.table().container().offsetWidth;
|
198
|
+
var usedWidth = widthAvailable - requiredWidth;
|
199
|
+
|
200
|
+
for ( i=0, ien=display.length ; i<ien ; i++ ) {
|
201
|
+
// Control column needs to always be included. This makes it sub-
|
202
|
+
// optimal in terms of using the available with, but to stop layout
|
203
|
+
// thrashing or overflow
|
204
|
+
if ( columns[i].control ) {
|
205
|
+
usedWidth -= columns[i].minWidth;
|
206
|
+
}
|
207
|
+
else if ( display[i] === '-' ) {
|
208
|
+
// Otherwise, remove the width
|
209
|
+
display[i] = usedWidth - columns[i].minWidth < 0 ?
|
210
|
+
false :
|
211
|
+
true;
|
212
|
+
|
213
|
+
// Continue counting down the width, so a smaller column to the
|
214
|
+
// left won't be shown
|
215
|
+
usedWidth -= columns[i].minWidth;
|
216
|
+
}
|
217
|
+
}
|
218
|
+
|
219
|
+
// Determine if the 'control' column should be shown (if there is one).
|
220
|
+
// This is the case when there is a hidden column (that is not the
|
221
|
+
// control column). The two loops look inefficient here, but they are
|
222
|
+
// trivial and will fly through. We need to know the outcome from the
|
223
|
+
// first , before the action in the second can be taken
|
224
|
+
var showControl = false;
|
225
|
+
|
226
|
+
for ( i=0, ien=columns.length ; i<ien ; i++ ) {
|
227
|
+
if ( ! columns[i].control && ! display[i] ) {
|
228
|
+
showControl = true;
|
229
|
+
break;
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
for ( i=0, ien=columns.length ; i<ien ; i++ ) {
|
234
|
+
if ( columns[i].control ) {
|
235
|
+
display[i] = showControl;
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
return display;
|
240
|
+
},
|
241
|
+
|
242
|
+
|
243
|
+
/**
|
244
|
+
* Create the internal `columns` array with information about the columns
|
245
|
+
* for the table. This includes determining which breakpoints the column
|
246
|
+
* will appear in, based upon class names in the column, which makes up the
|
247
|
+
* vast majority of this method.
|
248
|
+
*
|
249
|
+
* @private
|
250
|
+
*/
|
251
|
+
_classLogic: function ()
|
252
|
+
{
|
253
|
+
var that = this;
|
254
|
+
var calc = {};
|
255
|
+
var breakpoints = this.c.breakpoints;
|
256
|
+
var columns = this.s.dt.columns().eq(0).map( function (i) {
|
257
|
+
return {
|
258
|
+
className: this.column(i).header().className,
|
259
|
+
includeIn: [],
|
260
|
+
auto: false,
|
261
|
+
control: false
|
262
|
+
};
|
263
|
+
} );
|
264
|
+
|
265
|
+
// Simply add a breakpoint to `includeIn` array, ensuring that there are
|
266
|
+
// no duplicates
|
267
|
+
var add = function ( colIdx, name ) {
|
268
|
+
var includeIn = columns[ colIdx ].includeIn;
|
269
|
+
|
270
|
+
if ( includeIn.indexOf( name ) === -1 ) {
|
271
|
+
includeIn.push( name );
|
272
|
+
}
|
273
|
+
};
|
274
|
+
|
275
|
+
var column = function ( colIdx, name, operator, matched ) {
|
276
|
+
var size, i, ien;
|
277
|
+
|
278
|
+
if ( ! operator ) {
|
279
|
+
columns[ colIdx ].includeIn.push( name );
|
280
|
+
}
|
281
|
+
else if ( operator === 'max-' ) {
|
282
|
+
// Add this breakpoint and all smaller
|
283
|
+
size = that._find( name ).width;
|
284
|
+
|
285
|
+
for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
|
286
|
+
if ( breakpoints[i].width <= size ) {
|
287
|
+
add( colIdx, breakpoints[i].name );
|
288
|
+
}
|
289
|
+
}
|
290
|
+
}
|
291
|
+
else if ( operator === 'min-' ) {
|
292
|
+
// Add this breakpoint and all larger
|
293
|
+
size = that._find( name ).width;
|
294
|
+
|
295
|
+
for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
|
296
|
+
if ( breakpoints[i].width >= size ) {
|
297
|
+
add( colIdx, breakpoints[i].name );
|
298
|
+
}
|
299
|
+
}
|
300
|
+
}
|
301
|
+
else if ( operator === 'not-' ) {
|
302
|
+
// Add all but this breakpoint (xxx need extra information)
|
303
|
+
|
304
|
+
for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
|
305
|
+
if ( breakpoints[i].name.indexOf( matched ) === -1 ) {
|
306
|
+
add( colIdx, breakpoints[i].name );
|
307
|
+
}
|
308
|
+
}
|
309
|
+
}
|
310
|
+
};
|
311
|
+
|
312
|
+
// Loop over each column and determine if it has a responsive control
|
313
|
+
// class
|
314
|
+
columns.each( function ( col, i ) {
|
315
|
+
var classNames = col.className.split(' ');
|
316
|
+
var hasClass = false;
|
317
|
+
|
318
|
+
// Split the class name up so multiple rules can be applied if needed
|
319
|
+
for ( var k=0, ken=classNames.length ; k<ken ; k++ ) {
|
320
|
+
var className = $.trim( classNames[k] );
|
321
|
+
|
322
|
+
if ( className === 'all' ) {
|
323
|
+
// Include in all
|
324
|
+
hasClass = true;
|
325
|
+
col.includeIn = $.map( breakpoints, function (a) {
|
326
|
+
return a.name;
|
327
|
+
} );
|
328
|
+
return;
|
329
|
+
}
|
330
|
+
else if ( className === 'none' ) {
|
331
|
+
// Include in none (default) and no auto
|
332
|
+
hasClass = true;
|
333
|
+
return;
|
334
|
+
}
|
335
|
+
else if ( className === 'control' ) {
|
336
|
+
// Special column that is only visible, when one of the other
|
337
|
+
// columns is hidden. This is used for the details control
|
338
|
+
hasClass = true;
|
339
|
+
col.control = true;
|
340
|
+
return;
|
341
|
+
}
|
342
|
+
|
343
|
+
$.each( breakpoints, function ( j, breakpoint ) {
|
344
|
+
// Does this column have a class that matches this breakpoint?
|
345
|
+
var brokenPoint = breakpoint.name.split('-');
|
346
|
+
var re = new RegExp( '(min\\-|max\\-|not\\-)?('+brokenPoint[0]+')(\\-[_a-zA-Z0-9])?' );
|
347
|
+
var match = className.match( re );
|
348
|
+
|
349
|
+
if ( match ) {
|
350
|
+
hasClass = true;
|
351
|
+
|
352
|
+
if ( match[2] === brokenPoint[0] && match[3] === '-'+brokenPoint[1] ) {
|
353
|
+
// Class name matches breakpoint name fully
|
354
|
+
column( i, breakpoint.name, match[1], match[2]+match[3] );
|
355
|
+
}
|
356
|
+
else if ( match[2] === brokenPoint[0] && ! match[3] ) {
|
357
|
+
// Class name matched primary breakpoint name with no qualifier
|
358
|
+
column( i, breakpoint.name, match[1], match[2] );
|
359
|
+
}
|
360
|
+
}
|
361
|
+
} );
|
362
|
+
}
|
363
|
+
|
364
|
+
// If there was no control class, then automatic sizing is used
|
365
|
+
if ( ! hasClass ) {
|
366
|
+
col.auto = true;
|
367
|
+
}
|
368
|
+
} );
|
369
|
+
|
370
|
+
this.s.columns = columns;
|
371
|
+
},
|
372
|
+
|
373
|
+
|
374
|
+
/**
|
375
|
+
* Initialisation for the details handler
|
376
|
+
*
|
377
|
+
* @private
|
378
|
+
*/
|
379
|
+
_detailsInit: function ()
|
380
|
+
{
|
381
|
+
var that = this;
|
382
|
+
var dt = this.s.dt;
|
383
|
+
var details = this.c.details;
|
384
|
+
|
385
|
+
// The inline type always uses the first child as the target
|
386
|
+
if ( details.type === 'inline' ) {
|
387
|
+
details.target = 'td:first-child';
|
388
|
+
}
|
389
|
+
|
390
|
+
// type.target can be a string jQuery selector or a column index
|
391
|
+
var target = details.target;
|
392
|
+
var selector = typeof target === 'string' ? target : 'td';
|
393
|
+
|
394
|
+
// Click handler to show / hide the details rows when they are available
|
395
|
+
$( dt.table().body() ).on( 'click', selector, function (e) {
|
396
|
+
// If the table is not collapsed (i.e. there is no hidden columns)
|
397
|
+
// then take no action
|
398
|
+
if ( ! $(dt.table().node()).hasClass('collapsed' ) ) {
|
399
|
+
return;
|
400
|
+
}
|
401
|
+
|
402
|
+
// For column index, we determine if we should act or not in the
|
403
|
+
// handler - otherwise it is already okay
|
404
|
+
if ( typeof target === 'number' ) {
|
405
|
+
var targetIdx = target < 0 ?
|
406
|
+
dt.columns().eq(0).length + target :
|
407
|
+
target;
|
408
|
+
|
409
|
+
if ( dt.cell( this ).index().column !== targetIdx ) {
|
410
|
+
return;
|
411
|
+
}
|
412
|
+
}
|
413
|
+
|
414
|
+
// $().closest() includes itself in its check
|
415
|
+
var row = dt.row( $(this).closest('tr') );
|
416
|
+
|
417
|
+
if ( row.child.isShown() ) {
|
418
|
+
row.child( false );
|
419
|
+
$( row.node() ).removeClass( 'parent' );
|
420
|
+
}
|
421
|
+
else {
|
422
|
+
var info = that.c.details.renderer( dt, row[0] );
|
423
|
+
row.child( info, 'child' ).show();
|
424
|
+
$( row.node() ).addClass( 'parent' );
|
425
|
+
}
|
426
|
+
} );
|
427
|
+
},
|
428
|
+
|
429
|
+
|
430
|
+
/**
|
431
|
+
* Update the child rows in the table whenever the column visibility changes
|
432
|
+
*
|
433
|
+
* @private
|
434
|
+
*/
|
435
|
+
_detailsVis: function ()
|
436
|
+
{
|
437
|
+
var that = this;
|
438
|
+
var dt = this.s.dt;
|
439
|
+
|
440
|
+
var hiddenColumns = dt.columns(':hidden').indexes().flatten();
|
441
|
+
var haveHidden = true;
|
442
|
+
|
443
|
+
if ( hiddenColumns.length === 0 || ( hiddenColumns.length === 1 && this.s.columns[ hiddenColumns[0] ].control ) ) {
|
444
|
+
haveHidden = false;
|
445
|
+
}
|
446
|
+
|
447
|
+
if ( haveHidden ) {
|
448
|
+
// Got hidden columns
|
449
|
+
$( dt.table().node() ).addClass('collapsed');
|
450
|
+
|
451
|
+
// Show all existing child rows
|
452
|
+
dt.rows().eq(0).each( function (idx) {
|
453
|
+
var row = dt.row( idx );
|
454
|
+
|
455
|
+
if ( row.child() ) {
|
456
|
+
var info = that.c.details.renderer( dt, row[0] );
|
457
|
+
|
458
|
+
// The renderer can return false to have no child row
|
459
|
+
if ( info === false ) {
|
460
|
+
row.child.hide();
|
461
|
+
}
|
462
|
+
else {
|
463
|
+
row.child( info, 'child' ).show();
|
464
|
+
}
|
465
|
+
}
|
466
|
+
} );
|
467
|
+
}
|
468
|
+
else {
|
469
|
+
// No hidden columns
|
470
|
+
$( dt.table().node() ).removeClass('collapsed');
|
471
|
+
|
472
|
+
// Hide all existing child rows
|
473
|
+
dt.rows().eq(0).each( function (idx) {
|
474
|
+
dt.row( idx ).child.hide();
|
475
|
+
} );
|
476
|
+
}
|
477
|
+
},
|
478
|
+
|
479
|
+
|
480
|
+
/**
|
481
|
+
* Find a breakpoint object from a name
|
482
|
+
* @param {string} name Breakpoint name to find
|
483
|
+
* @return {object} Breakpoint description object
|
484
|
+
*/
|
485
|
+
_find: function ( name )
|
486
|
+
{
|
487
|
+
var breakpoints = this.c.breakpoints;
|
488
|
+
|
489
|
+
for ( var i=0, ien=breakpoints.length ; i<ien ; i++ ) {
|
490
|
+
if ( breakpoints[i].name === name ) {
|
491
|
+
return breakpoints[i];
|
492
|
+
}
|
493
|
+
}
|
494
|
+
},
|
495
|
+
|
496
|
+
|
497
|
+
/**
|
498
|
+
* Alter the table display for a resized viewport. This involves first
|
499
|
+
* determining what breakpoint the window currently is in, getting the
|
500
|
+
* column visibilities to apply and then setting them.
|
501
|
+
*
|
502
|
+
* @private
|
503
|
+
*/
|
504
|
+
_resize: function ()
|
505
|
+
{
|
506
|
+
var dt = this.s.dt;
|
507
|
+
var width = $(window).width();
|
508
|
+
var breakpoints = this.c.breakpoints;
|
509
|
+
var breakpoint = breakpoints[0].name;
|
510
|
+
|
511
|
+
// Determine what breakpoint we are currently at
|
512
|
+
for ( var i=breakpoints.length-1 ; i>=0 ; i-- ) {
|
513
|
+
if ( width <= breakpoints[i].width ) {
|
514
|
+
breakpoint = breakpoints[i].name;
|
515
|
+
break;
|
516
|
+
}
|
517
|
+
}
|
518
|
+
|
519
|
+
// Show the columns for that break point
|
520
|
+
var columns = this._columnsVisiblity( breakpoint );
|
521
|
+
|
522
|
+
dt.columns().eq(0).each( function ( colIdx, i ) {
|
523
|
+
dt.column( colIdx ).visible( columns[i] );
|
524
|
+
} );
|
525
|
+
},
|
526
|
+
|
527
|
+
|
528
|
+
/**
|
529
|
+
* Determine the width of each column in the table so the auto column hiding
|
530
|
+
* has that information to work with. This method is never going to be 100%
|
531
|
+
* perfect since column widths can change slightly per page, but without
|
532
|
+
* seriously compromising performance this is quite effective.
|
533
|
+
*
|
534
|
+
* @private
|
535
|
+
*/
|
536
|
+
_resizeAuto: function ()
|
537
|
+
{
|
538
|
+
var dt = this.s.dt;
|
539
|
+
var columns = this.s.columns;
|
540
|
+
|
541
|
+
// Are we allowed to do auto sizing?
|
542
|
+
if ( ! this.c.auto ) {
|
543
|
+
return;
|
544
|
+
}
|
545
|
+
|
546
|
+
// Are there any columns that actually need auto-sizing, or do they all
|
547
|
+
// have classes defined
|
548
|
+
if ( $.inArray( true, $.map( columns, function (c) { return c.auto; } ) ) === -1 ) {
|
549
|
+
return;
|
550
|
+
}
|
551
|
+
|
552
|
+
// Clone the table with the current data in it
|
553
|
+
var tableWidth = dt.table().node().offsetWidth;
|
554
|
+
var columnWidths = dt.columns;
|
555
|
+
var clonedTable = dt.table().node().cloneNode( false );
|
556
|
+
var clonedHeader = $( dt.table().header().cloneNode( false ) ).appendTo( clonedTable );
|
557
|
+
var clonedBody = $( dt.table().body().cloneNode( false ) ).appendTo( clonedTable );
|
558
|
+
|
559
|
+
// This is a bit slow, but we need to get a clone of each row that
|
560
|
+
// includes all columns. As such, try to do this as little as possible.
|
561
|
+
dt.rows( { page: 'current' } ).indexes().each( function ( idx ) {
|
562
|
+
var clone = dt.row( idx ).node().cloneNode( true );
|
563
|
+
|
564
|
+
if ( dt.columns( ':hidden' ).flatten().length ) {
|
565
|
+
$(clone).append( dt.cells( idx, ':hidden' ).nodes().to$().clone() );
|
566
|
+
}
|
567
|
+
|
568
|
+
$(clone).appendTo( clonedBody );
|
569
|
+
} );
|
570
|
+
|
571
|
+
var cells = dt.columns().header().to$().clone( false ).wrapAll('tr').appendTo( clonedHeader );
|
572
|
+
var inserted = $('<div/>')
|
573
|
+
.css( {
|
574
|
+
width: 1,
|
575
|
+
height: 1,
|
576
|
+
overflow: 'hidden'
|
577
|
+
} )
|
578
|
+
.append( clonedTable )
|
579
|
+
.insertBefore( dt.table().node() );
|
580
|
+
|
581
|
+
// The cloned header now contains the smallest that each column can be
|
582
|
+
dt.columns().eq(0).each( function ( idx ) {
|
583
|
+
columns[idx].minWidth = cells[ idx ].offsetWidth || 0;
|
584
|
+
} );
|
585
|
+
|
586
|
+
inserted.remove();
|
587
|
+
}
|
255
588
|
};
|
256
589
|
|
257
|
-
/**
|
258
|
-
* Sets or removes window resize handler.
|
259
|
-
*
|
260
|
-
* @param {Boolean} bindFlag
|
261
|
-
*/
|
262
|
-
ResponsiveDatatablesHelper.prototype.setWindowsResizeHandler = function(bindFlag) {
|
263
|
-
if (bindFlag === undefined) {
|
264
|
-
bindFlag = true;
|
265
|
-
}
|
266
|
-
|
267
|
-
if (bindFlag) {
|
268
|
-
var that = this;
|
269
|
-
$(window).bind("resize", function () {
|
270
|
-
that.respond();
|
271
|
-
});
|
272
|
-
} else {
|
273
|
-
$(window).unbind("resize");
|
274
|
-
}
|
275
|
-
};
|
276
590
|
|
277
591
|
/**
|
278
|
-
*
|
592
|
+
* List of default breakpoints. Each item in the array is an object with two
|
593
|
+
* properties:
|
594
|
+
*
|
595
|
+
* * `name` - the breakpoint name.
|
596
|
+
* * `width` - the breakpoint width
|
597
|
+
*
|
598
|
+
* @name Responsive.breakpoints
|
599
|
+
* @static
|
279
600
|
*/
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
var newWindowWidth = $(window).width();
|
288
|
-
|
289
|
-
// Loop through breakpoints to see which columns need to be shown/hidden.
|
290
|
-
var newColumnsToHide = [];
|
291
|
-
|
292
|
-
for (var prop in this.breakpoints) {
|
293
|
-
var element = this.breakpoints[prop];
|
294
|
-
if ((!element.lowerLimit || newWindowWidth > element.lowerLimit) && (!element.upperLimit || newWindowWidth <= element.upperLimit)) {
|
295
|
-
this.currentBreakpoint = element.name;
|
296
|
-
newColumnsToHide = element.columnsToHide;
|
297
|
-
}
|
298
|
-
}
|
299
|
-
|
300
|
-
// Find out if a column show/hide should happen.
|
301
|
-
// Skip column show/hide if this window width change follows immediately
|
302
|
-
// after a previous column show/hide. This will help prevent a loop.
|
303
|
-
var columnShowHide = false;
|
304
|
-
if (!this.skipNextWindowsWidthChange) {
|
305
|
-
// Check difference in length
|
306
|
-
if (this.lastBreakpoint.length === 0 && newColumnsToHide.length) {
|
307
|
-
// No previous breakpoint and new breakpoint
|
308
|
-
columnShowHide = true;
|
309
|
-
} else if (this.lastBreakpoint != this.currentBreakpoint) {
|
310
|
-
// Different breakpoints
|
311
|
-
columnShowHide = true;
|
312
|
-
} else if (this.columnsHiddenIndexes.length !== newColumnsToHide.length) {
|
313
|
-
// Difference in number of hidden columns
|
314
|
-
columnShowHide = true;
|
315
|
-
} else {
|
316
|
-
// Possible same number of columns but check for difference in columns
|
317
|
-
var d1 = this.difference(this.columnsHiddenIndexes, newColumnsToHide).length;
|
318
|
-
var d2 = this.difference(newColumnsToHide, this.columnsHiddenIndexes).length;
|
319
|
-
columnShowHide = d1 + d2 > 0;
|
320
|
-
}
|
321
|
-
}
|
322
|
-
|
323
|
-
if (columnShowHide) {
|
324
|
-
// Showing/hiding a column at breakpoint may cause a windows width
|
325
|
-
// change. Let's flag to skip the column show/hide that may be
|
326
|
-
// caused by the next windows width change.
|
327
|
-
this.skipNextWindowsWidthChange = true;
|
328
|
-
this.columnsHiddenIndexes = newColumnsToHide;
|
329
|
-
this.columnsShownIndexes = this.difference(this.columnIndexes, this.columnsHiddenIndexes);
|
330
|
-
this.showHideColumns();
|
331
|
-
this.lastBreakpoint = this.currentBreakpoint;
|
332
|
-
this.setState();
|
333
|
-
this.skipNextWindowsWidthChange = false;
|
334
|
-
}
|
335
|
-
|
336
|
-
|
337
|
-
// We don't skip this part.
|
338
|
-
// If one or more columns have been hidden, add the has-columns-hidden class to table.
|
339
|
-
// This class will show what state the table is in.
|
340
|
-
if (this.columnsHiddenIndexes.length) {
|
341
|
-
this.tableElement.addClass('has-columns-hidden');
|
342
|
-
|
343
|
-
// Show details for each row that is tagged with the class .detail-show.
|
344
|
-
$('tr.detail-show', this.tableElement).each(function (index, element) {
|
345
|
-
var tr = $(element);
|
346
|
-
if (tr.next('.row-detail').length === 0) {
|
347
|
-
ResponsiveDatatablesHelper.prototype.showRowDetail(that, tr);
|
348
|
-
}
|
349
|
-
});
|
350
|
-
} else {
|
351
|
-
this.tableElement.removeClass('has-columns-hidden');
|
352
|
-
$('tr.row-detail').each(function (event) {
|
353
|
-
ResponsiveDatatablesHelper.prototype.hideRowDetail(that, $(this).prev());
|
354
|
-
});
|
355
|
-
}
|
356
|
-
};
|
601
|
+
Responsive.breakpoints = [
|
602
|
+
{ name: 'desktop', width: Infinity },
|
603
|
+
{ name: 'tablet-l', width: 1024 },
|
604
|
+
{ name: 'tablet-p', width: 768 },
|
605
|
+
{ name: 'mobile-l', width: 480 },
|
606
|
+
{ name: 'mobile-p', width: 320 }
|
607
|
+
];
|
357
608
|
|
358
|
-
/**
|
359
|
-
* Show/hide datatables columns.
|
360
|
-
*/
|
361
|
-
ResponsiveDatatablesHelper.prototype.showHideColumns = function () {
|
362
|
-
// Calculate the columns to show
|
363
|
-
// Show columns that may have been previously hidden.
|
364
|
-
for (var i = 0, l = this.columnsShownIndexes.length; i < l; i++) {
|
365
|
-
this.api.column(this.columnsShownIndexes[i]).visible(true);
|
366
|
-
}
|
367
|
-
|
368
|
-
// Hide columns that may have been previously shown.
|
369
|
-
for (var i = 0, l = this.columnsHiddenIndexes.length; i < l; i++) {
|
370
|
-
this.api.column(this.columnsHiddenIndexes[i]).visible(false);
|
371
|
-
}
|
372
|
-
|
373
|
-
// Rebuild details to reflect shown/hidden column changes.
|
374
|
-
var that = this;
|
375
|
-
$('tr.row-detail').each(function () {
|
376
|
-
ResponsiveDatatablesHelper.prototype.hideRowDetail(that, $(this).prev());
|
377
|
-
});
|
378
|
-
if (this.tableElement.hasClass('has-columns-hidden')) {
|
379
|
-
$('tr.detail-show', this.tableElement).each(function (index, element) {
|
380
|
-
ResponsiveDatatablesHelper.prototype.showRowDetail(that, $(element));
|
381
|
-
});
|
382
|
-
}
|
383
|
-
};
|
384
609
|
|
385
610
|
/**
|
386
|
-
*
|
387
|
-
* defined for it's header.
|
611
|
+
* Responsive default settings for initialisation
|
388
612
|
*
|
389
|
-
* @
|
613
|
+
* @namespace
|
614
|
+
* @name Responsive.defaults
|
615
|
+
* @static
|
390
616
|
*/
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
617
|
+
Responsive.defaults = {
|
618
|
+
/**
|
619
|
+
* List of breakpoints for the instance. Note that this means that each
|
620
|
+
* instance can have its own breakpoints. Additionally, the breakpoints
|
621
|
+
* cannot be changed once an instance has been creased.
|
622
|
+
*
|
623
|
+
* @type {Array}
|
624
|
+
* @default Takes the value of `Responsive.breakpoints`
|
625
|
+
*/
|
626
|
+
breakpoints: Responsive.breakpoints,
|
627
|
+
|
628
|
+
/**
|
629
|
+
* Enable / disable auto hiding calculations. It can help to increase
|
630
|
+
* performance slightly if you disable this option, but all columns would
|
631
|
+
* need to have breakpoint classes assigned to them
|
632
|
+
*
|
633
|
+
* @type {Boolean}
|
634
|
+
* @default `true`
|
635
|
+
*/
|
636
|
+
auto: true,
|
637
|
+
|
638
|
+
/**
|
639
|
+
* Details control. If given as a string value, the `type` property of the
|
640
|
+
* default object is set to that value, and the defaults used for the rest
|
641
|
+
* of the object - this is for ease of implementation.
|
642
|
+
*
|
643
|
+
* The object consists of the following properties:
|
644
|
+
*
|
645
|
+
* * `renderer` - function that is called for display of the child row data.
|
646
|
+
* The default function will show the data from the hidden columns
|
647
|
+
* * `target` - Used as the selector for what objects to attach the child
|
648
|
+
* open / close to
|
649
|
+
* * `type` - `false` to disable the details display, `inline` or `column`
|
650
|
+
* for the two control types
|
651
|
+
*
|
652
|
+
* @type {Object|string}
|
653
|
+
*/
|
654
|
+
details: {
|
655
|
+
renderer: function ( api, rowIdx ) {
|
656
|
+
var data = api.cells( rowIdx, ':hidden' ).eq(0).map( function ( cell ) {
|
657
|
+
var header = $( api.column( cell.column ).header() );
|
658
|
+
|
659
|
+
if ( header.hasClass( 'control' ) ) {
|
660
|
+
return '';
|
661
|
+
}
|
662
|
+
|
663
|
+
return '<li>'+
|
664
|
+
'<span class="dtr-title">'+
|
665
|
+
header.text()+':'+
|
666
|
+
'</span> '+
|
667
|
+
'<span class="dtr-data">'+
|
668
|
+
api.cell( cell ).data()+
|
669
|
+
'</span>'+
|
670
|
+
'</li>';
|
671
|
+
} ).toArray().join('');
|
672
|
+
|
673
|
+
return data ?
|
674
|
+
$('<ul/>').append( data ) :
|
675
|
+
false;
|
676
|
+
},
|
677
|
+
|
678
|
+
target: 0,
|
679
|
+
|
680
|
+
type: 'inline'
|
681
|
+
}
|
426
682
|
};
|
427
683
|
|
428
|
-
/**
|
429
|
-
* Show row detail event handler.
|
430
|
-
*
|
431
|
-
* This handler is used to handle the click event of the expand icon defined in
|
432
|
-
* the table row data element.
|
433
|
-
*
|
434
|
-
* @param {Object} event jQuery event object
|
435
|
-
*/
|
436
|
-
ResponsiveDatatablesHelper.prototype.showRowDetailEventHandler = function (event) {
|
437
|
-
var responsiveDatatablesHelperInstance = event.data.responsiveDatatablesHelperInstance;
|
438
|
-
if (responsiveDatatablesHelperInstance.disabled) {
|
439
|
-
return;
|
440
|
-
}
|
441
|
-
|
442
|
-
var td = $(this);
|
443
|
-
|
444
|
-
// Nothing to do if there are no columns hidden.
|
445
|
-
if (!td.closest('table').hasClass('has-columns-hidden')) {
|
446
|
-
return;
|
447
|
-
}
|
448
|
-
|
449
|
-
// Get the parent tr of which this td belongs to.
|
450
|
-
var tr = td.closest('tr');
|
451
|
-
|
452
|
-
// Show/hide row details
|
453
|
-
if (tr.hasClass('detail-show')) {
|
454
|
-
ResponsiveDatatablesHelper.prototype.hideRowDetail(responsiveDatatablesHelperInstance, tr);
|
455
|
-
} else {
|
456
|
-
ResponsiveDatatablesHelper.prototype.showRowDetail(responsiveDatatablesHelperInstance, tr);
|
457
|
-
}
|
458
684
|
|
459
|
-
|
685
|
+
/*
|
686
|
+
* API
|
687
|
+
*/
|
688
|
+
var Api = $.fn.dataTable.Api;
|
460
689
|
|
461
|
-
|
462
|
-
|
463
|
-
|
690
|
+
// Doesn't do anything - work around for a bug in DT... Not documented
|
691
|
+
Api.register( 'responsive()', function () {
|
692
|
+
return this;
|
693
|
+
} );
|
464
694
|
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
var api = responsiveDatatablesHelperInstance.api;
|
474
|
-
var columns = api.columns().header();
|
475
|
-
|
476
|
-
// Create the new tr.
|
477
|
-
var newTr = $(responsiveDatatablesHelperInstance.rowTemplate);
|
478
|
-
|
479
|
-
// Get the ul that we'll insert li's into.
|
480
|
-
var ul = $('ul', newTr);
|
481
|
-
|
482
|
-
// Loop through hidden columns and create an li for each of them.
|
483
|
-
for (var i = 0; i < responsiveDatatablesHelperInstance.columnsHiddenIndexes.length; i++) {
|
484
|
-
var index = responsiveDatatablesHelperInstance.columnsHiddenIndexes[i];
|
485
|
-
|
486
|
-
// Get row td
|
487
|
-
var rowIndex = api.row(tr).index();
|
488
|
-
var td = api.cell(rowIndex, index).node();
|
489
|
-
|
490
|
-
// Don't create li if contents are empty (depends on hideEmptyColumnsInRowDetail option).
|
491
|
-
if (!responsiveDatatablesHelperInstance.options.hideEmptyColumnsInRowDetail || td.innerHTML.trim().length) {
|
492
|
-
var li = $(responsiveDatatablesHelperInstance.rowLiTemplate);
|
493
|
-
var hiddenColumnName = $(columns[index]).attr('data-name');
|
494
|
-
$('.columnTitle', li).html(hiddenColumnName !== undefined ? hiddenColumnName : columns[index].innerHTML);
|
495
|
-
var contents = $(td).contents();
|
496
|
-
var clonedContents = contents.clone();
|
497
|
-
|
498
|
-
// Select elements' selectedIndex are not cloned. Do it manually.
|
499
|
-
for (var n = 0, m = contents.length; n < m; n++) {
|
500
|
-
var node = contents[n];
|
501
|
-
if (node.nodeType === Node.ELEMENT_NODE && node.tagName === 'SELECT') {
|
502
|
-
clonedContents[n].selectedIndex = node.selectedIndex
|
503
|
-
}
|
504
|
-
}
|
505
|
-
|
506
|
-
// Set the column contents and save the original td source.
|
507
|
-
$('.columnValue', li).append(clonedContents).data('originalTdSource', td);
|
508
|
-
|
509
|
-
// Copy index to data attribute, so we'll know where to put the value when the tr.row-detail is removed.
|
510
|
-
li.attr('data-column', index);
|
511
|
-
|
512
|
-
// Copy td class to new li.
|
513
|
-
var tdClass = $(td).attr('class');
|
514
|
-
if (tdClass !== 'undefined' && tdClass !== false && tdClass !== '') {
|
515
|
-
li.addClass(tdClass)
|
516
|
-
}
|
517
|
-
|
518
|
-
ul.append(li);
|
519
|
-
}
|
520
|
-
}
|
521
|
-
|
522
|
-
// Create tr colspan attribute.
|
523
|
-
var colspan = responsiveDatatablesHelperInstance.columnIndexes.length - responsiveDatatablesHelperInstance.columnsHiddenIndexes.length;
|
524
|
-
newTr.find('> td').attr('colspan', colspan);
|
525
|
-
|
526
|
-
// Append the new tr after the current tr.
|
527
|
-
tr.after(newTr);
|
528
|
-
|
529
|
-
// call the showDetail function if needbe
|
530
|
-
if (responsiveDatatablesHelperInstance.options.showDetail){
|
531
|
-
responsiveDatatablesHelperInstance.options.showDetail(newTr);
|
532
|
-
}
|
533
|
-
};
|
695
|
+
Api.register( 'responsive.recalc()', function ( rowIdx, intParse, virtual ) {
|
696
|
+
this.iterator( 'table', function ( ctx ) {
|
697
|
+
if ( ctx._responsive ) {
|
698
|
+
ctx._responsive._resizeAuto();
|
699
|
+
ctx._responsive._resize();
|
700
|
+
}
|
701
|
+
} );
|
702
|
+
} );
|
534
703
|
|
535
|
-
/**
|
536
|
-
* Hide row details.
|
537
|
-
*
|
538
|
-
* @param {ResponsiveDatatablesHelper} responsiveDatatablesHelperInstance instance of ResponsiveDatatablesHelper
|
539
|
-
* @param {Object} tr jQuery wrapped set
|
540
|
-
*/
|
541
|
-
ResponsiveDatatablesHelper.prototype.hideRowDetail = function (responsiveDatatablesHelperInstance, tr) {
|
542
|
-
// If the value of an input has changed while in row detail, we need to copy its state back
|
543
|
-
// to the DataTables object so that value will persist when the tr.row-detail is removed.
|
544
|
-
var rowDetail = tr.next('.row-detail');
|
545
|
-
if (responsiveDatatablesHelperInstance.options.hideDetail){
|
546
|
-
responsiveDatatablesHelperInstance.options.hideDetail(rowDetail);
|
547
|
-
}
|
548
|
-
rowDetail.find('li').each(function () {
|
549
|
-
var columnValueContainer = $(this).find('span.columnValue');
|
550
|
-
var tdContents = columnValueContainer.contents();
|
551
|
-
var td = columnValueContainer.data('originalTdSource');
|
552
|
-
$(td).empty().append(tdContents);
|
553
|
-
});
|
554
|
-
rowDetail.remove();
|
555
|
-
};
|
556
704
|
|
557
705
|
/**
|
558
|
-
*
|
706
|
+
* Version information
|
559
707
|
*
|
560
|
-
* @
|
708
|
+
* @name Responsive.version
|
709
|
+
* @static
|
561
710
|
*/
|
562
|
-
|
563
|
-
this.disabled = (disable === undefined) || disable;
|
711
|
+
Responsive.version = '1.0.1';
|
564
712
|
|
565
|
-
if (this.disabled) {
|
566
|
-
// Remove windows resize handler.
|
567
|
-
this.setWindowsResizeHandler(false);
|
568
713
|
|
569
|
-
|
570
|
-
|
714
|
+
$.fn.dataTable.Responsive = Responsive;
|
715
|
+
$.fn.DataTable.Responsive = Responsive;
|
571
716
|
|
572
|
-
|
573
|
-
|
717
|
+
// Attach a listener to the document which listens for DataTables initialisation
|
718
|
+
// events so we can automatically initialise
|
719
|
+
$(document).on( 'init.dt.dtr', function (e, settings, json) {
|
720
|
+
if ( $(settings.nTable).hasClass( 'responsive' ) ||
|
721
|
+
$(settings.nTable).hasClass( 'dt-responsive' ) ||
|
722
|
+
settings.oInit.responsive
|
723
|
+
) {
|
724
|
+
var init = settings.oInit.responsive;
|
574
725
|
|
575
|
-
|
576
|
-
|
726
|
+
if ( init !== false ) {
|
727
|
+
new Responsive( settings, $.isPlainObject( init ) ? init : {} );
|
728
|
+
}
|
729
|
+
}
|
730
|
+
} );
|
577
731
|
|
578
|
-
|
579
|
-
|
580
|
-
this.showHideColumns();
|
581
|
-
this.tableElement.removeClass('has-columns-hidden');
|
582
|
-
|
583
|
-
this.tableElement.off('click', 'span.responsiveExpander', this.showRowDetailEventHandler);
|
584
|
-
} else {
|
585
|
-
// Add windows resize handler.
|
586
|
-
this.setWindowsResizeHandler();
|
587
|
-
}
|
588
|
-
};
|
732
|
+
return Responsive;
|
733
|
+
}; // /factory
|
589
734
|
|
590
|
-
/**
|
591
|
-
* Get state from cookie.
|
592
|
-
*/
|
593
|
-
ResponsiveDatatablesHelper.prototype.getState = function () {
|
594
|
-
try {
|
595
|
-
var value = JSON.parse(decodeURIComponent(this.getCookie(this.cookieName)));
|
596
|
-
if (value) {
|
597
|
-
this.columnIndexes = value.columnIndexes;
|
598
|
-
this.breakpoints = value.breakpoints;
|
599
|
-
this.expandColumn = value.expandColumn;
|
600
|
-
this.lastBreakpoint = value.lastBreakpoint;
|
601
|
-
this.lastStateExists = true;
|
602
|
-
}
|
603
|
-
} catch (e) {
|
604
|
-
}
|
605
|
-
};
|
606
735
|
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
expandColumn: this.expandColumn,
|
620
|
-
lastBreakpoint: this.lastBreakpoint
|
621
|
-
}));
|
622
|
-
|
623
|
-
this.setCookie(this.cookieName, value, 2 * 60 * 60 * 1000);
|
624
|
-
this.lastColumnsHiddenIndexes = this.columnsHiddenIndexes.slice(0);
|
625
|
-
}
|
626
|
-
};
|
736
|
+
// Define as an AMD module if possible
|
737
|
+
if ( typeof define === 'function' && define.amd ) {
|
738
|
+
define( ['jquery', 'datatables'], factory );
|
739
|
+
}
|
740
|
+
else if ( typeof exports === 'object' ) {
|
741
|
+
// Node/CommonJS
|
742
|
+
factory( require('jquery'), require('datatables') );
|
743
|
+
}
|
744
|
+
else if ( jQuery && !jQuery.fn.dataTable.Responsive ) {
|
745
|
+
// Otherwise simply initialise as normal, stopping multiple evaluation
|
746
|
+
factory( jQuery, jQuery.fn.dataTable );
|
747
|
+
}
|
627
748
|
|
628
|
-
/**
|
629
|
-
* Get cookie.
|
630
|
-
*/
|
631
|
-
ResponsiveDatatablesHelper.prototype.getCookie = function (cname) {
|
632
|
-
var name = cname + "=";
|
633
|
-
var ca = document.cookie.split(';');
|
634
|
-
for (var i = 0; i < ca.length; i++) {
|
635
|
-
var c = ca[i].trim();
|
636
|
-
if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
|
637
|
-
}
|
638
|
-
return "";
|
639
|
-
};
|
640
749
|
|
641
|
-
|
642
|
-
* Set cookie.
|
643
|
-
*/
|
644
|
-
ResponsiveDatatablesHelper.prototype.setCookie = function (cname, cvalue, cexp) {
|
645
|
-
var d = new Date();
|
646
|
-
d.setTime(d.getTime() + cexp);
|
647
|
-
var expires = "expires=" + d.toGMTString();
|
648
|
-
document.cookie = cname + "=" + cvalue + "; " + expires;
|
649
|
-
};
|
750
|
+
})(window, document);
|
650
751
|
|
651
|
-
/**
|
652
|
-
* Get Difference.
|
653
|
-
*/
|
654
|
-
ResponsiveDatatablesHelper.prototype.difference = function (a, b) {
|
655
|
-
var arr = [], i, hash = {};
|
656
|
-
for (i = b.length - 1; i >= 0; i--) {
|
657
|
-
hash[b[i]] = true;
|
658
|
-
}
|
659
|
-
for (i = a.length - 1; i >= 0; i--) {
|
660
|
-
if (hash[a[i]] !== true) {
|
661
|
-
arr.push(a[i]);
|
662
|
-
}
|
663
|
-
}
|
664
|
-
return arr;
|
665
|
-
};
|