jquery-datatables 1.10.19.1 → 1.10.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitattributes +1 -0
- data/README.md +28 -1
- data/app/assets/javascripts/datatables/dataTables.uikit.js +2 -2
- data/app/assets/javascripts/datatables/extensions/AutoFill/dataTables.autoFill.js +42 -29
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.bootstrap.js +1 -1
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.bootstrap4.js +8 -2
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.colVis.js +6 -3
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.foundation.js +5 -4
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.html5.js +58 -6
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.print.js +16 -5
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.semanticui.js +1 -1
- data/app/assets/javascripts/datatables/extensions/Buttons/dataTables.buttons.js +267 -152
- data/app/assets/javascripts/datatables/extensions/ColReorder/colReorder.foundation.js +1 -1
- data/app/assets/javascripts/datatables/extensions/ColReorder/dataTables.colReorder.js +121 -52
- data/app/assets/javascripts/datatables/extensions/FixedColumns/dataTables.fixedColumns.js +32 -5
- data/app/assets/javascripts/datatables/extensions/KeyTable/dataTables.keyTable.js +166 -63
- data/app/assets/javascripts/datatables/extensions/KeyTable/keyTable.foundation.js +1 -1
- data/app/assets/javascripts/datatables/extensions/RowGroup/dataTables.rowGroup.js +105 -53
- data/app/assets/javascripts/datatables/extensions/RowGroup/rowGroup.foundation.js +1 -1
- data/app/assets/javascripts/datatables/extensions/RowGroup/{rowGroup.semanicui.js → rowGroup.semanticui.js} +0 -0
- data/app/assets/javascripts/datatables/extensions/RowReorder/dataTables.rowReorder.js +10 -9
- data/app/assets/javascripts/datatables/extensions/RowReorder/rowReorder.foundation.js +1 -1
- data/app/assets/javascripts/datatables/extensions/Scroller/dataTables.scroller.js +519 -636
- data/app/assets/javascripts/datatables/extensions/Scroller/scroller.foundation.js +1 -1
- data/app/assets/javascripts/datatables/extensions/Select/dataTables.select.js +49 -18
- data/app/assets/javascripts/datatables/extensions/Select/select.foundation.js +1 -1
- data/app/assets/javascripts/datatables/jquery.dataTables.js +97 -60
- data/app/assets/javascripts/datatables/plugins/api/average.js +7 -6
- data/app/assets/javascripts/datatables/plugins/api/sum.js +7 -6
- data/app/assets/javascripts/datatables/plugins/pagination/ellipses.js +160 -0
- data/app/assets/javascripts/datatables/plugins/pagination/extjs.js +137 -0
- data/app/assets/javascripts/datatables/plugins/pagination/four_button.js +110 -0
- data/app/assets/javascripts/datatables/plugins/pagination/full_numbers_no_ellipses.js +59 -0
- data/app/assets/javascripts/datatables/plugins/pagination/input.js +22 -19
- data/app/assets/javascripts/datatables/plugins/pagination/scrolling.js +130 -0
- data/app/assets/javascripts/datatables/plugins/pagination/select.js +97 -0
- data/app/assets/javascripts/datatables/plugins/pagination/simple_incremental_bootstrap.js +154 -0
- data/app/assets/javascripts/datatables/plugins/pagination/simple_numbers_no_ellipses.js +59 -0
- data/app/assets/javascripts/datatables/plugins/search/dataTables.alphabetSearch.js +440 -399
- data/app/assets/javascripts/datatables/plugins/sorting/enum.js +51 -0
- data/app/assets/javascripts/datatables/plugins/type-detection/date-dd-MMM-yyyy.js +63 -0
- data/app/assets/javascripts/datatables/plugins/type-detection/date-de.js +125 -0
- data/app/assets/javascripts/datatables/plugins/type-detection/date-eu.js +64 -0
- data/app/assets/javascripts/datatables/plugins/type-detection/date-euro.js +48 -0
- data/app/assets/javascripts/datatables/plugins/type-detection/date-uk.js +35 -12
- data/app/assets/javascripts/datatables/plugins/type-detection/datetime-moment.js +74 -0
- data/app/assets/javascripts/datatables/plugins/type-detection/datetime-us.js +86 -0
- data/app/assets/javascripts/datatables/plugins/type-detection/file-size.js +37 -13
- data/app/assets/javascripts/datatables/plugins/type-detection/ip-address.js +113 -11
- data/app/assets/javascripts/datatables/plugins/type-detection/numString.js +63 -0
- data/app/assets/javascripts/datatables/plugins/type-detection/percent.js +34 -0
- data/app/assets/javascripts/datatables/plugins/type-detection/time-elapsed-dhms.js +42 -0
- data/app/assets/javascripts/datatables/plugins/type-detection/time.js +56 -0
- data/app/assets/javascripts/datatables/plugins/type-detection/title-numeric.js +40 -0
- data/app/assets/javascripts/datatables/plugins/type-detection/title-string.js +36 -0
- data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.dataTables.scss +10 -3
- data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.bootstrap.scss +12 -3
- data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.bootstrap4.scss +13 -6
- data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.dataTables.scss +2 -0
- data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.foundation.scss +5 -1
- data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.jqueryui.scss +1 -0
- data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.semanticui.scss +2 -1
- data/app/assets/stylesheets/datatables/extensions/Buttons/common.scss +10 -0
- data/app/assets/stylesheets/datatables/extensions/Buttons/mixins.scss +42 -30
- data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.bootstrap.scss +11 -7
- data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.foundation.scss +1 -0
- data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.dataTables.scss +13 -5
- data/app/assets/stylesheets/datatables/extensions/RowGroup/rowGroup.dataTables.scss +20 -2
- data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.dataTables.scss +15 -2
- data/lib/jquery-datatables/version.rb +1 -1
- metadata +26 -12
- data/app/assets/javascripts/datatables/dataTables.bootstrap2.js +0 -162
- data/app/assets/javascripts/datatables/extensions/ColReorder/colReorder.semanicui.js +0 -38
- data/app/assets/javascripts/datatables/extensions/FixedColumns/fixedColumns.semanicui.js +0 -38
- data/app/assets/javascripts/datatables/extensions/FixedHeader/fixedHeader.semanicui.js +0 -38
- data/app/assets/javascripts/datatables/extensions/KeyTable/keyTable.semanicui.js +0 -38
- data/app/assets/javascripts/datatables/extensions/RowReorder/rowReorder.semanicui.js +0 -38
- data/app/assets/stylesheets/datatables/dataTables.bootstrap2.scss +0 -178
@@ -1,15 +1,15 @@
|
|
1
|
-
/*! RowGroup 1.
|
2
|
-
* ©2017-
|
1
|
+
/*! RowGroup 1.1.1
|
2
|
+
* ©2017-2019 SpryMedia Ltd - datatables.net/license
|
3
3
|
*/
|
4
4
|
|
5
5
|
/**
|
6
6
|
* @summary RowGroup
|
7
7
|
* @description RowGrouping for DataTables
|
8
|
-
* @version 1.
|
8
|
+
* @version 1.1.1
|
9
9
|
* @file dataTables.rowGroup.js
|
10
10
|
* @author SpryMedia Ltd (www.sprymedia.co.uk)
|
11
11
|
* @contact datatables.net
|
12
|
-
* @copyright Copyright 2017-
|
12
|
+
* @copyright Copyright 2017-2019 SpryMedia Ltd.
|
13
13
|
*
|
14
14
|
* This source file is free software, available under the following license:
|
15
15
|
* MIT license - http://datatables.net/license/mit
|
@@ -66,9 +66,7 @@ var RowGroup = function ( dt, opts ) {
|
|
66
66
|
|
67
67
|
// Internal settings
|
68
68
|
this.s = {
|
69
|
-
dt: new DataTable.Api( dt )
|
70
|
-
|
71
|
-
dataFn: DataTable.ext.oApi._fnGetObjectDataFn( this.c.dataSrc )
|
69
|
+
dt: new DataTable.Api( dt )
|
72
70
|
};
|
73
71
|
|
74
72
|
// DOM items
|
@@ -107,7 +105,6 @@ $.extend( RowGroup.prototype, {
|
|
107
105
|
var dt = this.s.dt;
|
108
106
|
|
109
107
|
this.c.dataSrc = val;
|
110
|
-
this.s.dataFn = DataTable.ext.oApi._fnGetObjectDataFn( this.c.dataSrc );
|
111
108
|
|
112
109
|
$(dt.table().node()).triggerHandler( 'rowgroup-datasrc.dt', [ dt, val ] );
|
113
110
|
|
@@ -146,17 +143,6 @@ $.extend( RowGroup.prototype, {
|
|
146
143
|
{
|
147
144
|
var that = this;
|
148
145
|
var dt = this.s.dt;
|
149
|
-
var rows = dt.rows();
|
150
|
-
var groups = [];
|
151
|
-
|
152
|
-
rows.every( function () {
|
153
|
-
var d = this.data();
|
154
|
-
var group = that.s.dataFn( d );
|
155
|
-
|
156
|
-
if ( groups.indexOf(group) == -1 ) {
|
157
|
-
groups.push( group );
|
158
|
-
}
|
159
|
-
} );
|
160
146
|
|
161
147
|
dt.on( 'draw.dtrg', function () {
|
162
148
|
if ( that.c.enable ) {
|
@@ -171,6 +157,10 @@ $.extend( RowGroup.prototype, {
|
|
171
157
|
dt.on( 'destroy', function () {
|
172
158
|
dt.off( '.dtrg' );
|
173
159
|
} );
|
160
|
+
|
161
|
+
dt.on('responsive-resize.dt', function () {
|
162
|
+
that._adjustColspan();
|
163
|
+
})
|
174
164
|
},
|
175
165
|
|
176
166
|
|
@@ -184,7 +174,7 @@ $.extend( RowGroup.prototype, {
|
|
184
174
|
*/
|
185
175
|
_adjustColspan: function ()
|
186
176
|
{
|
187
|
-
$( 'tr.'+this.c.className, this.s.dt.table().body() )
|
177
|
+
$( 'tr.'+this.c.className, this.s.dt.table().body() ).find('td')
|
188
178
|
.attr( 'colspan', this._colspan() );
|
189
179
|
},
|
190
180
|
|
@@ -199,76 +189,137 @@ $.extend( RowGroup.prototype, {
|
|
199
189
|
}, 0 );
|
200
190
|
},
|
201
191
|
|
192
|
+
|
202
193
|
/**
|
203
|
-
* Update function that is called whenever we need to draw the grouping rows
|
194
|
+
* Update function that is called whenever we need to draw the grouping rows.
|
195
|
+
* This is basically a bootstrap for the self iterative _group and _groupDisplay
|
196
|
+
* methods
|
204
197
|
* @private
|
205
198
|
*/
|
206
199
|
_draw: function ()
|
207
200
|
{
|
208
|
-
var that = this;
|
209
201
|
var dt = this.s.dt;
|
210
|
-
var
|
211
|
-
|
212
|
-
|
202
|
+
var groupedRows = this._group( 0, dt.rows( { page: 'current' } ).indexes() );
|
203
|
+
|
204
|
+
this._groupDisplay( 0, groupedRows );
|
205
|
+
},
|
206
|
+
|
207
|
+
/**
|
208
|
+
* Get the grouping information from a data set (index) of rows
|
209
|
+
* @param {number} level Nesting level
|
210
|
+
* @param {DataTables.Api} rows API of the rows to consider for this group
|
211
|
+
* @returns {object[]} Nested grouping information - it is structured like this:
|
212
|
+
* {
|
213
|
+
* dataPoint: 'Edinburgh',
|
214
|
+
* rows: [ 1,2,3,4,5,6,7 ],
|
215
|
+
* children: [ {
|
216
|
+
* dataPoint: 'developer'
|
217
|
+
* rows: [ 1, 2, 3 ]
|
218
|
+
* },
|
219
|
+
* {
|
220
|
+
* dataPoint: 'support',
|
221
|
+
* rows: [ 4, 5, 6, 7 ]
|
222
|
+
* } ]
|
223
|
+
* }
|
224
|
+
* @private
|
225
|
+
*/
|
226
|
+
_group: function ( level, rows ) {
|
227
|
+
var fns = $.isArray( this.c.dataSrc ) ? this.c.dataSrc : [ this.c.dataSrc ];
|
228
|
+
var fn = DataTable.ext.oApi._fnGetObjectDataFn( fns[ level ] );
|
229
|
+
var dt = this.s.dt;
|
230
|
+
var group, last;
|
231
|
+
var data = [];
|
232
|
+
var that = this;
|
213
233
|
|
214
|
-
rows.
|
215
|
-
var
|
216
|
-
var
|
234
|
+
for ( var i=0, ien=rows.length ; i<ien ; i++ ) {
|
235
|
+
var rowIndex = rows[i];
|
236
|
+
var rowData = dt.row( rowIndex ).data();
|
237
|
+
var group = fn( rowData );
|
217
238
|
|
218
239
|
if ( group === null || group === undefined ) {
|
219
240
|
group = that.c.emptyDataGroup;
|
220
241
|
}
|
221
242
|
|
222
243
|
if ( last === undefined || group !== last ) {
|
223
|
-
|
244
|
+
data.push( {
|
245
|
+
dataPoint: group,
|
246
|
+
rows: []
|
247
|
+
} );
|
248
|
+
|
224
249
|
last = group;
|
225
250
|
}
|
226
|
-
|
227
|
-
groupedRows[ groupedRows.length - 1 ].push( this.index() );
|
228
|
-
} );
|
229
251
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
252
|
+
data[ data.length-1 ].rows.push( rowIndex );
|
253
|
+
}
|
254
|
+
|
255
|
+
if ( fns[ level+1 ] !== undefined ) {
|
256
|
+
for ( var i=0, ien=data.length ; i<ien ; i++ ) {
|
257
|
+
data[i].children = this._group( level+1, data[i].rows );
|
258
|
+
}
|
259
|
+
}
|
260
|
+
|
261
|
+
return data;
|
262
|
+
},
|
263
|
+
|
264
|
+
/**
|
265
|
+
* Row group display - insert the rows into the document
|
266
|
+
* @param {number} level Nesting level
|
267
|
+
* @param {object[]} groups Takes the nested array from `_group`
|
268
|
+
* @private
|
269
|
+
*/
|
270
|
+
_groupDisplay: function ( level, groups )
|
271
|
+
{
|
272
|
+
var dt = this.s.dt;
|
273
|
+
var display;
|
274
|
+
|
275
|
+
for ( var i=0, ien=groups.length ; i<ien ; i++ ) {
|
276
|
+
var group = groups[i];
|
277
|
+
var groupName = group.dataPoint;
|
234
278
|
var row;
|
279
|
+
var rows = group.rows;
|
235
280
|
|
236
281
|
if ( this.c.startRender ) {
|
237
|
-
display = this.c.startRender.call( this, dt.rows(
|
238
|
-
row = this._rowWrap( display, this.c.startClassName );
|
282
|
+
display = this.c.startRender.call( this, dt.rows(rows), groupName, level );
|
283
|
+
row = this._rowWrap( display, this.c.startClassName, level );
|
239
284
|
|
240
285
|
if ( row ) {
|
241
|
-
row.insertBefore(
|
286
|
+
row.insertBefore( dt.row( rows[0] ).node() );
|
242
287
|
}
|
243
288
|
}
|
244
289
|
|
245
290
|
if ( this.c.endRender ) {
|
246
|
-
display = this.c.endRender.call( this, dt.rows(
|
247
|
-
row = this._rowWrap( display, this.c.endClassName );
|
291
|
+
display = this.c.endRender.call( this, dt.rows(rows), groupName, level );
|
292
|
+
row = this._rowWrap( display, this.c.endClassName, level );
|
248
293
|
|
249
294
|
if ( row ) {
|
250
|
-
row.insertAfter( dt.row(
|
295
|
+
row.insertAfter( dt.row( rows[ rows.length-1 ] ).node() );
|
251
296
|
}
|
252
297
|
}
|
298
|
+
|
299
|
+
if ( group.children ) {
|
300
|
+
this._groupDisplay( level+1, group.children );
|
301
|
+
}
|
253
302
|
}
|
254
303
|
},
|
255
304
|
|
256
305
|
/**
|
257
306
|
* Take a rendered value from an end user and make it suitable for display
|
258
307
|
* as a row, by wrapping it in a row, or detecting that it is a row.
|
259
|
-
* @param
|
260
|
-
* @param
|
308
|
+
* @param {node|jQuery|string} display Display value
|
309
|
+
* @param {string} className Class to add to the row
|
310
|
+
* @param {array} group
|
311
|
+
* @param {number} group level
|
261
312
|
* @private
|
262
313
|
*/
|
263
|
-
_rowWrap: function ( display, className )
|
314
|
+
_rowWrap: function ( display, className, level )
|
264
315
|
{
|
265
316
|
var row;
|
266
317
|
|
267
|
-
if ( display === null || display ===
|
318
|
+
if ( display === null || display === '' ) {
|
268
319
|
display = this.c.emptyDataGroup;
|
269
320
|
}
|
270
321
|
|
271
|
-
if ( display === null ) {
|
322
|
+
if ( display === undefined || display === null ) {
|
272
323
|
return null;
|
273
324
|
}
|
274
325
|
|
@@ -289,7 +340,8 @@ $.extend( RowGroup.prototype, {
|
|
289
340
|
|
290
341
|
return row
|
291
342
|
.addClass( this.c.className )
|
292
|
-
.addClass( className )
|
343
|
+
.addClass( className )
|
344
|
+
.addClass( 'dtrg-level-'+level );
|
293
345
|
}
|
294
346
|
} );
|
295
347
|
|
@@ -307,11 +359,11 @@ RowGroup.defaults = {
|
|
307
359
|
* end grouping rows.
|
308
360
|
* @type string
|
309
361
|
*/
|
310
|
-
className: 'group',
|
362
|
+
className: 'dtrg-group',
|
311
363
|
|
312
364
|
/**
|
313
365
|
* Data property from which to read the grouping information
|
314
|
-
* @type string|integer
|
366
|
+
* @type string|integer|array
|
315
367
|
*/
|
316
368
|
dataSrc: 0,
|
317
369
|
|
@@ -331,7 +383,7 @@ RowGroup.defaults = {
|
|
331
383
|
* Class name to give to the end grouping row
|
332
384
|
* @type string
|
333
385
|
*/
|
334
|
-
endClassName: '
|
386
|
+
endClassName: 'dtrg-end',
|
335
387
|
|
336
388
|
/**
|
337
389
|
* End grouping label function
|
@@ -343,7 +395,7 @@ RowGroup.defaults = {
|
|
343
395
|
* Class name to give to the start grouping row
|
344
396
|
* @type string
|
345
397
|
*/
|
346
|
-
startClassName: '
|
398
|
+
startClassName: 'dtrg-start',
|
347
399
|
|
348
400
|
/**
|
349
401
|
* Start grouping label function
|
@@ -355,7 +407,7 @@ RowGroup.defaults = {
|
|
355
407
|
};
|
356
408
|
|
357
409
|
|
358
|
-
RowGroup.version = "1.
|
410
|
+
RowGroup.version = "1.1.1";
|
359
411
|
|
360
412
|
|
361
413
|
$.fn.dataTable.RowGroup = RowGroup;
|
File without changes
|
@@ -1,15 +1,15 @@
|
|
1
|
-
/*! RowReorder 1.2.
|
2
|
-
* 2015-
|
1
|
+
/*! RowReorder 1.2.6
|
2
|
+
* 2015-2019 SpryMedia Ltd - datatables.net/license
|
3
3
|
*/
|
4
4
|
|
5
5
|
/**
|
6
6
|
* @summary RowReorder
|
7
7
|
* @description Row reordering extension for DataTables
|
8
|
-
* @version 1.2.
|
8
|
+
* @version 1.2.6
|
9
9
|
* @file dataTables.rowReorder.js
|
10
10
|
* @author SpryMedia Ltd (www.sprymedia.co.uk)
|
11
11
|
* @contact www.sprymedia.co.uk/contact
|
12
|
-
* @copyright Copyright 2015-
|
12
|
+
* @copyright Copyright 2015-2019 SpryMedia Ltd.
|
13
13
|
*
|
14
14
|
* This source file is free software, available under the following license:
|
15
15
|
* MIT license - http://datatables.net/license/mit
|
@@ -528,10 +528,11 @@ $.extend( RowReorder.prototype, {
|
|
528
528
|
|
529
529
|
// Create event args
|
530
530
|
var eventArgs = [ fullDiff, {
|
531
|
-
dataSrc:
|
532
|
-
nodes:
|
533
|
-
values:
|
534
|
-
triggerRow:
|
531
|
+
dataSrc: dataSrc,
|
532
|
+
nodes: diffNodes,
|
533
|
+
values: idDiff,
|
534
|
+
triggerRow: dt.row( this.dom.target ),
|
535
|
+
originalEvent: e
|
535
536
|
} ];
|
536
537
|
|
537
538
|
// Emit event
|
@@ -788,7 +789,7 @@ Api.register( 'rowReorder.disable()', function () {
|
|
788
789
|
* @name RowReorder.version
|
789
790
|
* @static
|
790
791
|
*/
|
791
|
-
RowReorder.version = '1.2.
|
792
|
+
RowReorder.version = '1.2.6';
|
792
793
|
|
793
794
|
|
794
795
|
$.fn.dataTable.RowReorder = RowReorder;
|
@@ -1,15 +1,15 @@
|
|
1
|
-
/*! Scroller
|
2
|
-
* ©2011-
|
1
|
+
/*! Scroller 2.0.1
|
2
|
+
* ©2011-2019 SpryMedia Ltd - datatables.net/license
|
3
3
|
*/
|
4
4
|
|
5
5
|
/**
|
6
6
|
* @summary Scroller
|
7
7
|
* @description Virtual rendering for DataTables
|
8
|
-
* @version
|
8
|
+
* @version 2.0.1
|
9
9
|
* @file dataTables.scroller.js
|
10
10
|
* @author SpryMedia Ltd (www.sprymedia.co.uk)
|
11
11
|
* @contact www.sprymedia.co.uk/contact
|
12
|
-
* @copyright Copyright 2011-
|
12
|
+
* @copyright Copyright 2011-2019 SpryMedia Ltd.
|
13
13
|
*
|
14
14
|
* This source file is free software, available under the following license:
|
15
15
|
* MIT license - http://datatables.net/license/mit
|
@@ -93,7 +93,7 @@ var DataTable = $.fn.dataTable;
|
|
93
93
|
* $('#example').DataTable( {
|
94
94
|
* "scrollY": "200px",
|
95
95
|
* "ajax": "media/dataset/large.txt",
|
96
|
-
* "
|
96
|
+
* "scroller": true,
|
97
97
|
* "deferRender": true
|
98
98
|
* } );
|
99
99
|
* } );
|
@@ -123,27 +123,27 @@ var Scroller = function ( dt, opts ) {
|
|
123
123
|
* @type object
|
124
124
|
* @default Passed in as first parameter to constructor
|
125
125
|
*/
|
126
|
-
|
126
|
+
dt: dtApi.settings()[0],
|
127
127
|
|
128
128
|
/**
|
129
129
|
* DataTables API instance
|
130
130
|
* @type DataTable.Api
|
131
131
|
*/
|
132
|
-
|
132
|
+
dtApi: dtApi,
|
133
133
|
|
134
134
|
/**
|
135
135
|
* Pixel location of the top of the drawn table in the viewport
|
136
136
|
* @type int
|
137
137
|
* @default 0
|
138
138
|
*/
|
139
|
-
|
139
|
+
tableTop: 0,
|
140
140
|
|
141
141
|
/**
|
142
142
|
* Pixel location of the bottom of the drawn table in the viewport
|
143
143
|
* @type int
|
144
144
|
* @default 0
|
145
145
|
*/
|
146
|
-
|
146
|
+
tableBottom: 0,
|
147
147
|
|
148
148
|
/**
|
149
149
|
* Pixel location of the boundary for when the next data set should be loaded and drawn
|
@@ -152,7 +152,7 @@ var Scroller = function ( dt, opts ) {
|
|
152
152
|
* @default 0
|
153
153
|
* @private
|
154
154
|
*/
|
155
|
-
|
155
|
+
redrawTop: 0,
|
156
156
|
|
157
157
|
/**
|
158
158
|
* Pixel location of the boundary for when the next data set should be loaded and drawn
|
@@ -162,21 +162,21 @@ var Scroller = function ( dt, opts ) {
|
|
162
162
|
* @default 0
|
163
163
|
* @private
|
164
164
|
*/
|
165
|
-
|
165
|
+
redrawBottom: 0,
|
166
166
|
|
167
167
|
/**
|
168
168
|
* Auto row height or not indicator
|
169
169
|
* @type bool
|
170
170
|
* @default 0
|
171
171
|
*/
|
172
|
-
|
172
|
+
autoHeight: true,
|
173
173
|
|
174
174
|
/**
|
175
175
|
* Number of rows calculated as visible in the visible viewport
|
176
176
|
* @type int
|
177
177
|
* @default 0
|
178
178
|
*/
|
179
|
-
|
179
|
+
viewportRows: 0,
|
180
180
|
|
181
181
|
/**
|
182
182
|
* setTimeout reference for state saving, used when state saving is enabled in the DataTable
|
@@ -185,7 +185,7 @@ var Scroller = function ( dt, opts ) {
|
|
185
185
|
* @type int
|
186
186
|
* @default 0
|
187
187
|
*/
|
188
|
-
|
188
|
+
stateTO: null,
|
189
189
|
|
190
190
|
/**
|
191
191
|
* setTimeout reference for the redraw, used when server-side processing is enabled in the
|
@@ -193,7 +193,7 @@ var Scroller = function ( dt, opts ) {
|
|
193
193
|
* @type int
|
194
194
|
* @default null
|
195
195
|
*/
|
196
|
-
|
196
|
+
drawTO: null,
|
197
197
|
|
198
198
|
heights: {
|
199
199
|
jump: null,
|
@@ -213,13 +213,18 @@ var Scroller = function ( dt, opts ) {
|
|
213
213
|
* @type int
|
214
214
|
* @default 0
|
215
215
|
*/
|
216
|
-
viewport: null
|
216
|
+
viewport: null,
|
217
|
+
labelFactor: 1
|
217
218
|
},
|
218
219
|
|
219
220
|
topRowFloat: 0,
|
220
221
|
scrollDrawDiff: null,
|
221
222
|
loaderVisible: false,
|
222
|
-
forceReposition: false
|
223
|
+
forceReposition: false,
|
224
|
+
baseRowTop: 0,
|
225
|
+
baseScrollTop: 0,
|
226
|
+
mousedown: false,
|
227
|
+
lastScrollTop: 0
|
223
228
|
};
|
224
229
|
|
225
230
|
// @todo The defaults should extend a `c` property and the internal settings
|
@@ -237,6 +242,7 @@ var Scroller = function ( dt, opts ) {
|
|
237
242
|
*/
|
238
243
|
this.dom = {
|
239
244
|
"force": document.createElement('div'),
|
245
|
+
"label": $('<div class="dts_label">0</div>'),
|
240
246
|
"scroller": null,
|
241
247
|
"table": null,
|
242
248
|
"loader": null
|
@@ -251,54 +257,80 @@ var Scroller = function ( dt, opts ) {
|
|
251
257
|
this.s.dt.oScroller = this;
|
252
258
|
|
253
259
|
/* Let's do it */
|
254
|
-
this.
|
260
|
+
this.construct();
|
255
261
|
};
|
256
262
|
|
257
263
|
|
258
264
|
|
259
265
|
$.extend( Scroller.prototype, {
|
260
266
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
261
|
-
* Public methods
|
262
|
-
|
267
|
+
* Public methods - to be exposed via the DataTables API
|
268
|
+
*/
|
263
269
|
|
264
270
|
/**
|
265
|
-
* Calculate
|
266
|
-
*
|
267
|
-
*
|
268
|
-
*
|
269
|
-
* @
|
270
|
-
*
|
271
|
-
*
|
272
|
-
* "sScrollY": "200px",
|
273
|
-
* "sAjaxSource": "media/dataset/large.txt",
|
274
|
-
* "sDom": "frtiS",
|
275
|
-
* "bDeferRender": true,
|
276
|
-
* "fnInitComplete": function (o) {
|
277
|
-
* // Find where row 25 is
|
278
|
-
* alert( o.oScroller.fnRowToPixels( 25 ) );
|
279
|
-
* }
|
280
|
-
* } );
|
281
|
-
* } );
|
271
|
+
* Calculate and store information about how many rows are to be displayed
|
272
|
+
* in the scrolling viewport, based on current dimensions in the browser's
|
273
|
+
* rendering. This can be particularly useful if the table is initially
|
274
|
+
* drawn in a hidden element - for example in a tab.
|
275
|
+
* @param {bool} [redraw=true] Redraw the table automatically after the recalculation, with
|
276
|
+
* the new dimensions forming the basis for the draw.
|
277
|
+
* @returns {void}
|
282
278
|
*/
|
283
|
-
|
279
|
+
measure: function ( redraw )
|
284
280
|
{
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
if ( virtual ) {
|
289
|
-
pixels = this._domain( 'virtualToPhysical', this.s.baseScrollTop );
|
290
|
-
pixels += diff * this.s.heights.row;
|
281
|
+
if ( this.s.autoHeight )
|
282
|
+
{
|
283
|
+
this._calcRowHeight();
|
291
284
|
}
|
292
|
-
|
293
|
-
|
294
|
-
|
285
|
+
|
286
|
+
var heights = this.s.heights;
|
287
|
+
|
288
|
+
if ( heights.row ) {
|
289
|
+
heights.viewport = $.contains(document, this.dom.scroller) ?
|
290
|
+
this.dom.scroller.clientHeight :
|
291
|
+
this._parseHeight($(this.dom.scroller).css('height'));
|
292
|
+
|
293
|
+
// If collapsed (no height) use the max-height parameter
|
294
|
+
if ( ! heights.viewport ) {
|
295
|
+
heights.viewport = this._parseHeight($(this.dom.scroller).css('max-height'));
|
296
|
+
}
|
297
|
+
|
298
|
+
this.s.viewportRows = parseInt( heights.viewport / heights.row, 10 )+1;
|
299
|
+
this.s.dt._iDisplayLength = this.s.viewportRows * this.s.displayBuffer;
|
295
300
|
}
|
296
301
|
|
297
|
-
|
298
|
-
|
299
|
-
|
302
|
+
var label = this.dom.label.outerHeight();
|
303
|
+
heights.labelFactor = (heights.viewport-label) / heights.scroll;
|
304
|
+
|
305
|
+
if ( redraw === undefined || redraw )
|
306
|
+
{
|
307
|
+
this.s.dt.oInstance.fnDraw( false );
|
308
|
+
}
|
300
309
|
},
|
301
310
|
|
311
|
+
/**
|
312
|
+
* Get information about current displayed record range. This corresponds to
|
313
|
+
* the information usually displayed in the "Info" block of the table.
|
314
|
+
*
|
315
|
+
* @returns {object} info as an object:
|
316
|
+
* {
|
317
|
+
* start: {int}, // the 0-indexed record at the top of the viewport
|
318
|
+
* end: {int}, // the 0-indexed record at the bottom of the viewport
|
319
|
+
* }
|
320
|
+
*/
|
321
|
+
pageInfo: function()
|
322
|
+
{
|
323
|
+
var
|
324
|
+
dt = this.s.dt,
|
325
|
+
iScrollTop = this.dom.scroller.scrollTop,
|
326
|
+
iTotal = dt.fnRecordsDisplay(),
|
327
|
+
iPossibleEnd = Math.ceil(this.pixelsToRow(iScrollTop + this.s.heights.viewport, false, this.s.ani));
|
328
|
+
|
329
|
+
return {
|
330
|
+
start: Math.floor(this.pixelsToRow(iScrollTop, false, this.s.ani)),
|
331
|
+
end: iTotal < iPossibleEnd ? iTotal-1 : iPossibleEnd-1
|
332
|
+
};
|
333
|
+
},
|
302
334
|
|
303
335
|
/**
|
304
336
|
* Calculate the row number that will be found at the given pixel position
|
@@ -308,25 +340,12 @@ $.extend( Scroller.prototype, {
|
|
308
340
|
* pixels, Scroller switches into a non-linear mode for the scrollbar to fit
|
309
341
|
* all of the records into a finite area, but this function returns a linear
|
310
342
|
* value (relative to the last non-linear positioning).
|
311
|
-
* @param {int}
|
343
|
+
* @param {int} pixels Offset from top to calculate the row number of
|
312
344
|
* @param {int} [intParse=true] If an integer value should be returned
|
313
345
|
* @param {int} [virtual=false] Perform the calculations in the virtual domain
|
314
346
|
* @returns {int} Row index
|
315
|
-
* @example
|
316
|
-
* $(document).ready(function() {
|
317
|
-
* $('#example').dataTable( {
|
318
|
-
* "sScrollY": "200px",
|
319
|
-
* "sAjaxSource": "media/dataset/large.txt",
|
320
|
-
* "sDom": "frtiS",
|
321
|
-
* "bDeferRender": true,
|
322
|
-
* "fnInitComplete": function (o) {
|
323
|
-
* // Find what row number is at 500px
|
324
|
-
* alert( o.oScroller.fnPixelsToRow( 500 ) );
|
325
|
-
* }
|
326
|
-
* } );
|
327
|
-
* } );
|
328
347
|
*/
|
329
|
-
|
348
|
+
pixelsToRow: function ( pixels, intParse, virtual )
|
330
349
|
{
|
331
350
|
var diff = pixels - this.s.baseScrollTop;
|
332
351
|
var row = virtual ?
|
@@ -338,35 +357,43 @@ $.extend( Scroller.prototype, {
|
|
338
357
|
row;
|
339
358
|
},
|
340
359
|
|
360
|
+
/**
|
361
|
+
* Calculate the pixel position from the top of the scrolling container for
|
362
|
+
* a given row
|
363
|
+
* @param {int} iRow Row number to calculate the position of
|
364
|
+
* @returns {int} Pixels
|
365
|
+
*/
|
366
|
+
rowToPixels: function ( rowIdx, intParse, virtual )
|
367
|
+
{
|
368
|
+
var pixels;
|
369
|
+
var diff = rowIdx - this.s.baseRowTop;
|
370
|
+
|
371
|
+
if ( virtual ) {
|
372
|
+
pixels = this._domain( 'virtualToPhysical', this.s.baseScrollTop );
|
373
|
+
pixels += diff * this.s.heights.row;
|
374
|
+
}
|
375
|
+
else {
|
376
|
+
pixels = this.s.baseScrollTop;
|
377
|
+
pixels += diff * this.s.heights.row;
|
378
|
+
}
|
379
|
+
|
380
|
+
return intParse || intParse === undefined ?
|
381
|
+
parseInt( pixels, 10 ) :
|
382
|
+
pixels;
|
383
|
+
},
|
384
|
+
|
341
385
|
|
342
386
|
/**
|
343
387
|
* Calculate the row number that will be found at the given pixel position (y-scroll)
|
344
|
-
* @param {int}
|
345
|
-
* @param {bool} [
|
388
|
+
* @param {int} row Row index to scroll to
|
389
|
+
* @param {bool} [animate=true] Animate the transition or not
|
346
390
|
* @returns {void}
|
347
|
-
* @example
|
348
|
-
* $(document).ready(function() {
|
349
|
-
* $('#example').dataTable( {
|
350
|
-
* "sScrollY": "200px",
|
351
|
-
* "sAjaxSource": "media/dataset/large.txt",
|
352
|
-
* "sDom": "frtiS",
|
353
|
-
* "bDeferRender": true,
|
354
|
-
* "fnInitComplete": function (o) {
|
355
|
-
* // Immediately scroll to row 1000
|
356
|
-
* o.oScroller.fnScrollToRow( 1000 );
|
357
|
-
* }
|
358
|
-
* } );
|
359
|
-
*
|
360
|
-
* // Sometime later on use the following to scroll to row 500...
|
361
|
-
* var oSettings = $('#example').dataTable().fnSettings();
|
362
|
-
* oSettings.oScroller.fnScrollToRow( 500 );
|
363
|
-
* } );
|
364
391
|
*/
|
365
|
-
|
392
|
+
scrollToRow: function ( row, animate )
|
366
393
|
{
|
367
394
|
var that = this;
|
368
395
|
var ani = false;
|
369
|
-
var px = this.
|
396
|
+
var px = this.rowToPixels( row );
|
370
397
|
|
371
398
|
// We need to know if the table will redraw or not before doing the
|
372
399
|
// scroll. If it will not redraw, then we need to use the currently
|
@@ -374,25 +401,25 @@ $.extend( Scroller.prototype, {
|
|
374
401
|
// need to calculate the table's new position from the virtual
|
375
402
|
// transform.
|
376
403
|
var preRows = ((this.s.displayBuffer-1)/2) * this.s.viewportRows;
|
377
|
-
var drawRow =
|
404
|
+
var drawRow = row - preRows;
|
378
405
|
if ( drawRow < 0 ) {
|
379
406
|
drawRow = 0;
|
380
407
|
}
|
381
408
|
|
382
409
|
if ( (px > this.s.redrawBottom || px < this.s.redrawTop) && this.s.dt._iDisplayStart !== drawRow ) {
|
383
410
|
ani = true;
|
384
|
-
px = this._domain( 'virtualToPhysical',
|
411
|
+
px = this._domain( 'virtualToPhysical', row * this.s.heights.row );
|
385
412
|
|
386
413
|
// If we need records outside the current draw region, but the new
|
387
414
|
// scrolling position is inside that (due to the non-linear nature
|
388
415
|
// for larger numbers of records), we need to force position update.
|
389
416
|
if ( this.s.redrawTop < px && px < this.s.redrawBottom ) {
|
390
417
|
this.s.forceReposition = true;
|
391
|
-
|
418
|
+
animate = false;
|
392
419
|
}
|
393
420
|
}
|
394
421
|
|
395
|
-
if (
|
422
|
+
if ( animate === undefined || animate )
|
396
423
|
{
|
397
424
|
this.s.ani = ani;
|
398
425
|
$(this.dom.scroller).animate( {
|
@@ -402,7 +429,7 @@ $.extend( Scroller.prototype, {
|
|
402
429
|
// the final scroll event fired
|
403
430
|
setTimeout( function () {
|
404
431
|
that.s.ani = false;
|
405
|
-
},
|
432
|
+
}, 250 );
|
406
433
|
} );
|
407
434
|
}
|
408
435
|
else
|
@@ -412,100 +439,16 @@ $.extend( Scroller.prototype, {
|
|
412
439
|
},
|
413
440
|
|
414
441
|
|
415
|
-
/**
|
416
|
-
* Calculate and store information about how many rows are to be displayed
|
417
|
-
* in the scrolling viewport, based on current dimensions in the browser's
|
418
|
-
* rendering. This can be particularly useful if the table is initially
|
419
|
-
* drawn in a hidden element - for example in a tab.
|
420
|
-
* @param {bool} [bRedraw=true] Redraw the table automatically after the recalculation, with
|
421
|
-
* the new dimensions forming the basis for the draw.
|
422
|
-
* @returns {void}
|
423
|
-
* @example
|
424
|
-
* $(document).ready(function() {
|
425
|
-
* // Make the example container hidden to throw off the browser's sizing
|
426
|
-
* document.getElementById('container').style.display = "none";
|
427
|
-
* var oTable = $('#example').dataTable( {
|
428
|
-
* "sScrollY": "200px",
|
429
|
-
* "sAjaxSource": "media/dataset/large.txt",
|
430
|
-
* "sDom": "frtiS",
|
431
|
-
* "bDeferRender": true,
|
432
|
-
* "fnInitComplete": function (o) {
|
433
|
-
* // Immediately scroll to row 1000
|
434
|
-
* o.oScroller.fnScrollToRow( 1000 );
|
435
|
-
* }
|
436
|
-
* } );
|
437
|
-
*
|
438
|
-
* setTimeout( function () {
|
439
|
-
* // Make the example container visible and recalculate the scroller sizes
|
440
|
-
* document.getElementById('container').style.display = "block";
|
441
|
-
* oTable.fnSettings().oScroller.fnMeasure();
|
442
|
-
* }, 3000 );
|
443
|
-
*/
|
444
|
-
"fnMeasure": function ( bRedraw )
|
445
|
-
{
|
446
|
-
if ( this.s.autoHeight )
|
447
|
-
{
|
448
|
-
this._fnCalcRowHeight();
|
449
|
-
}
|
450
|
-
|
451
|
-
var heights = this.s.heights;
|
452
|
-
|
453
|
-
if ( heights.row ) {
|
454
|
-
heights.viewport = $.contains(document, this.dom.scroller) ?
|
455
|
-
$(this.dom.scroller).height() :
|
456
|
-
this._parseHeight($(this.dom.scroller).css('height'));
|
457
|
-
|
458
|
-
// If collapsed (no height) use the max-height parameter
|
459
|
-
if ( ! heights.viewport ) {
|
460
|
-
heights.viewport = this._parseHeight($(this.dom.scroller).css('max-height'));
|
461
|
-
}
|
462
|
-
|
463
|
-
this.s.viewportRows = parseInt( heights.viewport / heights.row, 10 )+1;
|
464
|
-
this.s.dt._iDisplayLength = this.s.viewportRows * this.s.displayBuffer;
|
465
|
-
}
|
466
|
-
|
467
|
-
if ( bRedraw === undefined || bRedraw )
|
468
|
-
{
|
469
|
-
this.s.dt.oInstance.fnDraw( false );
|
470
|
-
}
|
471
|
-
},
|
472
|
-
|
473
|
-
|
474
|
-
/**
|
475
|
-
* Get information about current displayed record range. This corresponds to
|
476
|
-
* the information usually displayed in the "Info" block of the table.
|
477
|
-
*
|
478
|
-
* @returns {object} info as an object:
|
479
|
-
* {
|
480
|
-
* start: {int}, // the 0-indexed record at the top of the viewport
|
481
|
-
* end: {int}, // the 0-indexed record at the bottom of the viewport
|
482
|
-
* }
|
483
|
-
*/
|
484
|
-
"fnPageInfo": function()
|
485
|
-
{
|
486
|
-
var
|
487
|
-
dt = this.s.dt,
|
488
|
-
iScrollTop = this.dom.scroller.scrollTop,
|
489
|
-
iTotal = dt.fnRecordsDisplay(),
|
490
|
-
iPossibleEnd = Math.ceil(this.fnPixelsToRow(iScrollTop + this.s.heights.viewport, false, this.s.ani));
|
491
|
-
|
492
|
-
return {
|
493
|
-
start: Math.floor(this.fnPixelsToRow(iScrollTop, false, this.s.ani)),
|
494
|
-
end: iTotal < iPossibleEnd ? iTotal-1 : iPossibleEnd-1
|
495
|
-
};
|
496
|
-
},
|
497
|
-
|
498
|
-
|
499
442
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
500
|
-
*
|
501
|
-
|
443
|
+
* Constructor
|
444
|
+
*/
|
502
445
|
|
503
446
|
/**
|
504
447
|
* Initialisation for Scroller
|
505
448
|
* @returns {void}
|
506
449
|
* @private
|
507
450
|
*/
|
508
|
-
|
451
|
+
construct: function ()
|
509
452
|
{
|
510
453
|
var that = this;
|
511
454
|
var dt = this.s.dtApi;
|
@@ -534,12 +477,12 @@ $.extend( Scroller.prototype, {
|
|
534
477
|
this.dom.table.style.left = "0px";
|
535
478
|
|
536
479
|
// Add class to 'announce' that we are a Scroller table
|
537
|
-
$(dt.table().container()).addClass('DTS');
|
480
|
+
$(dt.table().container()).addClass('dts DTS');
|
538
481
|
|
539
482
|
// Add a 'loading' indicator
|
540
483
|
if ( this.s.loadingIndicator )
|
541
484
|
{
|
542
|
-
this.dom.loader = $('<div class="dataTables_processing
|
485
|
+
this.dom.loader = $('<div class="dataTables_processing dts_loading">'+this.s.dt.oLanguage.sLoadingRecords+'</div>')
|
543
486
|
.css('display', 'none');
|
544
487
|
|
545
488
|
$(this.dom.scroller.parentNode)
|
@@ -547,12 +490,14 @@ $.extend( Scroller.prototype, {
|
|
547
490
|
.append( this.dom.loader );
|
548
491
|
}
|
549
492
|
|
493
|
+
this.dom.label.appendTo(this.dom.scroller);
|
494
|
+
|
550
495
|
/* Initial size calculations */
|
551
496
|
if ( this.s.heights.row && this.s.heights.row != 'auto' )
|
552
497
|
{
|
553
498
|
this.s.autoHeight = false;
|
554
499
|
}
|
555
|
-
this.
|
500
|
+
this.measure( false );
|
556
501
|
|
557
502
|
// Scrolling callback to see if a page change is needed - use a throttled
|
558
503
|
// function for the save save callback so we aren't hitting it on every
|
@@ -562,19 +507,28 @@ $.extend( Scroller.prototype, {
|
|
562
507
|
that.s.dtApi.state.save();
|
563
508
|
}, 500 );
|
564
509
|
$(this.dom.scroller).on( 'scroll.dt-scroller', function (e) {
|
565
|
-
that.
|
510
|
+
that._scroll.call( that );
|
566
511
|
} );
|
567
512
|
|
568
513
|
// In iOS we catch the touchstart event in case the user tries to scroll
|
569
514
|
// while the display is already scrolling
|
570
515
|
$(this.dom.scroller).on('touchstart.dt-scroller', function () {
|
571
|
-
that.
|
516
|
+
that._scroll.call( that );
|
572
517
|
} );
|
573
518
|
|
519
|
+
$(this.dom.scroller)
|
520
|
+
.on('mousedown.dt-scroller', function () {
|
521
|
+
that.s.mousedown = true;
|
522
|
+
})
|
523
|
+
.on('mouseup.dt-scroller', function () {
|
524
|
+
that.s.mouseup = false;
|
525
|
+
that.dom.label.css('display', 'none');
|
526
|
+
});
|
527
|
+
|
574
528
|
// On resize, update the information element, since the number of rows shown might change
|
575
529
|
$(window).on( 'resize.dt-scroller', function () {
|
576
|
-
that.
|
577
|
-
that.
|
530
|
+
that.measure( false );
|
531
|
+
that._info();
|
578
532
|
} );
|
579
533
|
|
580
534
|
// Add a state saving parameter to the DT state saving so we can restore the exact
|
@@ -604,20 +558,23 @@ $.extend( Scroller.prototype, {
|
|
604
558
|
}
|
605
559
|
|
606
560
|
dt.on( 'init.scroller', function () {
|
607
|
-
that.
|
561
|
+
that.measure( false );
|
608
562
|
|
609
|
-
|
563
|
+
// Setting to `jump` will instruct _draw to calculate the scroll top
|
564
|
+
// position
|
565
|
+
that.s.scrollType = 'jump';
|
566
|
+
that._draw();
|
610
567
|
|
611
568
|
// Update the scroller when the DataTable is redrawn
|
612
569
|
dt.on( 'draw.scroller', function () {
|
613
|
-
that.
|
570
|
+
that._draw();
|
614
571
|
});
|
615
572
|
} );
|
616
573
|
|
617
574
|
// Set height before the draw happens, allowing everything else to update
|
618
575
|
// on draw complete without worry for roder.
|
619
576
|
dt.on( 'preDraw.dt.scroller', function () {
|
620
|
-
that.
|
577
|
+
that._scrollForce();
|
621
578
|
} );
|
622
579
|
|
623
580
|
// Destructor
|
@@ -636,280 +593,111 @@ $.extend( Scroller.prototype, {
|
|
636
593
|
},
|
637
594
|
|
638
595
|
|
596
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
597
|
+
* Private methods
|
598
|
+
*/
|
599
|
+
|
639
600
|
/**
|
640
|
-
*
|
641
|
-
*
|
642
|
-
*
|
643
|
-
*
|
644
|
-
*
|
601
|
+
* Automatic calculation of table row height. This is just a little tricky here as using
|
602
|
+
* initialisation DataTables has tale the table out of the document, so we need to create
|
603
|
+
* a new table and insert it into the document, calculate the row height and then whip the
|
604
|
+
* table out.
|
605
|
+
* @returns {void}
|
606
|
+
* @private
|
607
|
+
*/
|
608
|
+
_calcRowHeight: function ()
|
609
|
+
{
|
610
|
+
var dt = this.s.dt;
|
611
|
+
var origTable = dt.nTable;
|
612
|
+
var nTable = origTable.cloneNode( false );
|
613
|
+
var tbody = $('<tbody/>').appendTo( nTable );
|
614
|
+
var container = $(
|
615
|
+
'<div class="'+dt.oClasses.sWrapper+' DTS">'+
|
616
|
+
'<div class="'+dt.oClasses.sScrollWrapper+'">'+
|
617
|
+
'<div class="'+dt.oClasses.sScrollBody+'"></div>'+
|
618
|
+
'</div>'+
|
619
|
+
'</div>'
|
620
|
+
);
|
621
|
+
|
622
|
+
// Want 3 rows in the sizing table so :first-child and :last-child
|
623
|
+
// CSS styles don't come into play - take the size of the middle row
|
624
|
+
$('tbody tr:lt(4)', origTable).clone().appendTo( tbody );
|
625
|
+
var rowsCount = $('tr', tbody).length;
|
626
|
+
|
627
|
+
if ( rowsCount === 1 ) {
|
628
|
+
tbody.prepend('<tr><td> </td></tr>');
|
629
|
+
tbody.append('<tr><td> </td></tr>');
|
630
|
+
}
|
631
|
+
else {
|
632
|
+
for (; rowsCount < 3; rowsCount++) {
|
633
|
+
tbody.append('<tr><td> </td></tr>');
|
634
|
+
}
|
635
|
+
}
|
636
|
+
|
637
|
+
$('div.'+dt.oClasses.sScrollBody, container).append( nTable );
|
638
|
+
|
639
|
+
// If initialised using `dom`, use the holding element as the insert point
|
640
|
+
var insertEl = this.s.dt.nHolding || origTable.parentNode;
|
641
|
+
|
642
|
+
if ( ! $(insertEl).is(':visible') ) {
|
643
|
+
insertEl = 'body';
|
644
|
+
}
|
645
|
+
|
646
|
+
container.appendTo( insertEl );
|
647
|
+
this.s.heights.row = $('tr', tbody).eq(1).outerHeight();
|
648
|
+
|
649
|
+
container.remove();
|
650
|
+
},
|
651
|
+
|
652
|
+
/**
|
653
|
+
* Draw callback function which is fired when the DataTable is redrawn. The main function of
|
654
|
+
* this method is to position the drawn table correctly the scrolling container for the rows
|
655
|
+
* that is displays as a result of the scrolling position.
|
645
656
|
* @returns {void}
|
646
657
|
* @private
|
647
658
|
*/
|
648
|
-
|
659
|
+
_draw: function ()
|
649
660
|
{
|
650
661
|
var
|
651
662
|
that = this,
|
652
663
|
heights = this.s.heights,
|
653
664
|
iScrollTop = this.dom.scroller.scrollTop,
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
}
|
665
|
+
iTableHeight = $(this.s.dt.nTable).height(),
|
666
|
+
displayStart = this.s.dt._iDisplayStart,
|
667
|
+
displayLen = this.s.dt._iDisplayLength,
|
668
|
+
displayEnd = this.s.dt.fnRecordsDisplay();
|
659
669
|
|
660
|
-
|
661
|
-
|
662
|
-
}
|
670
|
+
// Disable the scroll event listener while we are updating the DOM
|
671
|
+
this.s.skip = true;
|
663
672
|
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
if ( this.s.dt.bFiltered || this.s.dt.bSorted ) {
|
668
|
-
this.s.lastScrollTop = 0;
|
669
|
-
return;
|
673
|
+
// If paging is reset
|
674
|
+
if ( (this.s.dt.bSorted || this.s.dt.bFiltered) && displayStart === 0 && !this.s.dt._drawHold ) {
|
675
|
+
this.s.topRowFloat = 0;
|
670
676
|
}
|
671
677
|
|
672
|
-
|
673
|
-
|
678
|
+
iScrollTop = this.s.scrollType === 'jump' ?
|
679
|
+
this._domain( 'virtualToPhysical', this.s.topRowFloat * heights.row ) :
|
680
|
+
iScrollTop;
|
674
681
|
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
clearTimeout( this.s.stateTO );
|
680
|
-
this.s.stateTO = setTimeout( function () {
|
681
|
-
that.s.dtApi.state.save();
|
682
|
-
}, 250 );
|
682
|
+
// Store positional information so positional calculations can be based
|
683
|
+
// upon the current table draw position
|
684
|
+
this.s.baseScrollTop = iScrollTop;
|
685
|
+
this.s.baseRowTop = this.s.topRowFloat;
|
683
686
|
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
687
|
+
// Position the table in the virtual scroller
|
688
|
+
var tableTop = iScrollTop - ((this.s.topRowFloat - displayStart) * heights.row);
|
689
|
+
if ( displayStart === 0 ) {
|
690
|
+
tableTop = 0;
|
691
|
+
}
|
692
|
+
else if ( displayStart + displayLen >= displayEnd ) {
|
693
|
+
tableTop = heights.scroll - iTableHeight;
|
694
|
+
}
|
688
695
|
|
689
|
-
|
696
|
+
this.dom.table.style.top = tableTop+'px';
|
690
697
|
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
if ( iTopRow <= 0 ) {
|
696
|
-
/* At the start of the table */
|
697
|
-
iTopRow = 0;
|
698
|
-
}
|
699
|
-
else if ( iTopRow + this.s.dt._iDisplayLength > this.s.dt.fnRecordsDisplay() ) {
|
700
|
-
/* At the end of the table */
|
701
|
-
iTopRow = this.s.dt.fnRecordsDisplay() - this.s.dt._iDisplayLength;
|
702
|
-
if ( iTopRow < 0 ) {
|
703
|
-
iTopRow = 0;
|
704
|
-
}
|
705
|
-
}
|
706
|
-
else if ( iTopRow % 2 !== 0 ) {
|
707
|
-
// For the row-striping classes (odd/even) we want only to start
|
708
|
-
// on evens otherwise the stripes will change between draws and
|
709
|
-
// look rubbish
|
710
|
-
iTopRow++;
|
711
|
-
}
|
712
|
-
|
713
|
-
if ( iTopRow != this.s.dt._iDisplayStart ) {
|
714
|
-
/* Cache the new table position for quick lookups */
|
715
|
-
this.s.tableTop = $(this.s.dt.nTable).offset().top;
|
716
|
-
this.s.tableBottom = $(this.s.dt.nTable).height() + this.s.tableTop;
|
717
|
-
|
718
|
-
var draw = function () {
|
719
|
-
if ( that.s.scrollDrawReq === null ) {
|
720
|
-
that.s.scrollDrawReq = iScrollTop;
|
721
|
-
}
|
722
|
-
|
723
|
-
that.s.dt._iDisplayStart = iTopRow;
|
724
|
-
that.s.dt.oApi._fnDraw( that.s.dt );
|
725
|
-
};
|
726
|
-
|
727
|
-
/* Do the DataTables redraw based on the calculated start point - note that when
|
728
|
-
* using server-side processing we introduce a small delay to not DoS the server...
|
729
|
-
*/
|
730
|
-
if ( this.s.dt.oFeatures.bServerSide ) {
|
731
|
-
clearTimeout( this.s.drawTO );
|
732
|
-
this.s.drawTO = setTimeout( draw, this.s.serverWait );
|
733
|
-
}
|
734
|
-
else {
|
735
|
-
draw();
|
736
|
-
}
|
737
|
-
|
738
|
-
if ( this.dom.loader && ! this.s.loaderVisible ) {
|
739
|
-
this.dom.loader.css( 'display', 'block' );
|
740
|
-
this.s.loaderVisible = true;
|
741
|
-
}
|
742
|
-
}
|
743
|
-
}
|
744
|
-
else {
|
745
|
-
this.s.topRowFloat = this.fnPixelsToRow( iScrollTop, false, true );
|
746
|
-
}
|
747
|
-
|
748
|
-
this.s.lastScrollTop = iScrollTop;
|
749
|
-
this.s.stateSaveThrottle();
|
750
|
-
},
|
751
|
-
|
752
|
-
|
753
|
-
/**
|
754
|
-
* Convert from one domain to another. The physical domain is the actual
|
755
|
-
* pixel count on the screen, while the virtual is if we had browsers which
|
756
|
-
* had scrolling containers of infinite height (i.e. the absolute value)
|
757
|
-
*
|
758
|
-
* @param {string} dir Domain transform direction, `virtualToPhysical` or
|
759
|
-
* `physicalToVirtual`
|
760
|
-
* @returns {number} Calculated transform
|
761
|
-
* @private
|
762
|
-
*/
|
763
|
-
_domain: function ( dir, val )
|
764
|
-
{
|
765
|
-
var heights = this.s.heights;
|
766
|
-
var coeff;
|
767
|
-
|
768
|
-
// If the virtual and physical height match, then we use a linear
|
769
|
-
// transform between the two, allowing the scrollbar to be linear
|
770
|
-
if ( heights.virtual === heights.scroll ) {
|
771
|
-
return val;
|
772
|
-
}
|
773
|
-
|
774
|
-
// Otherwise, we want a non-linear scrollbar to take account of the
|
775
|
-
// redrawing regions at the start and end of the table, otherwise these
|
776
|
-
// can stutter badly - on large tables 30px (for example) scroll might
|
777
|
-
// be hundreds of rows, so the table would be redrawing every few px at
|
778
|
-
// the start and end. Use a simple quadratic to stop this. It does mean
|
779
|
-
// the scrollbar is non-linear, but with such massive data sets, the
|
780
|
-
// scrollbar is going to be a best guess anyway
|
781
|
-
var xMax = (heights.scroll - heights.viewport) / 2;
|
782
|
-
var yMax = (heights.virtual - heights.viewport) / 2;
|
783
|
-
|
784
|
-
coeff = yMax / ( xMax * xMax );
|
785
|
-
|
786
|
-
if ( dir === 'virtualToPhysical' ) {
|
787
|
-
if ( val < yMax ) {
|
788
|
-
return Math.pow(val / coeff, 0.5);
|
789
|
-
}
|
790
|
-
else {
|
791
|
-
val = (yMax*2) - val;
|
792
|
-
return val < 0 ?
|
793
|
-
heights.scroll :
|
794
|
-
(xMax*2) - Math.pow(val / coeff, 0.5);
|
795
|
-
}
|
796
|
-
}
|
797
|
-
else if ( dir === 'physicalToVirtual' ) {
|
798
|
-
if ( val < xMax ) {
|
799
|
-
return val * val * coeff;
|
800
|
-
}
|
801
|
-
else {
|
802
|
-
val = (xMax*2) - val;
|
803
|
-
return val < 0 ?
|
804
|
-
heights.virtual :
|
805
|
-
(yMax*2) - (val * val * coeff);
|
806
|
-
}
|
807
|
-
}
|
808
|
-
},
|
809
|
-
|
810
|
-
/**
|
811
|
-
* Parse CSS height property string as number
|
812
|
-
*
|
813
|
-
* An attempt is made to parse the string as a number. Currently supported units are 'px',
|
814
|
-
* 'vh', and 'rem'. 'em' is partially supported; it works as long as the parent element's
|
815
|
-
* font size matches the body element. Zero is returned for unrecognized strings.
|
816
|
-
* @param {string} cssHeight CSS height property string
|
817
|
-
* @returns {number} height
|
818
|
-
* @private
|
819
|
-
*/
|
820
|
-
_parseHeight: function(cssHeight) {
|
821
|
-
var height;
|
822
|
-
var matches = /^([+-]?(?:\d+(?:\.\d+)?|\.\d+))(px|em|rem|vh)$/.exec(cssHeight);
|
823
|
-
|
824
|
-
if (matches === null) {
|
825
|
-
return 0;
|
826
|
-
}
|
827
|
-
|
828
|
-
var value = parseFloat(matches[1]);
|
829
|
-
var unit = matches[2];
|
830
|
-
|
831
|
-
if ( unit === 'px' ) {
|
832
|
-
height = value;
|
833
|
-
}
|
834
|
-
else if ( unit === 'vh' ) {
|
835
|
-
height = ( value / 100 ) * $(window).height();
|
836
|
-
}
|
837
|
-
else if ( unit === 'rem' ) {
|
838
|
-
height = value * parseFloat($(':root').css('font-size'));
|
839
|
-
}
|
840
|
-
else if ( unit === 'em' ) {
|
841
|
-
height = value * parseFloat($('body').css('font-size'));
|
842
|
-
}
|
843
|
-
|
844
|
-
return height ?
|
845
|
-
height :
|
846
|
-
0;
|
847
|
-
},
|
848
|
-
|
849
|
-
|
850
|
-
/**
|
851
|
-
* Draw callback function which is fired when the DataTable is redrawn. The main function of
|
852
|
-
* this method is to position the drawn table correctly the scrolling container for the rows
|
853
|
-
* that is displays as a result of the scrolling position.
|
854
|
-
* @returns {void}
|
855
|
-
* @private
|
856
|
-
*/
|
857
|
-
"_fnDrawCallback": function ()
|
858
|
-
{
|
859
|
-
var
|
860
|
-
that = this,
|
861
|
-
heights = this.s.heights,
|
862
|
-
iScrollTop = this.dom.scroller.scrollTop,
|
863
|
-
iActualScrollTop = iScrollTop,
|
864
|
-
iScrollBottom = iScrollTop + heights.viewport,
|
865
|
-
iTableHeight = $(this.s.dt.nTable).height(),
|
866
|
-
displayStart = this.s.dt._iDisplayStart,
|
867
|
-
displayLen = this.s.dt._iDisplayLength,
|
868
|
-
displayEnd = this.s.dt.fnRecordsDisplay();
|
869
|
-
|
870
|
-
// Disable the scroll event listener while we are updating the DOM
|
871
|
-
this.s.skip = true;
|
872
|
-
|
873
|
-
// If paging is reset
|
874
|
-
if ( (this.s.dt.bSorted || this.s.dt.bFiltered) && displayStart === 0 ) {
|
875
|
-
this.s.topRowFloat = 0;
|
876
|
-
}
|
877
|
-
|
878
|
-
// Reposition the scrolling for the updated virtual position if needed
|
879
|
-
if ( displayStart === 0 ) {
|
880
|
-
// Linear calculation at the top of the table
|
881
|
-
iScrollTop = this.s.topRowFloat * heights.row;
|
882
|
-
}
|
883
|
-
else if ( displayStart + displayLen >= displayEnd ) {
|
884
|
-
// Linear calculation that the bottom as well
|
885
|
-
iScrollTop = heights.scroll - ((displayEnd - this.s.topRowFloat) * heights.row);
|
886
|
-
}
|
887
|
-
else {
|
888
|
-
// Domain scaled in the middle
|
889
|
-
iScrollTop = this._domain( 'virtualToPhysical', this.s.topRowFloat * heights.row );
|
890
|
-
}
|
891
|
-
|
892
|
-
this.dom.scroller.scrollTop = iScrollTop;
|
893
|
-
|
894
|
-
// Store positional information so positional calculations can be based
|
895
|
-
// upon the current table draw position
|
896
|
-
this.s.baseScrollTop = iScrollTop;
|
897
|
-
this.s.baseRowTop = this.s.topRowFloat;
|
898
|
-
|
899
|
-
// Position the table in the virtual scroller
|
900
|
-
var tableTop = iScrollTop - ((this.s.topRowFloat - displayStart) * heights.row);
|
901
|
-
if ( displayStart === 0 ) {
|
902
|
-
tableTop = 0;
|
903
|
-
}
|
904
|
-
else if ( displayStart + displayLen >= displayEnd ) {
|
905
|
-
tableTop = heights.scroll - iTableHeight;
|
906
|
-
}
|
907
|
-
|
908
|
-
this.dom.table.style.top = tableTop+'px';
|
909
|
-
|
910
|
-
/* Cache some information for the scroller */
|
911
|
-
this.s.tableTop = tableTop;
|
912
|
-
this.s.tableBottom = iTableHeight + this.s.tableTop;
|
698
|
+
/* Cache some information for the scroller */
|
699
|
+
this.s.tableTop = tableTop;
|
700
|
+
this.s.tableBottom = iTableHeight + this.s.tableTop;
|
913
701
|
|
914
702
|
// Calculate the boundaries for where a redraw will be triggered by the
|
915
703
|
// scroll event listener
|
@@ -957,7 +745,7 @@ $.extend( Scroller.prototype, {
|
|
957
745
|
// needed. Only add the thread break if bInfo is set
|
958
746
|
if ( this.s.dt.oFeatures.bInfo ) {
|
959
747
|
setTimeout( function () {
|
960
|
-
that.
|
748
|
+
that._info.call( that );
|
961
749
|
}, 0 );
|
962
750
|
}
|
963
751
|
|
@@ -968,83 +756,59 @@ $.extend( Scroller.prototype, {
|
|
968
756
|
}
|
969
757
|
},
|
970
758
|
|
971
|
-
|
972
759
|
/**
|
973
|
-
*
|
974
|
-
*
|
760
|
+
* Convert from one domain to another. The physical domain is the actual
|
761
|
+
* pixel count on the screen, while the virtual is if we had browsers which
|
762
|
+
* had scrolling containers of infinite height (i.e. the absolute value)
|
975
763
|
*
|
976
|
-
*
|
977
|
-
*
|
978
|
-
*
|
979
|
-
* be used to allow Scroller to display tables of any number of records.
|
980
|
-
* @returns {void}
|
764
|
+
* @param {string} dir Domain transform direction, `virtualToPhysical` or
|
765
|
+
* `physicalToVirtual`
|
766
|
+
* @returns {number} Calculated transform
|
981
767
|
* @private
|
982
768
|
*/
|
983
|
-
|
769
|
+
_domain: function ( dir, val )
|
984
770
|
{
|
985
771
|
var heights = this.s.heights;
|
986
|
-
var
|
772
|
+
var diff;
|
773
|
+
var magic = 10000; // the point at which the non-linear calculations start to happen
|
987
774
|
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
heights.scroll = max;
|
775
|
+
// If the virtual and physical height match, then we use a linear
|
776
|
+
// transform between the two, allowing the scrollbar to be linear
|
777
|
+
if ( heights.virtual === heights.scroll ) {
|
778
|
+
return val;
|
993
779
|
}
|
994
780
|
|
995
|
-
//
|
996
|
-
//
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
},
|
1001
|
-
|
1002
|
-
|
1003
|
-
/**
|
1004
|
-
* Automatic calculation of table row height. This is just a little tricky here as using
|
1005
|
-
* initialisation DataTables has tale the table out of the document, so we need to create
|
1006
|
-
* a new table and insert it into the document, calculate the row height and then whip the
|
1007
|
-
* table out.
|
1008
|
-
* @returns {void}
|
1009
|
-
* @private
|
1010
|
-
*/
|
1011
|
-
"_fnCalcRowHeight": function ()
|
1012
|
-
{
|
1013
|
-
var dt = this.s.dt;
|
1014
|
-
var origTable = dt.nTable;
|
1015
|
-
var nTable = origTable.cloneNode( false );
|
1016
|
-
var tbody = $('<tbody/>').appendTo( nTable );
|
1017
|
-
var container = $(
|
1018
|
-
'<div class="'+dt.oClasses.sWrapper+' DTS">'+
|
1019
|
-
'<div class="'+dt.oClasses.sScrollWrapper+'">'+
|
1020
|
-
'<div class="'+dt.oClasses.sScrollBody+'"></div>'+
|
1021
|
-
'</div>'+
|
1022
|
-
'</div>'
|
1023
|
-
);
|
1024
|
-
|
1025
|
-
// Want 3 rows in the sizing table so :first-child and :last-child
|
1026
|
-
// CSS styles don't come into play - take the size of the middle row
|
1027
|
-
$('tbody tr:lt(4)', origTable).clone().appendTo( tbody );
|
1028
|
-
while( $('tr', tbody).length < 3 ) {
|
1029
|
-
tbody.append( '<tr><td> </td></tr>' );
|
781
|
+
// In the first 10k pixels and the last 10k pixels, we want the scrolling
|
782
|
+
// to be linear. After that it can be non-linear. It would be unusual for
|
783
|
+
// anyone to mouse wheel through that much.
|
784
|
+
if ( val < magic ) {
|
785
|
+
return val;
|
1030
786
|
}
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
insertEl = 'body';
|
787
|
+
else if ( dir === 'virtualToPhysical' && val >= heights.virtual - magic ) {
|
788
|
+
diff = heights.virtual - val;
|
789
|
+
return heights.scroll - diff;
|
790
|
+
}
|
791
|
+
else if ( dir === 'physicalToVirtual' && val >= heights.scroll - magic ) {
|
792
|
+
diff = heights.scroll - val;
|
793
|
+
return heights.virtual - diff;
|
1039
794
|
}
|
1040
795
|
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
796
|
+
// Otherwise, we want a non-linear scrollbar to take account of the
|
797
|
+
// redrawing regions at the start and end of the table, otherwise these
|
798
|
+
// can stutter badly - on large tables 30px (for example) scroll might
|
799
|
+
// be hundreds of rows, so the table would be redrawing every few px at
|
800
|
+
// the start and end. Use a simple linear eq. to stop this, effectively
|
801
|
+
// causing a kink in the scrolling ratio. It does mean the scrollbar is
|
802
|
+
// non-linear, but with such massive data sets, the scrollbar is going
|
803
|
+
// to be a best guess anyway
|
804
|
+
var m = (heights.virtual - magic - magic) / (heights.scroll - magic - magic);
|
805
|
+
var c = magic - (m*magic);
|
806
|
+
|
807
|
+
return dir === 'virtualToPhysical' ?
|
808
|
+
(val-c) / m :
|
809
|
+
(m*val) + c;
|
1045
810
|
},
|
1046
811
|
|
1047
|
-
|
1048
812
|
/**
|
1049
813
|
* Update any information elements that are controlled by the DataTable based on the scrolling
|
1050
814
|
* viewport and what rows are visible in it. This function basically acts in the same way as
|
@@ -1052,7 +816,7 @@ $.extend( Scroller.prototype, {
|
|
1052
816
|
* @returns {void}
|
1053
817
|
* @private
|
1054
818
|
*/
|
1055
|
-
|
819
|
+
_info: function ()
|
1056
820
|
{
|
1057
821
|
if ( !this.s.dt.oFeatures.bInfo )
|
1058
822
|
{
|
@@ -1063,10 +827,10 @@ $.extend( Scroller.prototype, {
|
|
1063
827
|
dt = this.s.dt,
|
1064
828
|
language = dt.oLanguage,
|
1065
829
|
iScrollTop = this.dom.scroller.scrollTop,
|
1066
|
-
iStart = Math.floor( this.
|
830
|
+
iStart = Math.floor( this.pixelsToRow(iScrollTop, false, this.s.ani)+1 ),
|
1067
831
|
iMax = dt.fnRecordsTotal(),
|
1068
832
|
iTotal = dt.fnRecordsDisplay(),
|
1069
|
-
iPossibleEnd = Math.ceil( this.
|
833
|
+
iPossibleEnd = Math.ceil( this.pixelsToRow(iScrollTop+this.s.heights.viewport, false, this.s.ani) ),
|
1070
834
|
iEnd = iTotal < iPossibleEnd ? iTotal : iPossibleEnd,
|
1071
835
|
sStart = dt.fnFormatNumber( iStart ),
|
1072
836
|
sEnd = dt.fnFormatNumber( iEnd ),
|
@@ -1130,6 +894,210 @@ $.extend( Scroller.prototype, {
|
|
1130
894
|
|
1131
895
|
// DT doesn't actually (yet) trigger this event, but it will in future
|
1132
896
|
$(dt.nTable).triggerHandler( 'info.dt' );
|
897
|
+
},
|
898
|
+
|
899
|
+
/**
|
900
|
+
* Parse CSS height property string as number
|
901
|
+
*
|
902
|
+
* An attempt is made to parse the string as a number. Currently supported units are 'px',
|
903
|
+
* 'vh', and 'rem'. 'em' is partially supported; it works as long as the parent element's
|
904
|
+
* font size matches the body element. Zero is returned for unrecognized strings.
|
905
|
+
* @param {string} cssHeight CSS height property string
|
906
|
+
* @returns {number} height
|
907
|
+
* @private
|
908
|
+
*/
|
909
|
+
_parseHeight: function(cssHeight) {
|
910
|
+
var height;
|
911
|
+
var matches = /^([+-]?(?:\d+(?:\.\d+)?|\.\d+))(px|em|rem|vh)$/.exec(cssHeight);
|
912
|
+
|
913
|
+
if (matches === null) {
|
914
|
+
return 0;
|
915
|
+
}
|
916
|
+
|
917
|
+
var value = parseFloat(matches[1]);
|
918
|
+
var unit = matches[2];
|
919
|
+
|
920
|
+
if ( unit === 'px' ) {
|
921
|
+
height = value;
|
922
|
+
}
|
923
|
+
else if ( unit === 'vh' ) {
|
924
|
+
height = ( value / 100 ) * $(window).height();
|
925
|
+
}
|
926
|
+
else if ( unit === 'rem' ) {
|
927
|
+
height = value * parseFloat($(':root').css('font-size'));
|
928
|
+
}
|
929
|
+
else if ( unit === 'em' ) {
|
930
|
+
height = value * parseFloat($('body').css('font-size'));
|
931
|
+
}
|
932
|
+
|
933
|
+
return height ?
|
934
|
+
height :
|
935
|
+
0;
|
936
|
+
},
|
937
|
+
|
938
|
+
/**
|
939
|
+
* Scrolling function - fired whenever the scrolling position is changed.
|
940
|
+
* This method needs to use the stored values to see if the table should be
|
941
|
+
* redrawn as we are moving towards the end of the information that is
|
942
|
+
* currently drawn or not. If needed, then it will redraw the table based on
|
943
|
+
* the new position.
|
944
|
+
* @returns {void}
|
945
|
+
* @private
|
946
|
+
*/
|
947
|
+
_scroll: function ()
|
948
|
+
{
|
949
|
+
var
|
950
|
+
that = this,
|
951
|
+
heights = this.s.heights,
|
952
|
+
iScrollTop = this.dom.scroller.scrollTop,
|
953
|
+
iTopRow;
|
954
|
+
|
955
|
+
if ( this.s.skip ) {
|
956
|
+
return;
|
957
|
+
}
|
958
|
+
|
959
|
+
if ( this.s.ingnoreScroll ) {
|
960
|
+
return;
|
961
|
+
}
|
962
|
+
|
963
|
+
if ( iScrollTop === this.s.lastScrollTop ) {
|
964
|
+
return;
|
965
|
+
}
|
966
|
+
|
967
|
+
/* If the table has been sorted or filtered, then we use the redraw that
|
968
|
+
* DataTables as done, rather than performing our own
|
969
|
+
*/
|
970
|
+
if ( this.s.dt.bFiltered || this.s.dt.bSorted ) {
|
971
|
+
this.s.lastScrollTop = 0;
|
972
|
+
return;
|
973
|
+
}
|
974
|
+
|
975
|
+
/* Update the table's information display for what is now in the viewport */
|
976
|
+
this._info();
|
977
|
+
|
978
|
+
/* We don't want to state save on every scroll event - that's heavy
|
979
|
+
* handed, so use a timeout to update the state saving only when the
|
980
|
+
* scrolling has finished
|
981
|
+
*/
|
982
|
+
clearTimeout( this.s.stateTO );
|
983
|
+
this.s.stateTO = setTimeout( function () {
|
984
|
+
that.s.dtApi.state.save();
|
985
|
+
}, 250 );
|
986
|
+
|
987
|
+
this.s.scrollType = Math.abs(iScrollTop - this.s.lastScrollTop) > heights.viewport ?
|
988
|
+
'jump' :
|
989
|
+
'cont';
|
990
|
+
|
991
|
+
this.s.topRowFloat = this.s.scrollType === 'cont' ?
|
992
|
+
this.pixelsToRow( iScrollTop, false, false ) :
|
993
|
+
this._domain( 'physicalToVirtual', iScrollTop ) / heights.row;
|
994
|
+
|
995
|
+
if ( this.s.topRowFloat < 0 ) {
|
996
|
+
this.s.topRowFloat = 0;
|
997
|
+
}
|
998
|
+
|
999
|
+
/* Check if the scroll point is outside the trigger boundary which would required
|
1000
|
+
* a DataTables redraw
|
1001
|
+
*/
|
1002
|
+
if ( this.s.forceReposition || iScrollTop < this.s.redrawTop || iScrollTop > this.s.redrawBottom ) {
|
1003
|
+
var preRows = Math.ceil( ((this.s.displayBuffer-1)/2) * this.s.viewportRows );
|
1004
|
+
|
1005
|
+
iTopRow = parseInt(this.s.topRowFloat, 10) - preRows;
|
1006
|
+
this.s.forceReposition = false;
|
1007
|
+
|
1008
|
+
if ( iTopRow <= 0 ) {
|
1009
|
+
/* At the start of the table */
|
1010
|
+
iTopRow = 0;
|
1011
|
+
}
|
1012
|
+
else if ( iTopRow + this.s.dt._iDisplayLength > this.s.dt.fnRecordsDisplay() ) {
|
1013
|
+
/* At the end of the table */
|
1014
|
+
iTopRow = this.s.dt.fnRecordsDisplay() - this.s.dt._iDisplayLength;
|
1015
|
+
if ( iTopRow < 0 ) {
|
1016
|
+
iTopRow = 0;
|
1017
|
+
}
|
1018
|
+
}
|
1019
|
+
else if ( iTopRow % 2 !== 0 ) {
|
1020
|
+
// For the row-striping classes (odd/even) we want only to start
|
1021
|
+
// on evens otherwise the stripes will change between draws and
|
1022
|
+
// look rubbish
|
1023
|
+
iTopRow++;
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
|
1027
|
+
if ( iTopRow != this.s.dt._iDisplayStart ) {
|
1028
|
+
/* Cache the new table position for quick lookups */
|
1029
|
+
this.s.tableTop = $(this.s.dt.nTable).offset().top;
|
1030
|
+
this.s.tableBottom = $(this.s.dt.nTable).height() + this.s.tableTop;
|
1031
|
+
|
1032
|
+
var draw = function () {
|
1033
|
+
if ( that.s.scrollDrawReq === null ) {
|
1034
|
+
that.s.scrollDrawReq = iScrollTop;
|
1035
|
+
}
|
1036
|
+
|
1037
|
+
that.s.dt._iDisplayStart = iTopRow;
|
1038
|
+
that.s.dt.oApi._fnDraw( that.s.dt );
|
1039
|
+
};
|
1040
|
+
|
1041
|
+
/* Do the DataTables redraw based on the calculated start point - note that when
|
1042
|
+
* using server-side processing we introduce a small delay to not DoS the server...
|
1043
|
+
*/
|
1044
|
+
if ( this.s.dt.oFeatures.bServerSide ) {
|
1045
|
+
clearTimeout( this.s.drawTO );
|
1046
|
+
this.s.drawTO = setTimeout( draw, this.s.serverWait );
|
1047
|
+
}
|
1048
|
+
else {
|
1049
|
+
draw();
|
1050
|
+
}
|
1051
|
+
|
1052
|
+
if ( this.dom.loader && ! this.s.loaderVisible ) {
|
1053
|
+
this.dom.loader.css( 'display', 'block' );
|
1054
|
+
this.s.loaderVisible = true;
|
1055
|
+
}
|
1056
|
+
}
|
1057
|
+
}
|
1058
|
+
else {
|
1059
|
+
this.s.topRowFloat = this.pixelsToRow( iScrollTop, false, true );
|
1060
|
+
}
|
1061
|
+
|
1062
|
+
this.s.lastScrollTop = iScrollTop;
|
1063
|
+
this.s.stateSaveThrottle();
|
1064
|
+
|
1065
|
+
if ( this.s.scrollType === 'jump' && this.s.mousedown ) {
|
1066
|
+
this.dom.label
|
1067
|
+
.html( this.s.dt.fnFormatNumber( parseInt( this.s.topRowFloat, 10 )+1 ) )
|
1068
|
+
.css( 'top', iScrollTop + (iScrollTop * heights.labelFactor ) )
|
1069
|
+
.css( 'display', 'block' );
|
1070
|
+
}
|
1071
|
+
},
|
1072
|
+
|
1073
|
+
/**
|
1074
|
+
* Force the scrolling container to have height beyond that of just the
|
1075
|
+
* table that has been drawn so the user can scroll the whole data set.
|
1076
|
+
*
|
1077
|
+
* Note that if the calculated required scrolling height exceeds a maximum
|
1078
|
+
* value (1 million pixels - hard-coded) the forcing element will be set
|
1079
|
+
* only to that maximum value and virtual / physical domain transforms will
|
1080
|
+
* be used to allow Scroller to display tables of any number of records.
|
1081
|
+
* @returns {void}
|
1082
|
+
* @private
|
1083
|
+
*/
|
1084
|
+
_scrollForce: function ()
|
1085
|
+
{
|
1086
|
+
var heights = this.s.heights;
|
1087
|
+
var max = 1000000;
|
1088
|
+
|
1089
|
+
heights.virtual = heights.row * this.s.dt.fnRecordsDisplay();
|
1090
|
+
heights.scroll = heights.virtual;
|
1091
|
+
|
1092
|
+
if ( heights.scroll > max ) {
|
1093
|
+
heights.scroll = max;
|
1094
|
+
}
|
1095
|
+
|
1096
|
+
// Minimum height so there is always a row visible (the 'no rows found'
|
1097
|
+
// if reduced to zero filtering)
|
1098
|
+
this.dom.force.style.height = heights.scroll > this.s.heights.row ?
|
1099
|
+
heights.scroll+'px' :
|
1100
|
+
this.s.heights.row+'px';
|
1133
1101
|
}
|
1134
1102
|
} );
|
1135
1103
|
|
@@ -1146,62 +1114,19 @@ $.extend( Scroller.prototype, {
|
|
1146
1114
|
* @name Scroller.defaults
|
1147
1115
|
* @static
|
1148
1116
|
*/
|
1149
|
-
Scroller.defaults =
|
1150
|
-
/**
|
1151
|
-
* Indicate if Scroller show show trace information on the console or not. This can be
|
1152
|
-
* useful when debugging Scroller or if just curious as to what it is doing, but should
|
1153
|
-
* be turned off for production.
|
1154
|
-
* @type bool
|
1155
|
-
* @default false
|
1156
|
-
* @static
|
1157
|
-
* @example
|
1158
|
-
* var oTable = $('#example').dataTable( {
|
1159
|
-
* "sScrollY": "200px",
|
1160
|
-
* "sDom": "frtiS",
|
1161
|
-
* "bDeferRender": true,
|
1162
|
-
* "oScroller": {
|
1163
|
-
* "trace": true
|
1164
|
-
* }
|
1165
|
-
* } );
|
1166
|
-
*/
|
1167
|
-
"trace": false,
|
1168
|
-
|
1117
|
+
Scroller.defaults = {
|
1169
1118
|
/**
|
1170
|
-
* Scroller
|
1171
|
-
*
|
1172
|
-
*
|
1173
|
-
*
|
1174
|
-
*
|
1175
|
-
*
|
1176
|
-
*
|
1177
|
-
*
|
1178
|
-
* "sDom": "frtiS",
|
1179
|
-
* "bDeferRender": true,
|
1180
|
-
* "oScroller": {
|
1181
|
-
* "rowHeight": 30
|
1182
|
-
* }
|
1183
|
-
* } );
|
1184
|
-
*/
|
1185
|
-
"rowHeight": "auto",
|
1186
|
-
|
1187
|
-
/**
|
1188
|
-
* When using server-side processing, Scroller will wait a small amount of time to allow
|
1189
|
-
* the scrolling to finish before requesting more data from the server. This prevents
|
1190
|
-
* you from DoSing your own server! The wait time can be configured by this parameter.
|
1191
|
-
* @type int
|
1192
|
-
* @default 200
|
1119
|
+
* Scroller uses the boundary scaling factor to decide when to redraw the table - which it
|
1120
|
+
* typically does before you reach the end of the currently loaded data set (in order to
|
1121
|
+
* allow the data to look continuous to a user scrolling through the data). If given as 0
|
1122
|
+
* then the table will be redrawn whenever the viewport is scrolled, while 1 would not
|
1123
|
+
* redraw the table until the currently loaded data has all been shown. You will want
|
1124
|
+
* something in the middle - the default factor of 0.5 is usually suitable.
|
1125
|
+
* @type float
|
1126
|
+
* @default 0.5
|
1193
1127
|
* @static
|
1194
|
-
* @example
|
1195
|
-
* var oTable = $('#example').dataTable( {
|
1196
|
-
* "sScrollY": "200px",
|
1197
|
-
* "sDom": "frtiS",
|
1198
|
-
* "bDeferRender": true,
|
1199
|
-
* "oScroller": {
|
1200
|
-
* "serverWait": 100
|
1201
|
-
* }
|
1202
|
-
* } );
|
1203
1128
|
*/
|
1204
|
-
|
1129
|
+
boundaryScale: 0.5,
|
1205
1130
|
|
1206
1131
|
/**
|
1207
1132
|
* The display buffer is what Scroller uses to calculate how many rows it should pre-fetch
|
@@ -1216,39 +1141,8 @@ Scroller.defaults = /** @lends Scroller.defaults */{
|
|
1216
1141
|
* @type int
|
1217
1142
|
* @default 7
|
1218
1143
|
* @static
|
1219
|
-
* @example
|
1220
|
-
* var oTable = $('#example').dataTable( {
|
1221
|
-
* "sScrollY": "200px",
|
1222
|
-
* "sDom": "frtiS",
|
1223
|
-
* "bDeferRender": true,
|
1224
|
-
* "oScroller": {
|
1225
|
-
* "displayBuffer": 10
|
1226
|
-
* }
|
1227
|
-
* } );
|
1228
|
-
*/
|
1229
|
-
"displayBuffer": 9,
|
1230
|
-
|
1231
|
-
/**
|
1232
|
-
* Scroller uses the boundary scaling factor to decide when to redraw the table - which it
|
1233
|
-
* typically does before you reach the end of the currently loaded data set (in order to
|
1234
|
-
* allow the data to look continuous to a user scrolling through the data). If given as 0
|
1235
|
-
* then the table will be redrawn whenever the viewport is scrolled, while 1 would not
|
1236
|
-
* redraw the table until the currently loaded data has all been shown. You will want
|
1237
|
-
* something in the middle - the default factor of 0.5 is usually suitable.
|
1238
|
-
* @type float
|
1239
|
-
* @default 0.5
|
1240
|
-
* @static
|
1241
|
-
* @example
|
1242
|
-
* var oTable = $('#example').dataTable( {
|
1243
|
-
* "sScrollY": "200px",
|
1244
|
-
* "sDom": "frtiS",
|
1245
|
-
* "bDeferRender": true,
|
1246
|
-
* "oScroller": {
|
1247
|
-
* "boundaryScale": 0.75
|
1248
|
-
* }
|
1249
|
-
* } );
|
1250
1144
|
*/
|
1251
|
-
|
1145
|
+
displayBuffer: 9,
|
1252
1146
|
|
1253
1147
|
/**
|
1254
1148
|
* Show (or not) the loading element in the background of the table. Note that you should
|
@@ -1256,17 +1150,27 @@ Scroller.defaults = /** @lends Scroller.defaults */{
|
|
1256
1150
|
* @type boolean
|
1257
1151
|
* @default false
|
1258
1152
|
* @static
|
1259
|
-
* @example
|
1260
|
-
* var oTable = $('#example').dataTable( {
|
1261
|
-
* "sScrollY": "200px",
|
1262
|
-
* "sDom": "frtiS",
|
1263
|
-
* "bDeferRender": true,
|
1264
|
-
* "oScroller": {
|
1265
|
-
* "loadingIndicator": true
|
1266
|
-
* }
|
1267
|
-
* } );
|
1268
1153
|
*/
|
1269
|
-
|
1154
|
+
loadingIndicator: false,
|
1155
|
+
|
1156
|
+
/**
|
1157
|
+
* Scroller will attempt to automatically calculate the height of rows for it's internal
|
1158
|
+
* calculations. However the height that is used can be overridden using this parameter.
|
1159
|
+
* @type int|string
|
1160
|
+
* @default auto
|
1161
|
+
* @static
|
1162
|
+
*/
|
1163
|
+
rowHeight: "auto",
|
1164
|
+
|
1165
|
+
/**
|
1166
|
+
* When using server-side processing, Scroller will wait a small amount of time to allow
|
1167
|
+
* the scrolling to finish before requesting more data from the server. This prevents
|
1168
|
+
* you from DoSing your own server! The wait time can be configured by this parameter.
|
1169
|
+
* @type int
|
1170
|
+
* @default 200
|
1171
|
+
* @static
|
1172
|
+
*/
|
1173
|
+
serverWait: 200
|
1270
1174
|
};
|
1271
1175
|
|
1272
1176
|
Scroller.oDefaults = Scroller.defaults;
|
@@ -1284,7 +1188,7 @@ Scroller.oDefaults = Scroller.defaults;
|
|
1284
1188
|
* @name Scroller.version
|
1285
1189
|
* @static
|
1286
1190
|
*/
|
1287
|
-
Scroller.version = "
|
1191
|
+
Scroller.version = "2.0.1";
|
1288
1192
|
|
1289
1193
|
|
1290
1194
|
|
@@ -1292,27 +1196,6 @@ Scroller.version = "1.5.1";
|
|
1292
1196
|
* Initialisation
|
1293
1197
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
1294
1198
|
|
1295
|
-
// Legacy `dom` parameter initialisation support
|
1296
|
-
if ( typeof $.fn.dataTable == "function" &&
|
1297
|
-
typeof $.fn.dataTableExt.fnVersionCheck == "function" &&
|
1298
|
-
$.fn.dataTableExt.fnVersionCheck('1.10.0') )
|
1299
|
-
{
|
1300
|
-
$.fn.dataTableExt.aoFeatures.push( {
|
1301
|
-
"fnInit": function( oDTSettings ) {
|
1302
|
-
var init = oDTSettings.oInit;
|
1303
|
-
var opts = init.scroller || init.oScroller || {};
|
1304
|
-
|
1305
|
-
new Scroller( oDTSettings, opts );
|
1306
|
-
},
|
1307
|
-
"cFeature": "S",
|
1308
|
-
"sFeature": "Scroller"
|
1309
|
-
} );
|
1310
|
-
}
|
1311
|
-
else
|
1312
|
-
{
|
1313
|
-
alert( "Warning: Scroller requires DataTables 1.10.0 or greater - www.datatables.net/download");
|
1314
|
-
}
|
1315
|
-
|
1316
1199
|
// Attach a listener to the document which listens for DataTables initialisation
|
1317
1200
|
// events so we can automatically initialise
|
1318
1201
|
$(document).on( 'preInit.dt.dtscroller', function (e, settings) {
|
@@ -1350,7 +1233,7 @@ Api.register( 'scroller().rowToPixels()', function ( rowIdx, intParse, virtual )
|
|
1350
1233
|
var ctx = this.context;
|
1351
1234
|
|
1352
1235
|
if ( ctx.length && ctx[0].oScroller ) {
|
1353
|
-
return ctx[0].oScroller.
|
1236
|
+
return ctx[0].oScroller.rowToPixels( rowIdx, intParse, virtual );
|
1354
1237
|
}
|
1355
1238
|
// undefined
|
1356
1239
|
} );
|
@@ -1360,7 +1243,7 @@ Api.register( 'scroller().pixelsToRow()', function ( pixels, intParse, virtual )
|
|
1360
1243
|
var ctx = this.context;
|
1361
1244
|
|
1362
1245
|
if ( ctx.length && ctx[0].oScroller ) {
|
1363
|
-
return ctx[0].oScroller.
|
1246
|
+
return ctx[0].oScroller.pixelsToRow( pixels, intParse, virtual );
|
1364
1247
|
}
|
1365
1248
|
// undefined
|
1366
1249
|
} );
|
@@ -1369,7 +1252,7 @@ Api.register( 'scroller().pixelsToRow()', function ( pixels, intParse, virtual )
|
|
1369
1252
|
Api.register( ['scroller().scrollToRow()', 'scroller.toPosition()'], function ( idx, ani ) {
|
1370
1253
|
this.iterator( 'table', function ( ctx ) {
|
1371
1254
|
if ( ctx.oScroller ) {
|
1372
|
-
ctx.oScroller.
|
1255
|
+
ctx.oScroller.scrollToRow( idx, ani );
|
1373
1256
|
}
|
1374
1257
|
} );
|
1375
1258
|
|
@@ -1386,7 +1269,7 @@ Api.register( 'row().scrollTo()', function ( ani ) {
|
|
1386
1269
|
.indexes()
|
1387
1270
|
.indexOf( rowIdx );
|
1388
1271
|
|
1389
|
-
ctx.oScroller.
|
1272
|
+
ctx.oScroller.scrollToRow( displayIdx, ani );
|
1390
1273
|
}
|
1391
1274
|
} );
|
1392
1275
|
|
@@ -1396,7 +1279,7 @@ Api.register( 'row().scrollTo()', function ( ani ) {
|
|
1396
1279
|
Api.register( 'scroller.measure()', function ( redraw ) {
|
1397
1280
|
this.iterator( 'table', function ( ctx ) {
|
1398
1281
|
if ( ctx.oScroller ) {
|
1399
|
-
ctx.oScroller.
|
1282
|
+
ctx.oScroller.measure( redraw );
|
1400
1283
|
}
|
1401
1284
|
} );
|
1402
1285
|
|
@@ -1407,7 +1290,7 @@ Api.register( 'scroller.page()', function() {
|
|
1407
1290
|
var ctx = this.context;
|
1408
1291
|
|
1409
1292
|
if ( ctx.length && ctx[0].oScroller ) {
|
1410
|
-
return ctx[0].oScroller.
|
1293
|
+
return ctx[0].oScroller.pageInfo();
|
1411
1294
|
}
|
1412
1295
|
// undefined
|
1413
1296
|
} );
|