jquery-datatables 1.10.19.1 → 1.10.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.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
|
} );
|