jquery-datatables 1.10.12
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 +7 -0
- data/.gitignore +23 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +27 -0
- data/README.md +118 -0
- data/Rakefile +166 -0
- data/app/assets/images/datatables/sort_asc.png +0 -0
- data/app/assets/images/datatables/sort_asc_disabled.png +0 -0
- data/app/assets/images/datatables/sort_both.png +0 -0
- data/app/assets/images/datatables/sort_desc.png +0 -0
- data/app/assets/images/datatables/sort_desc_disabled.png +0 -0
- data/app/assets/javascripts/datatables/dataTables.bootstrap.js +182 -0
- data/app/assets/javascripts/datatables/dataTables.bootstrap4.js +184 -0
- data/app/assets/javascripts/datatables/dataTables.foundation.js +174 -0
- data/app/assets/javascripts/datatables/dataTables.jqueryui.js +164 -0
- data/app/assets/javascripts/datatables/dataTables.material.js +191 -0
- data/app/assets/javascripts/datatables/dataTables.semanticui.js +208 -0
- data/app/assets/javascripts/datatables/dataTables.uikit.js +176 -0
- data/app/assets/javascripts/datatables/extensions/AutoFill/autoFill.bootstrap.js +43 -0
- data/app/assets/javascripts/datatables/extensions/AutoFill/autoFill.bootstrap4.js +43 -0
- data/app/assets/javascripts/datatables/extensions/AutoFill/autoFill.foundation.js +43 -0
- data/app/assets/javascripts/datatables/extensions/AutoFill/autoFill.jqueryui.js +43 -0
- data/app/assets/javascripts/datatables/extensions/AutoFill/autoFill.semanticui.js +43 -0
- data/app/assets/javascripts/datatables/extensions/AutoFill/dataTables.autoFill.js +1036 -0
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.bootstrap.js +68 -0
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.bootstrap4.js +60 -0
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.colVis.js +199 -0
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.flash.js +1325 -0
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.foundation.js +85 -0
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.html5.js +1322 -0
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.jqueryui.js +62 -0
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.print.js +172 -0
- data/app/assets/javascripts/datatables/extensions/Buttons/buttons.semanticui.js +57 -0
- data/app/assets/javascripts/datatables/extensions/Buttons/dataTables.buttons.js +1634 -0
- data/app/assets/javascripts/datatables/extensions/ColReorder/dataTables.colReorder.js +1335 -0
- data/app/assets/javascripts/datatables/extensions/FixedColumns/dataTables.fixedColumns.js +1623 -0
- data/app/assets/javascripts/datatables/extensions/FixedHeader/dataTables.fixedHeader.js +672 -0
- data/app/assets/javascripts/datatables/extensions/KeyTable/dataTables.keyTable.js +883 -0
- data/app/assets/javascripts/datatables/extensions/Responsive/dataTables.responsive.js +1232 -0
- data/app/assets/javascripts/datatables/extensions/Responsive/responsive.bootstrap.js +81 -0
- data/app/assets/javascripts/datatables/extensions/Responsive/responsive.bootstrap4.js +81 -0
- data/app/assets/javascripts/datatables/extensions/Responsive/responsive.foundation.js +62 -0
- data/app/assets/javascripts/datatables/extensions/Responsive/responsive.jqueryui.js +63 -0
- data/app/assets/javascripts/datatables/extensions/Responsive/responsive.semanticui.js +77 -0
- data/app/assets/javascripts/datatables/extensions/RowReorder/dataTables.rowReorder.js +709 -0
- data/app/assets/javascripts/datatables/extensions/Scroller/dataTables.scroller.js +1349 -0
- data/app/assets/javascripts/datatables/extensions/Select/dataTables.select.js +1109 -0
- data/app/assets/javascripts/datatables/jquery.dataTables.js +15278 -0
- data/app/assets/media/swf/flashExport.swf +0 -0
- data/app/assets/stylesheets/datatables/dataTables.bootstrap.css +185 -0
- data/app/assets/stylesheets/datatables/dataTables.bootstrap4.css +193 -0
- data/app/assets/stylesheets/datatables/dataTables.foundation.css +116 -0
- data/app/assets/stylesheets/datatables/dataTables.jqueryui.css +481 -0
- data/app/assets/stylesheets/datatables/dataTables.material.css +87 -0
- data/app/assets/stylesheets/datatables/dataTables.semanticui.css +103 -0
- data/app/assets/stylesheets/datatables/dataTables.uikit.css +146 -0
- data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.bootstrap.css +81 -0
- data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.bootstrap4.css +81 -0
- data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.dataTables.css +92 -0
- data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.foundation.css +85 -0
- data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.jqueryui.css +85 -0
- data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.semanticui.css +81 -0
- data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.bootstrap.css +102 -0
- data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.bootstrap4.css +163 -0
- data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.dataTables.css +298 -0
- data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.foundation.css +129 -0
- data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.jqueryui.css +162 -0
- data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.semanticui.css +114 -0
- data/app/assets/stylesheets/datatables/extensions/Buttons/common.scss +27 -0
- data/app/assets/stylesheets/datatables/extensions/Buttons/mixins.scss +89 -0
- data/app/assets/stylesheets/datatables/extensions/ColReorder/colReorder.bootstrap.css +11 -0
- data/app/assets/stylesheets/datatables/extensions/ColReorder/colReorder.bootstrap4.css +11 -0
- data/app/assets/stylesheets/datatables/extensions/ColReorder/colReorder.dataTables.css +11 -0
- data/app/assets/stylesheets/datatables/extensions/ColReorder/colReorder.foundation.css +11 -0
- data/app/assets/stylesheets/datatables/extensions/ColReorder/colReorder.jqueryui.css +11 -0
- data/app/assets/stylesheets/datatables/extensions/ColReorder/colReorder.semanticui.css +11 -0
- data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.bootstrap.css +44 -0
- data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.bootstrap4.css +44 -0
- data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.dataTables.css +18 -0
- data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.foundation.css +27 -0
- data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.jqueryui.css +8 -0
- data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.semanticui.css +16 -0
- data/app/assets/stylesheets/datatables/extensions/FixedHeader/fixedHeader.bootstrap.css +20 -0
- data/app/assets/stylesheets/datatables/extensions/FixedHeader/fixedHeader.bootstrap4.css +20 -0
- data/app/assets/stylesheets/datatables/extensions/FixedHeader/fixedHeader.dataTables.css +19 -0
- data/app/assets/stylesheets/datatables/extensions/FixedHeader/fixedHeader.foundation.css +20 -0
- data/app/assets/stylesheets/datatables/extensions/FixedHeader/fixedHeader.jqueryui.css +15 -0
- data/app/assets/stylesheets/datatables/extensions/FixedHeader/fixedHeader.semanticui.css +14 -0
- data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.bootstrap.css +5 -0
- data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.bootstrap4.css +5 -0
- data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.dataTables.css +5 -0
- data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.foundation.css +5 -0
- data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.jqueryui.css +5 -0
- data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.semanticui.css +5 -0
- data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.bootstrap.css +181 -0
- data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.bootstrap4.css +181 -0
- data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.dataTables.css +178 -0
- data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.foundation.css +181 -0
- data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.jqueryui.css +178 -0
- data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.semanticui.css +181 -0
- data/app/assets/stylesheets/datatables/extensions/RowReorder/rowReorder.bootstrap.css +22 -0
- data/app/assets/stylesheets/datatables/extensions/RowReorder/rowReorder.bootstrap4.css +22 -0
- data/app/assets/stylesheets/datatables/extensions/RowReorder/rowReorder.dataTables.css +22 -0
- data/app/assets/stylesheets/datatables/extensions/RowReorder/rowReorder.foundation.css +22 -0
- data/app/assets/stylesheets/datatables/extensions/RowReorder/rowReorder.jqueryui.css +22 -0
- data/app/assets/stylesheets/datatables/extensions/RowReorder/rowReorder.semanticui.css +22 -0
- data/app/assets/stylesheets/datatables/extensions/RowReorder/semanticui.scss +5 -0
- data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.bootstrap.css +24 -0
- data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.bootstrap4.css +24 -0
- data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.dataTables.css +20 -0
- data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.foundation.css +17 -0
- data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.jqueryui.css +20 -0
- data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.semanticui.css +20 -0
- data/app/assets/stylesheets/datatables/extensions/Select/select.bootstrap.css +110 -0
- data/app/assets/stylesheets/datatables/extensions/Select/select.bootstrap4.css +110 -0
- data/app/assets/stylesheets/datatables/extensions/Select/select.dataTables.css +100 -0
- data/app/assets/stylesheets/datatables/extensions/Select/select.foundation.css +112 -0
- data/app/assets/stylesheets/datatables/extensions/Select/select.jqueryui.css +100 -0
- data/app/assets/stylesheets/datatables/extensions/Select/select.semanticui.css +105 -0
- data/app/assets/stylesheets/datatables/jquery.dataTables.css +452 -0
- data/app/assets/stylesheets/datatables/jquery.dataTables_themeroller.css +416 -0
- data/jquery-datatables.gemspec +27 -0
- data/lib/generators/jquery/datatables/install_generator.rb +63 -0
- data/lib/generators/jquery/datatables/templates/bootstrap.css.tt +15 -0
- data/lib/generators/jquery/datatables/templates/bootstrap.js.tt +22 -0
- data/lib/generators/jquery/datatables/templates/bootstrap4.css.tt +15 -0
- data/lib/generators/jquery/datatables/templates/bootstrap4.js.tt +22 -0
- data/lib/generators/jquery/datatables/templates/foundation.css.tt +15 -0
- data/lib/generators/jquery/datatables/templates/foundation.js.tt +24 -0
- data/lib/generators/jquery/datatables/templates/jqueryui.css.tt +15 -0
- data/lib/generators/jquery/datatables/templates/jqueryui.js.tt +18 -0
- data/lib/generators/jquery/datatables/templates/material.css.tt +15 -0
- data/lib/generators/jquery/datatables/templates/material.js.tt +19 -0
- data/lib/generators/jquery/datatables/templates/regular.css.tt +15 -0
- data/lib/generators/jquery/datatables/templates/regular.js.tt +18 -0
- data/lib/generators/jquery/datatables/templates/semanticui.css.tt +16 -0
- data/lib/generators/jquery/datatables/templates/semanticui.js.tt +22 -0
- data/lib/generators/jquery/datatables/templates/uikit.css.tt +15 -0
- data/lib/generators/jquery/datatables/templates/uikit.js.tt +19 -0
- data/lib/jquery-datatables.rb +26 -0
- data/lib/jquery-datatables/engine.rb +11 -0
- data/lib/jquery-datatables/version.rb +6 -0
- metadata +269 -0
@@ -0,0 +1,1349 @@
|
|
1
|
+
/*! Scroller 1.4.2
|
2
|
+
* ©2011-2016 SpryMedia Ltd - datatables.net/license
|
3
|
+
*/
|
4
|
+
|
5
|
+
/**
|
6
|
+
* @summary Scroller
|
7
|
+
* @description Virtual rendering for DataTables
|
8
|
+
* @version 1.4.2
|
9
|
+
* @file dataTables.scroller.js
|
10
|
+
* @author SpryMedia Ltd (www.sprymedia.co.uk)
|
11
|
+
* @contact www.sprymedia.co.uk/contact
|
12
|
+
* @copyright Copyright 2011-2016 SpryMedia Ltd.
|
13
|
+
*
|
14
|
+
* This source file is free software, available under the following license:
|
15
|
+
* MIT license - http://datatables.net/license/mit
|
16
|
+
*
|
17
|
+
* This source file is distributed in the hope that it will be useful, but
|
18
|
+
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
19
|
+
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
|
20
|
+
*
|
21
|
+
* For details please refer to: http://www.datatables.net
|
22
|
+
*/
|
23
|
+
|
24
|
+
(function( factory ){
|
25
|
+
if ( typeof define === 'function' && define.amd ) {
|
26
|
+
// AMD
|
27
|
+
define( ['jquery', 'datatables.net'], function ( $ ) {
|
28
|
+
return factory( $, window, document );
|
29
|
+
} );
|
30
|
+
}
|
31
|
+
else if ( typeof exports === 'object' ) {
|
32
|
+
// CommonJS
|
33
|
+
module.exports = function (root, $) {
|
34
|
+
if ( ! root ) {
|
35
|
+
root = window;
|
36
|
+
}
|
37
|
+
|
38
|
+
if ( ! $ || ! $.fn.dataTable ) {
|
39
|
+
$ = require('datatables.net')(root, $).$;
|
40
|
+
}
|
41
|
+
|
42
|
+
return factory( $, root, root.document );
|
43
|
+
};
|
44
|
+
}
|
45
|
+
else {
|
46
|
+
// Browser
|
47
|
+
factory( jQuery, window, document );
|
48
|
+
}
|
49
|
+
}(function( $, window, document, undefined ) {
|
50
|
+
'use strict';
|
51
|
+
var DataTable = $.fn.dataTable;
|
52
|
+
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Scroller is a virtual rendering plug-in for DataTables which allows large
|
56
|
+
* datasets to be drawn on screen every quickly. What the virtual rendering means
|
57
|
+
* is that only the visible portion of the table (and a bit to either side to make
|
58
|
+
* the scrolling smooth) is drawn, while the scrolling container gives the
|
59
|
+
* visual impression that the whole table is visible. This is done by making use
|
60
|
+
* of the pagination abilities of DataTables and moving the table around in the
|
61
|
+
* scrolling container DataTables adds to the page. The scrolling container is
|
62
|
+
* forced to the height it would be for the full table display using an extra
|
63
|
+
* element.
|
64
|
+
*
|
65
|
+
* Note that rows in the table MUST all be the same height. Information in a cell
|
66
|
+
* which expands on to multiple lines will cause some odd behaviour in the scrolling.
|
67
|
+
*
|
68
|
+
* Scroller is initialised by simply including the letter 'S' in the sDom for the
|
69
|
+
* table you want to have this feature enabled on. Note that the 'S' must come
|
70
|
+
* AFTER the 't' parameter in `dom`.
|
71
|
+
*
|
72
|
+
* Key features include:
|
73
|
+
* <ul class="limit_length">
|
74
|
+
* <li>Speed! The aim of Scroller for DataTables is to make rendering large data sets fast</li>
|
75
|
+
* <li>Full compatibility with deferred rendering in DataTables for maximum speed</li>
|
76
|
+
* <li>Display millions of rows</li>
|
77
|
+
* <li>Integration with state saving in DataTables (scrolling position is saved)</li>
|
78
|
+
* <li>Easy to use</li>
|
79
|
+
* </ul>
|
80
|
+
*
|
81
|
+
* @class
|
82
|
+
* @constructor
|
83
|
+
* @global
|
84
|
+
* @param {object} dt DataTables settings object or API instance
|
85
|
+
* @param {object} [opts={}] Configuration object for FixedColumns. Options
|
86
|
+
* are defined by {@link Scroller.defaults}
|
87
|
+
*
|
88
|
+
* @requires jQuery 1.7+
|
89
|
+
* @requires DataTables 1.10.0+
|
90
|
+
*
|
91
|
+
* @example
|
92
|
+
* $(document).ready(function() {
|
93
|
+
* $('#example').DataTable( {
|
94
|
+
* "scrollY": "200px",
|
95
|
+
* "ajax": "media/dataset/large.txt",
|
96
|
+
* "dom": "frtiS",
|
97
|
+
* "deferRender": true
|
98
|
+
* } );
|
99
|
+
* } );
|
100
|
+
*/
|
101
|
+
var Scroller = function ( dt, opts ) {
|
102
|
+
/* Sanity check - you just know it will happen */
|
103
|
+
if ( ! (this instanceof Scroller) ) {
|
104
|
+
alert( "Scroller warning: Scroller must be initialised with the 'new' keyword." );
|
105
|
+
return;
|
106
|
+
}
|
107
|
+
|
108
|
+
if ( opts === undefined ) {
|
109
|
+
opts = {};
|
110
|
+
}
|
111
|
+
|
112
|
+
/**
|
113
|
+
* Settings object which contains customisable information for the Scroller instance
|
114
|
+
* @namespace
|
115
|
+
* @private
|
116
|
+
* @extends Scroller.defaults
|
117
|
+
*/
|
118
|
+
this.s = {
|
119
|
+
/**
|
120
|
+
* DataTables settings object
|
121
|
+
* @type object
|
122
|
+
* @default Passed in as first parameter to constructor
|
123
|
+
*/
|
124
|
+
"dt": $.fn.dataTable.Api( dt ).settings()[0],
|
125
|
+
|
126
|
+
/**
|
127
|
+
* Pixel location of the top of the drawn table in the viewport
|
128
|
+
* @type int
|
129
|
+
* @default 0
|
130
|
+
*/
|
131
|
+
"tableTop": 0,
|
132
|
+
|
133
|
+
/**
|
134
|
+
* Pixel location of the bottom of the drawn table in the viewport
|
135
|
+
* @type int
|
136
|
+
* @default 0
|
137
|
+
*/
|
138
|
+
"tableBottom": 0,
|
139
|
+
|
140
|
+
/**
|
141
|
+
* Pixel location of the boundary for when the next data set should be loaded and drawn
|
142
|
+
* when scrolling up the way.
|
143
|
+
* @type int
|
144
|
+
* @default 0
|
145
|
+
* @private
|
146
|
+
*/
|
147
|
+
"redrawTop": 0,
|
148
|
+
|
149
|
+
/**
|
150
|
+
* Pixel location of the boundary for when the next data set should be loaded and drawn
|
151
|
+
* when scrolling down the way. Note that this is actually calculated as the offset from
|
152
|
+
* the top.
|
153
|
+
* @type int
|
154
|
+
* @default 0
|
155
|
+
* @private
|
156
|
+
*/
|
157
|
+
"redrawBottom": 0,
|
158
|
+
|
159
|
+
/**
|
160
|
+
* Auto row height or not indicator
|
161
|
+
* @type bool
|
162
|
+
* @default 0
|
163
|
+
*/
|
164
|
+
"autoHeight": true,
|
165
|
+
|
166
|
+
/**
|
167
|
+
* Number of rows calculated as visible in the visible viewport
|
168
|
+
* @type int
|
169
|
+
* @default 0
|
170
|
+
*/
|
171
|
+
"viewportRows": 0,
|
172
|
+
|
173
|
+
/**
|
174
|
+
* setTimeout reference for state saving, used when state saving is enabled in the DataTable
|
175
|
+
* and when the user scrolls the viewport in order to stop the cookie set taking too much
|
176
|
+
* CPU!
|
177
|
+
* @type int
|
178
|
+
* @default 0
|
179
|
+
*/
|
180
|
+
"stateTO": null,
|
181
|
+
|
182
|
+
/**
|
183
|
+
* setTimeout reference for the redraw, used when server-side processing is enabled in the
|
184
|
+
* DataTables in order to prevent DoSing the server
|
185
|
+
* @type int
|
186
|
+
* @default null
|
187
|
+
*/
|
188
|
+
"drawTO": null,
|
189
|
+
|
190
|
+
heights: {
|
191
|
+
jump: null,
|
192
|
+
page: null,
|
193
|
+
virtual: null,
|
194
|
+
scroll: null,
|
195
|
+
|
196
|
+
/**
|
197
|
+
* Height of rows in the table
|
198
|
+
* @type int
|
199
|
+
* @default 0
|
200
|
+
*/
|
201
|
+
row: null,
|
202
|
+
|
203
|
+
/**
|
204
|
+
* Pixel height of the viewport
|
205
|
+
* @type int
|
206
|
+
* @default 0
|
207
|
+
*/
|
208
|
+
viewport: null
|
209
|
+
},
|
210
|
+
|
211
|
+
topRowFloat: 0,
|
212
|
+
scrollDrawDiff: null,
|
213
|
+
loaderVisible: false
|
214
|
+
};
|
215
|
+
|
216
|
+
// @todo The defaults should extend a `c` property and the internal settings
|
217
|
+
// only held in the `s` property. At the moment they are mixed
|
218
|
+
this.s = $.extend( this.s, Scroller.oDefaults, opts );
|
219
|
+
|
220
|
+
// Workaround for row height being read from height object (see above comment)
|
221
|
+
this.s.heights.row = this.s.rowHeight;
|
222
|
+
|
223
|
+
/**
|
224
|
+
* DOM elements used by the class instance
|
225
|
+
* @private
|
226
|
+
* @namespace
|
227
|
+
*
|
228
|
+
*/
|
229
|
+
this.dom = {
|
230
|
+
"force": document.createElement('div'),
|
231
|
+
"scroller": null,
|
232
|
+
"table": null,
|
233
|
+
"loader": null
|
234
|
+
};
|
235
|
+
|
236
|
+
// Attach the instance to the DataTables instance so it can be accessed in
|
237
|
+
// future. Don't initialise Scroller twice on the same table
|
238
|
+
if ( this.s.dt.oScroller ) {
|
239
|
+
return;
|
240
|
+
}
|
241
|
+
|
242
|
+
this.s.dt.oScroller = this;
|
243
|
+
|
244
|
+
/* Let's do it */
|
245
|
+
this._fnConstruct();
|
246
|
+
};
|
247
|
+
|
248
|
+
|
249
|
+
|
250
|
+
$.extend( Scroller.prototype, {
|
251
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
252
|
+
* Public methods
|
253
|
+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
254
|
+
|
255
|
+
/**
|
256
|
+
* Calculate the pixel position from the top of the scrolling container for
|
257
|
+
* a given row
|
258
|
+
* @param {int} iRow Row number to calculate the position of
|
259
|
+
* @returns {int} Pixels
|
260
|
+
* @example
|
261
|
+
* $(document).ready(function() {
|
262
|
+
* $('#example').dataTable( {
|
263
|
+
* "sScrollY": "200px",
|
264
|
+
* "sAjaxSource": "media/dataset/large.txt",
|
265
|
+
* "sDom": "frtiS",
|
266
|
+
* "bDeferRender": true,
|
267
|
+
* "fnInitComplete": function (o) {
|
268
|
+
* // Find where row 25 is
|
269
|
+
* alert( o.oScroller.fnRowToPixels( 25 ) );
|
270
|
+
* }
|
271
|
+
* } );
|
272
|
+
* } );
|
273
|
+
*/
|
274
|
+
"fnRowToPixels": function ( rowIdx, intParse, virtual )
|
275
|
+
{
|
276
|
+
var pixels;
|
277
|
+
|
278
|
+
if ( virtual ) {
|
279
|
+
pixels = this._domain( 'virtualToPhysical', rowIdx * this.s.heights.row );
|
280
|
+
}
|
281
|
+
else {
|
282
|
+
var diff = rowIdx - this.s.baseRowTop;
|
283
|
+
pixels = this.s.baseScrollTop + (diff * this.s.heights.row);
|
284
|
+
}
|
285
|
+
|
286
|
+
return intParse || intParse === undefined ?
|
287
|
+
parseInt( pixels, 10 ) :
|
288
|
+
pixels;
|
289
|
+
},
|
290
|
+
|
291
|
+
|
292
|
+
/**
|
293
|
+
* Calculate the row number that will be found at the given pixel position
|
294
|
+
* (y-scroll).
|
295
|
+
*
|
296
|
+
* Please note that when the height of the full table exceeds 1 million
|
297
|
+
* pixels, Scroller switches into a non-linear mode for the scrollbar to fit
|
298
|
+
* all of the records into a finite area, but this function returns a linear
|
299
|
+
* value (relative to the last non-linear positioning).
|
300
|
+
* @param {int} iPixels Offset from top to calculate the row number of
|
301
|
+
* @param {int} [intParse=true] If an integer value should be returned
|
302
|
+
* @param {int} [virtual=false] Perform the calculations in the virtual domain
|
303
|
+
* @returns {int} Row index
|
304
|
+
* @example
|
305
|
+
* $(document).ready(function() {
|
306
|
+
* $('#example').dataTable( {
|
307
|
+
* "sScrollY": "200px",
|
308
|
+
* "sAjaxSource": "media/dataset/large.txt",
|
309
|
+
* "sDom": "frtiS",
|
310
|
+
* "bDeferRender": true,
|
311
|
+
* "fnInitComplete": function (o) {
|
312
|
+
* // Find what row number is at 500px
|
313
|
+
* alert( o.oScroller.fnPixelsToRow( 500 ) );
|
314
|
+
* }
|
315
|
+
* } );
|
316
|
+
* } );
|
317
|
+
*/
|
318
|
+
"fnPixelsToRow": function ( pixels, intParse, virtual )
|
319
|
+
{
|
320
|
+
var diff = pixels - this.s.baseScrollTop;
|
321
|
+
var row = virtual ?
|
322
|
+
this._domain( 'physicalToVirtual', pixels ) / this.s.heights.row :
|
323
|
+
( diff / this.s.heights.row ) + this.s.baseRowTop;
|
324
|
+
|
325
|
+
return intParse || intParse === undefined ?
|
326
|
+
parseInt( row, 10 ) :
|
327
|
+
row;
|
328
|
+
},
|
329
|
+
|
330
|
+
|
331
|
+
/**
|
332
|
+
* Calculate the row number that will be found at the given pixel position (y-scroll)
|
333
|
+
* @param {int} iRow Row index to scroll to
|
334
|
+
* @param {bool} [bAnimate=true] Animate the transition or not
|
335
|
+
* @returns {void}
|
336
|
+
* @example
|
337
|
+
* $(document).ready(function() {
|
338
|
+
* $('#example').dataTable( {
|
339
|
+
* "sScrollY": "200px",
|
340
|
+
* "sAjaxSource": "media/dataset/large.txt",
|
341
|
+
* "sDom": "frtiS",
|
342
|
+
* "bDeferRender": true,
|
343
|
+
* "fnInitComplete": function (o) {
|
344
|
+
* // Immediately scroll to row 1000
|
345
|
+
* o.oScroller.fnScrollToRow( 1000 );
|
346
|
+
* }
|
347
|
+
* } );
|
348
|
+
*
|
349
|
+
* // Sometime later on use the following to scroll to row 500...
|
350
|
+
* var oSettings = $('#example').dataTable().fnSettings();
|
351
|
+
* oSettings.oScroller.fnScrollToRow( 500 );
|
352
|
+
* } );
|
353
|
+
*/
|
354
|
+
"fnScrollToRow": function ( iRow, bAnimate )
|
355
|
+
{
|
356
|
+
var that = this;
|
357
|
+
var ani = false;
|
358
|
+
var px = this.fnRowToPixels( iRow );
|
359
|
+
|
360
|
+
// We need to know if the table will redraw or not before doing the
|
361
|
+
// scroll. If it will not redraw, then we need to use the currently
|
362
|
+
// displayed table, and scroll with the physical pixels. Otherwise, we
|
363
|
+
// need to calculate the table's new position from the virtual
|
364
|
+
// transform.
|
365
|
+
var preRows = ((this.s.displayBuffer-1)/2) * this.s.viewportRows;
|
366
|
+
var drawRow = iRow - preRows;
|
367
|
+
if ( drawRow < 0 ) {
|
368
|
+
drawRow = 0;
|
369
|
+
}
|
370
|
+
|
371
|
+
if ( (px > this.s.redrawBottom || px < this.s.redrawTop) && this.s.dt._iDisplayStart !== drawRow ) {
|
372
|
+
ani = true;
|
373
|
+
px = this.fnRowToPixels( iRow, false, true );
|
374
|
+
}
|
375
|
+
|
376
|
+
if ( typeof bAnimate == 'undefined' || bAnimate )
|
377
|
+
{
|
378
|
+
this.s.ani = ani;
|
379
|
+
$(this.dom.scroller).animate( {
|
380
|
+
"scrollTop": px
|
381
|
+
}, function () {
|
382
|
+
// This needs to happen after the animation has completed and
|
383
|
+
// the final scroll event fired
|
384
|
+
setTimeout( function () {
|
385
|
+
that.s.ani = false;
|
386
|
+
}, 25 );
|
387
|
+
} );
|
388
|
+
}
|
389
|
+
else
|
390
|
+
{
|
391
|
+
$(this.dom.scroller).scrollTop( px );
|
392
|
+
}
|
393
|
+
},
|
394
|
+
|
395
|
+
|
396
|
+
/**
|
397
|
+
* Calculate and store information about how many rows are to be displayed
|
398
|
+
* in the scrolling viewport, based on current dimensions in the browser's
|
399
|
+
* rendering. This can be particularly useful if the table is initially
|
400
|
+
* drawn in a hidden element - for example in a tab.
|
401
|
+
* @param {bool} [bRedraw=true] Redraw the table automatically after the recalculation, with
|
402
|
+
* the new dimensions forming the basis for the draw.
|
403
|
+
* @returns {void}
|
404
|
+
* @example
|
405
|
+
* $(document).ready(function() {
|
406
|
+
* // Make the example container hidden to throw off the browser's sizing
|
407
|
+
* document.getElementById('container').style.display = "none";
|
408
|
+
* var oTable = $('#example').dataTable( {
|
409
|
+
* "sScrollY": "200px",
|
410
|
+
* "sAjaxSource": "media/dataset/large.txt",
|
411
|
+
* "sDom": "frtiS",
|
412
|
+
* "bDeferRender": true,
|
413
|
+
* "fnInitComplete": function (o) {
|
414
|
+
* // Immediately scroll to row 1000
|
415
|
+
* o.oScroller.fnScrollToRow( 1000 );
|
416
|
+
* }
|
417
|
+
* } );
|
418
|
+
*
|
419
|
+
* setTimeout( function () {
|
420
|
+
* // Make the example container visible and recalculate the scroller sizes
|
421
|
+
* document.getElementById('container').style.display = "block";
|
422
|
+
* oTable.fnSettings().oScroller.fnMeasure();
|
423
|
+
* }, 3000 );
|
424
|
+
*/
|
425
|
+
"fnMeasure": function ( bRedraw )
|
426
|
+
{
|
427
|
+
if ( this.s.autoHeight )
|
428
|
+
{
|
429
|
+
this._fnCalcRowHeight();
|
430
|
+
}
|
431
|
+
|
432
|
+
var heights = this.s.heights;
|
433
|
+
|
434
|
+
if ( heights.row ) {
|
435
|
+
heights.viewport = $(this.dom.scroller).height();
|
436
|
+
this.s.viewportRows = parseInt( heights.viewport / heights.row, 10 )+1;
|
437
|
+
this.s.dt._iDisplayLength = this.s.viewportRows * this.s.displayBuffer;
|
438
|
+
}
|
439
|
+
|
440
|
+
if ( bRedraw === undefined || bRedraw )
|
441
|
+
{
|
442
|
+
this.s.dt.oInstance.fnDraw( false );
|
443
|
+
}
|
444
|
+
},
|
445
|
+
|
446
|
+
|
447
|
+
/**
|
448
|
+
* Get information about current displayed record range. This corresponds to
|
449
|
+
* the information usually displayed in the "Info" block of the table.
|
450
|
+
*
|
451
|
+
* @returns {object} info as an object:
|
452
|
+
* {
|
453
|
+
* start: {int}, // the 0-indexed record at the top of the viewport
|
454
|
+
* end: {int}, // the 0-indexed record at the bottom of the viewport
|
455
|
+
* }
|
456
|
+
*/
|
457
|
+
"fnPageInfo": function()
|
458
|
+
{
|
459
|
+
var
|
460
|
+
dt = this.s.dt,
|
461
|
+
iScrollTop = this.dom.scroller.scrollTop,
|
462
|
+
iTotal = dt.fnRecordsDisplay(),
|
463
|
+
iPossibleEnd = Math.ceil(this.fnPixelsToRow(iScrollTop + this.s.heights.viewport, false, this.s.ani));
|
464
|
+
|
465
|
+
return {
|
466
|
+
start: Math.floor(this.fnPixelsToRow(iScrollTop, false, this.s.ani)),
|
467
|
+
end: iTotal < iPossibleEnd ? iTotal-1 : iPossibleEnd-1
|
468
|
+
};
|
469
|
+
},
|
470
|
+
|
471
|
+
|
472
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
473
|
+
* Private methods (they are of course public in JS, but recommended as private)
|
474
|
+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
475
|
+
|
476
|
+
/**
|
477
|
+
* Initialisation for Scroller
|
478
|
+
* @returns {void}
|
479
|
+
* @private
|
480
|
+
*/
|
481
|
+
"_fnConstruct": function ()
|
482
|
+
{
|
483
|
+
var that = this;
|
484
|
+
|
485
|
+
/* Sanity check */
|
486
|
+
if ( !this.s.dt.oFeatures.bPaginate ) {
|
487
|
+
this.s.dt.oApi._fnLog( this.s.dt, 0, 'Pagination must be enabled for Scroller' );
|
488
|
+
return;
|
489
|
+
}
|
490
|
+
|
491
|
+
/* Insert a div element that we can use to force the DT scrolling container to
|
492
|
+
* the height that would be required if the whole table was being displayed
|
493
|
+
*/
|
494
|
+
this.dom.force.style.position = "relative";
|
495
|
+
this.dom.force.style.top = "0px";
|
496
|
+
this.dom.force.style.left = "0px";
|
497
|
+
this.dom.force.style.width = "1px";
|
498
|
+
|
499
|
+
this.dom.scroller = $('div.'+this.s.dt.oClasses.sScrollBody, this.s.dt.nTableWrapper)[0];
|
500
|
+
this.dom.scroller.appendChild( this.dom.force );
|
501
|
+
this.dom.scroller.style.position = "relative";
|
502
|
+
|
503
|
+
this.dom.table = $('>table', this.dom.scroller)[0];
|
504
|
+
this.dom.table.style.position = "absolute";
|
505
|
+
this.dom.table.style.top = "0px";
|
506
|
+
this.dom.table.style.left = "0px";
|
507
|
+
|
508
|
+
// Add class to 'announce' that we are a Scroller table
|
509
|
+
$(this.s.dt.nTableWrapper).addClass('DTS');
|
510
|
+
|
511
|
+
// Add a 'loading' indicator
|
512
|
+
if ( this.s.loadingIndicator )
|
513
|
+
{
|
514
|
+
this.dom.loader = $('<div class="dataTables_processing DTS_Loading">'+this.s.dt.oLanguage.sLoadingRecords+'</div>')
|
515
|
+
.css('display', 'none');
|
516
|
+
|
517
|
+
$(this.dom.scroller.parentNode)
|
518
|
+
.css('position', 'relative')
|
519
|
+
.append( this.dom.loader );
|
520
|
+
}
|
521
|
+
|
522
|
+
/* Initial size calculations */
|
523
|
+
if ( this.s.heights.row && this.s.heights.row != 'auto' )
|
524
|
+
{
|
525
|
+
this.s.autoHeight = false;
|
526
|
+
}
|
527
|
+
this.fnMeasure( false );
|
528
|
+
|
529
|
+
/* Scrolling callback to see if a page change is needed - use a throttled
|
530
|
+
* function for the save save callback so we aren't hitting it on every
|
531
|
+
* scroll
|
532
|
+
*/
|
533
|
+
this.s.ingnoreScroll = true;
|
534
|
+
this.s.stateSaveThrottle = this.s.dt.oApi._fnThrottle( function () {
|
535
|
+
that.s.dt.oApi._fnSaveState( that.s.dt );
|
536
|
+
}, 500 );
|
537
|
+
$(this.dom.scroller).on( 'scroll.DTS', function (e) {
|
538
|
+
that._fnScroll.call( that );
|
539
|
+
} );
|
540
|
+
|
541
|
+
/* In iOS we catch the touchstart event in case the user tries to scroll
|
542
|
+
* while the display is already scrolling
|
543
|
+
*/
|
544
|
+
$(this.dom.scroller).on('touchstart.DTS', function () {
|
545
|
+
that._fnScroll.call( that );
|
546
|
+
} );
|
547
|
+
|
548
|
+
/* Update the scroller when the DataTable is redrawn */
|
549
|
+
this.s.dt.aoDrawCallback.push( {
|
550
|
+
"fn": function () {
|
551
|
+
if ( that.s.dt.bInitialised ) {
|
552
|
+
that._fnDrawCallback.call( that );
|
553
|
+
}
|
554
|
+
},
|
555
|
+
"sName": "Scroller"
|
556
|
+
} );
|
557
|
+
|
558
|
+
/* On resize, update the information element, since the number of rows shown might change */
|
559
|
+
$(window).on( 'resize.DTS', function () {
|
560
|
+
that.fnMeasure( false );
|
561
|
+
that._fnInfo();
|
562
|
+
} );
|
563
|
+
|
564
|
+
/* Add a state saving parameter to the DT state saving so we can restore the exact
|
565
|
+
* position of the scrolling
|
566
|
+
*/
|
567
|
+
var initialStateSave = true;
|
568
|
+
this.s.dt.oApi._fnCallbackReg( this.s.dt, 'aoStateSaveParams', function (oS, oData) {
|
569
|
+
/* Set iScroller to saved scroll position on initialization.
|
570
|
+
*/
|
571
|
+
if(initialStateSave && that.s.dt.oLoadedState){
|
572
|
+
oData.iScroller = that.s.dt.oLoadedState.iScroller;
|
573
|
+
oData.iScrollerTopRow = that.s.dt.oLoadedState.iScrollerTopRow;
|
574
|
+
initialStateSave = false;
|
575
|
+
} else {
|
576
|
+
oData.iScroller = that.dom.scroller.scrollTop;
|
577
|
+
oData.iScrollerTopRow = that.s.topRowFloat;
|
578
|
+
}
|
579
|
+
}, "Scroller_State" );
|
580
|
+
|
581
|
+
if ( this.s.dt.oLoadedState ) {
|
582
|
+
this.s.topRowFloat = this.s.dt.oLoadedState.iScrollerTopRow || 0;
|
583
|
+
}
|
584
|
+
|
585
|
+
// Measure immediately. Scroller will have been added using preInit, so
|
586
|
+
// we can reliably do this here. We could potentially also measure on
|
587
|
+
// init complete, which would be useful for cases where the data is Ajax
|
588
|
+
// loaded and longer than a single line.
|
589
|
+
$(this.s.dt.nTable).one( 'init.dt', function () {
|
590
|
+
that.fnMeasure();
|
591
|
+
} );
|
592
|
+
|
593
|
+
/* Destructor */
|
594
|
+
this.s.dt.aoDestroyCallback.push( {
|
595
|
+
"sName": "Scroller",
|
596
|
+
"fn": function () {
|
597
|
+
$(window).off( 'resize.DTS' );
|
598
|
+
$(that.dom.scroller).off('touchstart.DTS scroll.DTS');
|
599
|
+
$(that.s.dt.nTableWrapper).removeClass('DTS');
|
600
|
+
$('div.DTS_Loading', that.dom.scroller.parentNode).remove();
|
601
|
+
$(that.s.dt.nTable).off( 'init.dt' );
|
602
|
+
|
603
|
+
that.dom.table.style.position = "";
|
604
|
+
that.dom.table.style.top = "";
|
605
|
+
that.dom.table.style.left = "";
|
606
|
+
}
|
607
|
+
} );
|
608
|
+
},
|
609
|
+
|
610
|
+
|
611
|
+
/**
|
612
|
+
* Scrolling function - fired whenever the scrolling position is changed.
|
613
|
+
* This method needs to use the stored values to see if the table should be
|
614
|
+
* redrawn as we are moving towards the end of the information that is
|
615
|
+
* currently drawn or not. If needed, then it will redraw the table based on
|
616
|
+
* the new position.
|
617
|
+
* @returns {void}
|
618
|
+
* @private
|
619
|
+
*/
|
620
|
+
"_fnScroll": function ()
|
621
|
+
{
|
622
|
+
var
|
623
|
+
that = this,
|
624
|
+
heights = this.s.heights,
|
625
|
+
iScrollTop = this.dom.scroller.scrollTop,
|
626
|
+
iTopRow;
|
627
|
+
|
628
|
+
if ( this.s.skip ) {
|
629
|
+
return;
|
630
|
+
}
|
631
|
+
|
632
|
+
if ( this.s.ingnoreScroll ) {
|
633
|
+
return;
|
634
|
+
}
|
635
|
+
|
636
|
+
/* If the table has been sorted or filtered, then we use the redraw that
|
637
|
+
* DataTables as done, rather than performing our own
|
638
|
+
*/
|
639
|
+
if ( this.s.dt.bFiltered || this.s.dt.bSorted ) {
|
640
|
+
this.s.lastScrollTop = 0;
|
641
|
+
return;
|
642
|
+
}
|
643
|
+
|
644
|
+
/* Update the table's information display for what is now in the viewport */
|
645
|
+
this._fnInfo();
|
646
|
+
|
647
|
+
/* We don't want to state save on every scroll event - that's heavy
|
648
|
+
* handed, so use a timeout to update the state saving only when the
|
649
|
+
* scrolling has finished
|
650
|
+
*/
|
651
|
+
clearTimeout( this.s.stateTO );
|
652
|
+
this.s.stateTO = setTimeout( function () {
|
653
|
+
that.s.dt.oApi._fnSaveState( that.s.dt );
|
654
|
+
}, 250 );
|
655
|
+
|
656
|
+
/* Check if the scroll point is outside the trigger boundary which would required
|
657
|
+
* a DataTables redraw
|
658
|
+
*/
|
659
|
+
if ( iScrollTop < this.s.redrawTop || iScrollTop > this.s.redrawBottom ) {
|
660
|
+
var preRows = Math.ceil( ((this.s.displayBuffer-1)/2) * this.s.viewportRows );
|
661
|
+
|
662
|
+
if ( Math.abs( iScrollTop - this.s.lastScrollTop ) > heights.viewport || this.s.ani ) {
|
663
|
+
iTopRow = parseInt(this._domain( 'physicalToVirtual', iScrollTop ) / heights.row, 10) - preRows;
|
664
|
+
this.s.topRowFloat = this._domain( 'physicalToVirtual', iScrollTop ) / heights.row;
|
665
|
+
}
|
666
|
+
else {
|
667
|
+
iTopRow = this.fnPixelsToRow( iScrollTop ) - preRows;
|
668
|
+
this.s.topRowFloat = this.fnPixelsToRow( iScrollTop, false );
|
669
|
+
}
|
670
|
+
|
671
|
+
if ( iTopRow <= 0 ) {
|
672
|
+
/* At the start of the table */
|
673
|
+
iTopRow = 0;
|
674
|
+
}
|
675
|
+
else if ( iTopRow + this.s.dt._iDisplayLength > this.s.dt.fnRecordsDisplay() ) {
|
676
|
+
/* At the end of the table */
|
677
|
+
iTopRow = this.s.dt.fnRecordsDisplay() - this.s.dt._iDisplayLength;
|
678
|
+
if ( iTopRow < 0 ) {
|
679
|
+
iTopRow = 0;
|
680
|
+
}
|
681
|
+
}
|
682
|
+
else if ( iTopRow % 2 !== 0 ) {
|
683
|
+
// For the row-striping classes (odd/even) we want only to start
|
684
|
+
// on evens otherwise the stripes will change between draws and
|
685
|
+
// look rubbish
|
686
|
+
iTopRow++;
|
687
|
+
}
|
688
|
+
|
689
|
+
if ( iTopRow != this.s.dt._iDisplayStart ) {
|
690
|
+
/* Cache the new table position for quick lookups */
|
691
|
+
this.s.tableTop = $(this.s.dt.nTable).offset().top;
|
692
|
+
this.s.tableBottom = $(this.s.dt.nTable).height() + this.s.tableTop;
|
693
|
+
|
694
|
+
var draw = function () {
|
695
|
+
if ( that.s.scrollDrawReq === null ) {
|
696
|
+
that.s.scrollDrawReq = iScrollTop;
|
697
|
+
}
|
698
|
+
|
699
|
+
that.s.dt._iDisplayStart = iTopRow;
|
700
|
+
that.s.dt.oApi._fnDraw( that.s.dt );
|
701
|
+
};
|
702
|
+
|
703
|
+
/* Do the DataTables redraw based on the calculated start point - note that when
|
704
|
+
* using server-side processing we introduce a small delay to not DoS the server...
|
705
|
+
*/
|
706
|
+
if ( this.s.dt.oFeatures.bServerSide ) {
|
707
|
+
clearTimeout( this.s.drawTO );
|
708
|
+
this.s.drawTO = setTimeout( draw, this.s.serverWait );
|
709
|
+
}
|
710
|
+
else {
|
711
|
+
draw();
|
712
|
+
}
|
713
|
+
|
714
|
+
if ( this.dom.loader && ! this.s.loaderVisible ) {
|
715
|
+
this.dom.loader.css( 'display', 'block' );
|
716
|
+
this.s.loaderVisible = true;
|
717
|
+
}
|
718
|
+
}
|
719
|
+
}
|
720
|
+
else {
|
721
|
+
this.s.topRowFloat = this._domain( 'physicalToVirtual', iScrollTop ) / heights.row;
|
722
|
+
}
|
723
|
+
|
724
|
+
this.s.lastScrollTop = iScrollTop;
|
725
|
+
this.s.stateSaveThrottle();
|
726
|
+
},
|
727
|
+
|
728
|
+
|
729
|
+
/**
|
730
|
+
* Convert from one domain to another. The physical domain is the actual
|
731
|
+
* pixel count on the screen, while the virtual is if we had browsers which
|
732
|
+
* had scrolling containers of infinite height (i.e. the absolute value)
|
733
|
+
*
|
734
|
+
* @param {string} dir Domain transform direction, `virtualToPhysical` or
|
735
|
+
* `physicalToVirtual`
|
736
|
+
* @returns {number} Calculated transform
|
737
|
+
* @private
|
738
|
+
*/
|
739
|
+
_domain: function ( dir, val )
|
740
|
+
{
|
741
|
+
var heights = this.s.heights;
|
742
|
+
var coeff;
|
743
|
+
|
744
|
+
// If the virtual and physical height match, then we use a linear
|
745
|
+
// transform between the two, allowing the scrollbar to be linear
|
746
|
+
if ( heights.virtual === heights.scroll ) {
|
747
|
+
return val;
|
748
|
+
}
|
749
|
+
|
750
|
+
// Otherwise, we want a non-linear scrollbar to take account of the
|
751
|
+
// redrawing regions at the start and end of the table, otherwise these
|
752
|
+
// can stutter badly - on large tables 30px (for example) scroll might
|
753
|
+
// be hundreds of rows, so the table would be redrawing every few px at
|
754
|
+
// the start and end. Use a simple quadratic to stop this. It does mean
|
755
|
+
// the scrollbar is non-linear, but with such massive data sets, the
|
756
|
+
// scrollbar is going to be a best guess anyway
|
757
|
+
var xMax = (heights.scroll - heights.viewport) / 2;
|
758
|
+
var yMax = (heights.virtual - heights.viewport) / 2;
|
759
|
+
|
760
|
+
coeff = yMax / ( xMax * xMax );
|
761
|
+
|
762
|
+
if ( dir === 'virtualToPhysical' ) {
|
763
|
+
if ( val < yMax ) {
|
764
|
+
return Math.pow(val / coeff, 0.5);
|
765
|
+
}
|
766
|
+
else {
|
767
|
+
val = (yMax*2) - val;
|
768
|
+
return val < 0 ?
|
769
|
+
heights.scroll :
|
770
|
+
(xMax*2) - Math.pow(val / coeff, 0.5);
|
771
|
+
}
|
772
|
+
}
|
773
|
+
else if ( dir === 'physicalToVirtual' ) {
|
774
|
+
if ( val < xMax ) {
|
775
|
+
return val * val * coeff;
|
776
|
+
}
|
777
|
+
else {
|
778
|
+
val = (xMax*2) - val;
|
779
|
+
return val < 0 ?
|
780
|
+
heights.virtual :
|
781
|
+
(yMax*2) - (val * val * coeff);
|
782
|
+
}
|
783
|
+
}
|
784
|
+
},
|
785
|
+
|
786
|
+
|
787
|
+
/**
|
788
|
+
* Draw callback function which is fired when the DataTable is redrawn. The main function of
|
789
|
+
* this method is to position the drawn table correctly the scrolling container for the rows
|
790
|
+
* that is displays as a result of the scrolling position.
|
791
|
+
* @returns {void}
|
792
|
+
* @private
|
793
|
+
*/
|
794
|
+
"_fnDrawCallback": function ()
|
795
|
+
{
|
796
|
+
var
|
797
|
+
that = this,
|
798
|
+
heights = this.s.heights,
|
799
|
+
iScrollTop = this.dom.scroller.scrollTop,
|
800
|
+
iActualScrollTop = iScrollTop,
|
801
|
+
iScrollBottom = iScrollTop + heights.viewport,
|
802
|
+
iTableHeight = $(this.s.dt.nTable).height(),
|
803
|
+
displayStart = this.s.dt._iDisplayStart,
|
804
|
+
displayLen = this.s.dt._iDisplayLength,
|
805
|
+
displayEnd = this.s.dt.fnRecordsDisplay();
|
806
|
+
|
807
|
+
// Disable the scroll event listener while we are updating the DOM
|
808
|
+
this.s.skip = true;
|
809
|
+
|
810
|
+
// Resize the scroll forcing element
|
811
|
+
this._fnScrollForce();
|
812
|
+
|
813
|
+
// Reposition the scrolling for the updated virtual position if needed
|
814
|
+
if ( displayStart === 0 ) {
|
815
|
+
// Linear calculation at the top of the table
|
816
|
+
iScrollTop = this.s.topRowFloat * heights.row;
|
817
|
+
}
|
818
|
+
else if ( displayStart + displayLen >= displayEnd ) {
|
819
|
+
// Linear calculation that the bottom as well
|
820
|
+
iScrollTop = heights.scroll - ((displayEnd - this.s.topRowFloat) * heights.row);
|
821
|
+
}
|
822
|
+
else {
|
823
|
+
// Domain scaled in the middle
|
824
|
+
iScrollTop = this._domain( 'virtualToPhysical', this.s.topRowFloat * heights.row );
|
825
|
+
}
|
826
|
+
|
827
|
+
this.dom.scroller.scrollTop = iScrollTop;
|
828
|
+
|
829
|
+
// Store positional information so positional calculations can be based
|
830
|
+
// upon the current table draw position
|
831
|
+
this.s.baseScrollTop = iScrollTop;
|
832
|
+
this.s.baseRowTop = this.s.topRowFloat;
|
833
|
+
|
834
|
+
// Position the table in the virtual scroller
|
835
|
+
var tableTop = iScrollTop - ((this.s.topRowFloat - displayStart) * heights.row);
|
836
|
+
if ( displayStart === 0 ) {
|
837
|
+
tableTop = 0;
|
838
|
+
}
|
839
|
+
else if ( displayStart + displayLen >= displayEnd ) {
|
840
|
+
tableTop = heights.scroll - iTableHeight;
|
841
|
+
}
|
842
|
+
|
843
|
+
this.dom.table.style.top = tableTop+'px';
|
844
|
+
|
845
|
+
/* Cache some information for the scroller */
|
846
|
+
this.s.tableTop = tableTop;
|
847
|
+
this.s.tableBottom = iTableHeight + this.s.tableTop;
|
848
|
+
|
849
|
+
// Calculate the boundaries for where a redraw will be triggered by the
|
850
|
+
// scroll event listener
|
851
|
+
var boundaryPx = (iScrollTop - this.s.tableTop) * this.s.boundaryScale;
|
852
|
+
this.s.redrawTop = iScrollTop - boundaryPx;
|
853
|
+
this.s.redrawBottom = iScrollTop + boundaryPx;
|
854
|
+
|
855
|
+
this.s.skip = false;
|
856
|
+
|
857
|
+
// Restore the scrolling position that was saved by DataTable's state
|
858
|
+
// saving Note that this is done on the second draw when data is Ajax
|
859
|
+
// sourced, and the first draw when DOM soured
|
860
|
+
if ( this.s.dt.oFeatures.bStateSave && this.s.dt.oLoadedState !== null &&
|
861
|
+
typeof this.s.dt.oLoadedState.iScroller != 'undefined' )
|
862
|
+
{
|
863
|
+
// A quirk of DataTables is that the draw callback will occur on an
|
864
|
+
// empty set if Ajax sourced, but not if server-side processing.
|
865
|
+
var ajaxSourced = (this.s.dt.sAjaxSource || that.s.dt.ajax) && ! this.s.dt.oFeatures.bServerSide ?
|
866
|
+
true :
|
867
|
+
false;
|
868
|
+
|
869
|
+
if ( ( ajaxSourced && this.s.dt.iDraw == 2) ||
|
870
|
+
(!ajaxSourced && this.s.dt.iDraw == 1) )
|
871
|
+
{
|
872
|
+
setTimeout( function () {
|
873
|
+
$(that.dom.scroller).scrollTop( that.s.dt.oLoadedState.iScroller );
|
874
|
+
that.s.redrawTop = that.s.dt.oLoadedState.iScroller - (heights.viewport/2);
|
875
|
+
|
876
|
+
// In order to prevent layout thrashing we need another
|
877
|
+
// small delay
|
878
|
+
setTimeout( function () {
|
879
|
+
that.s.ingnoreScroll = false;
|
880
|
+
}, 0 );
|
881
|
+
}, 0 );
|
882
|
+
}
|
883
|
+
}
|
884
|
+
else {
|
885
|
+
that.s.ingnoreScroll = false;
|
886
|
+
}
|
887
|
+
|
888
|
+
// Because of the order of the DT callbacks, the info update will
|
889
|
+
// take precedence over the one we want here. So a 'thread' break is
|
890
|
+
// needed. Only add the thread break if bInfo is set
|
891
|
+
if ( this.s.dt.oFeatures.bInfo ) {
|
892
|
+
setTimeout( function () {
|
893
|
+
that._fnInfo.call( that );
|
894
|
+
}, 0 );
|
895
|
+
}
|
896
|
+
|
897
|
+
// Hide the loading indicator
|
898
|
+
if ( this.dom.loader && this.s.loaderVisible ) {
|
899
|
+
this.dom.loader.css( 'display', 'none' );
|
900
|
+
this.s.loaderVisible = false;
|
901
|
+
}
|
902
|
+
},
|
903
|
+
|
904
|
+
|
905
|
+
/**
|
906
|
+
* Force the scrolling container to have height beyond that of just the
|
907
|
+
* table that has been drawn so the user can scroll the whole data set.
|
908
|
+
*
|
909
|
+
* Note that if the calculated required scrolling height exceeds a maximum
|
910
|
+
* value (1 million pixels - hard-coded) the forcing element will be set
|
911
|
+
* only to that maximum value and virtual / physical domain transforms will
|
912
|
+
* be used to allow Scroller to display tables of any number of records.
|
913
|
+
* @returns {void}
|
914
|
+
* @private
|
915
|
+
*/
|
916
|
+
_fnScrollForce: function ()
|
917
|
+
{
|
918
|
+
var heights = this.s.heights;
|
919
|
+
var max = 1000000;
|
920
|
+
|
921
|
+
heights.virtual = heights.row * this.s.dt.fnRecordsDisplay();
|
922
|
+
heights.scroll = heights.virtual;
|
923
|
+
|
924
|
+
if ( heights.scroll > max ) {
|
925
|
+
heights.scroll = max;
|
926
|
+
}
|
927
|
+
|
928
|
+
// Minimum height so there is always a row visible (the 'no rows found'
|
929
|
+
// if reduced to zero filtering)
|
930
|
+
this.dom.force.style.height = heights.scroll > this.s.heights.row ?
|
931
|
+
heights.scroll+'px' :
|
932
|
+
this.s.heights.row+'px';
|
933
|
+
},
|
934
|
+
|
935
|
+
|
936
|
+
/**
|
937
|
+
* Automatic calculation of table row height. This is just a little tricky here as using
|
938
|
+
* initialisation DataTables has tale the table out of the document, so we need to create
|
939
|
+
* a new table and insert it into the document, calculate the row height and then whip the
|
940
|
+
* table out.
|
941
|
+
* @returns {void}
|
942
|
+
* @private
|
943
|
+
*/
|
944
|
+
"_fnCalcRowHeight": function ()
|
945
|
+
{
|
946
|
+
var dt = this.s.dt;
|
947
|
+
var origTable = dt.nTable;
|
948
|
+
var nTable = origTable.cloneNode( false );
|
949
|
+
var tbody = $('<tbody/>').appendTo( nTable );
|
950
|
+
var container = $(
|
951
|
+
'<div class="'+dt.oClasses.sWrapper+' DTS">'+
|
952
|
+
'<div class="'+dt.oClasses.sScrollWrapper+'">'+
|
953
|
+
'<div class="'+dt.oClasses.sScrollBody+'"></div>'+
|
954
|
+
'</div>'+
|
955
|
+
'</div>'
|
956
|
+
);
|
957
|
+
|
958
|
+
// Want 3 rows in the sizing table so :first-child and :last-child
|
959
|
+
// CSS styles don't come into play - take the size of the middle row
|
960
|
+
$('tbody tr:lt(4)', origTable).clone().appendTo( tbody );
|
961
|
+
while( $('tr', tbody).length < 3 ) {
|
962
|
+
tbody.append( '<tr><td> </td></tr>' );
|
963
|
+
}
|
964
|
+
|
965
|
+
$('div.'+dt.oClasses.sScrollBody, container).append( nTable );
|
966
|
+
|
967
|
+
// If initialised using `dom`, use the holding element as the insert point
|
968
|
+
var insertEl = this.s.dt.nHolding || origTable.parentNode;
|
969
|
+
|
970
|
+
if ( ! $(insertEl).is(':visible') ) {
|
971
|
+
insertEl = 'body';
|
972
|
+
}
|
973
|
+
|
974
|
+
container.appendTo( insertEl );
|
975
|
+
this.s.heights.row = $('tr', tbody).eq(1).outerHeight();
|
976
|
+
|
977
|
+
container.remove();
|
978
|
+
},
|
979
|
+
|
980
|
+
|
981
|
+
/**
|
982
|
+
* Update any information elements that are controlled by the DataTable based on the scrolling
|
983
|
+
* viewport and what rows are visible in it. This function basically acts in the same way as
|
984
|
+
* _fnUpdateInfo in DataTables, and effectively replaces that function.
|
985
|
+
* @returns {void}
|
986
|
+
* @private
|
987
|
+
*/
|
988
|
+
"_fnInfo": function ()
|
989
|
+
{
|
990
|
+
if ( !this.s.dt.oFeatures.bInfo )
|
991
|
+
{
|
992
|
+
return;
|
993
|
+
}
|
994
|
+
|
995
|
+
var
|
996
|
+
dt = this.s.dt,
|
997
|
+
language = dt.oLanguage,
|
998
|
+
iScrollTop = this.dom.scroller.scrollTop,
|
999
|
+
iStart = Math.floor( this.fnPixelsToRow(iScrollTop, false, this.s.ani)+1 ),
|
1000
|
+
iMax = dt.fnRecordsTotal(),
|
1001
|
+
iTotal = dt.fnRecordsDisplay(),
|
1002
|
+
iPossibleEnd = Math.ceil( this.fnPixelsToRow(iScrollTop+this.s.heights.viewport, false, this.s.ani) ),
|
1003
|
+
iEnd = iTotal < iPossibleEnd ? iTotal : iPossibleEnd,
|
1004
|
+
sStart = dt.fnFormatNumber( iStart ),
|
1005
|
+
sEnd = dt.fnFormatNumber( iEnd ),
|
1006
|
+
sMax = dt.fnFormatNumber( iMax ),
|
1007
|
+
sTotal = dt.fnFormatNumber( iTotal ),
|
1008
|
+
sOut;
|
1009
|
+
|
1010
|
+
if ( dt.fnRecordsDisplay() === 0 &&
|
1011
|
+
dt.fnRecordsDisplay() == dt.fnRecordsTotal() )
|
1012
|
+
{
|
1013
|
+
/* Empty record set */
|
1014
|
+
sOut = language.sInfoEmpty+ language.sInfoPostFix;
|
1015
|
+
}
|
1016
|
+
else if ( dt.fnRecordsDisplay() === 0 )
|
1017
|
+
{
|
1018
|
+
/* Empty record set after filtering */
|
1019
|
+
sOut = language.sInfoEmpty +' '+
|
1020
|
+
language.sInfoFiltered.replace('_MAX_', sMax)+
|
1021
|
+
language.sInfoPostFix;
|
1022
|
+
}
|
1023
|
+
else if ( dt.fnRecordsDisplay() == dt.fnRecordsTotal() )
|
1024
|
+
{
|
1025
|
+
/* Normal record set */
|
1026
|
+
sOut = language.sInfo.
|
1027
|
+
replace('_START_', sStart).
|
1028
|
+
replace('_END_', sEnd).
|
1029
|
+
replace('_MAX_', sMax).
|
1030
|
+
replace('_TOTAL_', sTotal)+
|
1031
|
+
language.sInfoPostFix;
|
1032
|
+
}
|
1033
|
+
else
|
1034
|
+
{
|
1035
|
+
/* Record set after filtering */
|
1036
|
+
sOut = language.sInfo.
|
1037
|
+
replace('_START_', sStart).
|
1038
|
+
replace('_END_', sEnd).
|
1039
|
+
replace('_MAX_', sMax).
|
1040
|
+
replace('_TOTAL_', sTotal) +' '+
|
1041
|
+
language.sInfoFiltered.replace(
|
1042
|
+
'_MAX_',
|
1043
|
+
dt.fnFormatNumber(dt.fnRecordsTotal())
|
1044
|
+
)+
|
1045
|
+
language.sInfoPostFix;
|
1046
|
+
}
|
1047
|
+
|
1048
|
+
var callback = language.fnInfoCallback;
|
1049
|
+
if ( callback ) {
|
1050
|
+
sOut = callback.call( dt.oInstance,
|
1051
|
+
dt, iStart, iEnd, iMax, iTotal, sOut
|
1052
|
+
);
|
1053
|
+
}
|
1054
|
+
|
1055
|
+
var n = dt.aanFeatures.i;
|
1056
|
+
if ( typeof n != 'undefined' )
|
1057
|
+
{
|
1058
|
+
for ( var i=0, iLen=n.length ; i<iLen ; i++ )
|
1059
|
+
{
|
1060
|
+
$(n[i]).html( sOut );
|
1061
|
+
}
|
1062
|
+
}
|
1063
|
+
|
1064
|
+
// DT doesn't actually (yet) trigger this event, but it will in future
|
1065
|
+
$(dt.nTable).triggerHandler( 'info.dt' );
|
1066
|
+
}
|
1067
|
+
} );
|
1068
|
+
|
1069
|
+
|
1070
|
+
|
1071
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
1072
|
+
* Statics
|
1073
|
+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
1074
|
+
|
1075
|
+
|
1076
|
+
/**
|
1077
|
+
* Scroller default settings for initialisation
|
1078
|
+
* @namespace
|
1079
|
+
* @name Scroller.defaults
|
1080
|
+
* @static
|
1081
|
+
*/
|
1082
|
+
Scroller.defaults = /** @lends Scroller.defaults */{
|
1083
|
+
/**
|
1084
|
+
* Indicate if Scroller show show trace information on the console or not. This can be
|
1085
|
+
* useful when debugging Scroller or if just curious as to what it is doing, but should
|
1086
|
+
* be turned off for production.
|
1087
|
+
* @type bool
|
1088
|
+
* @default false
|
1089
|
+
* @static
|
1090
|
+
* @example
|
1091
|
+
* var oTable = $('#example').dataTable( {
|
1092
|
+
* "sScrollY": "200px",
|
1093
|
+
* "sDom": "frtiS",
|
1094
|
+
* "bDeferRender": true,
|
1095
|
+
* "oScroller": {
|
1096
|
+
* "trace": true
|
1097
|
+
* }
|
1098
|
+
* } );
|
1099
|
+
*/
|
1100
|
+
"trace": false,
|
1101
|
+
|
1102
|
+
/**
|
1103
|
+
* Scroller will attempt to automatically calculate the height of rows for it's internal
|
1104
|
+
* calculations. However the height that is used can be overridden using this parameter.
|
1105
|
+
* @type int|string
|
1106
|
+
* @default auto
|
1107
|
+
* @static
|
1108
|
+
* @example
|
1109
|
+
* var oTable = $('#example').dataTable( {
|
1110
|
+
* "sScrollY": "200px",
|
1111
|
+
* "sDom": "frtiS",
|
1112
|
+
* "bDeferRender": true,
|
1113
|
+
* "oScroller": {
|
1114
|
+
* "rowHeight": 30
|
1115
|
+
* }
|
1116
|
+
* } );
|
1117
|
+
*/
|
1118
|
+
"rowHeight": "auto",
|
1119
|
+
|
1120
|
+
/**
|
1121
|
+
* When using server-side processing, Scroller will wait a small amount of time to allow
|
1122
|
+
* the scrolling to finish before requesting more data from the server. This prevents
|
1123
|
+
* you from DoSing your own server! The wait time can be configured by this parameter.
|
1124
|
+
* @type int
|
1125
|
+
* @default 200
|
1126
|
+
* @static
|
1127
|
+
* @example
|
1128
|
+
* var oTable = $('#example').dataTable( {
|
1129
|
+
* "sScrollY": "200px",
|
1130
|
+
* "sDom": "frtiS",
|
1131
|
+
* "bDeferRender": true,
|
1132
|
+
* "oScroller": {
|
1133
|
+
* "serverWait": 100
|
1134
|
+
* }
|
1135
|
+
* } );
|
1136
|
+
*/
|
1137
|
+
"serverWait": 200,
|
1138
|
+
|
1139
|
+
/**
|
1140
|
+
* The display buffer is what Scroller uses to calculate how many rows it should pre-fetch
|
1141
|
+
* for scrolling. Scroller automatically adjusts DataTables' display length to pre-fetch
|
1142
|
+
* rows that will be shown in "near scrolling" (i.e. just beyond the current display area).
|
1143
|
+
* The value is based upon the number of rows that can be displayed in the viewport (i.e.
|
1144
|
+
* a value of 1), and will apply the display range to records before before and after the
|
1145
|
+
* current viewport - i.e. a factor of 3 will allow Scroller to pre-fetch 1 viewport's worth
|
1146
|
+
* of rows before the current viewport, the current viewport's rows and 1 viewport's worth
|
1147
|
+
* of rows after the current viewport. Adjusting this value can be useful for ensuring
|
1148
|
+
* smooth scrolling based on your data set.
|
1149
|
+
* @type int
|
1150
|
+
* @default 7
|
1151
|
+
* @static
|
1152
|
+
* @example
|
1153
|
+
* var oTable = $('#example').dataTable( {
|
1154
|
+
* "sScrollY": "200px",
|
1155
|
+
* "sDom": "frtiS",
|
1156
|
+
* "bDeferRender": true,
|
1157
|
+
* "oScroller": {
|
1158
|
+
* "displayBuffer": 10
|
1159
|
+
* }
|
1160
|
+
* } );
|
1161
|
+
*/
|
1162
|
+
"displayBuffer": 9,
|
1163
|
+
|
1164
|
+
/**
|
1165
|
+
* Scroller uses the boundary scaling factor to decide when to redraw the table - which it
|
1166
|
+
* typically does before you reach the end of the currently loaded data set (in order to
|
1167
|
+
* allow the data to look continuous to a user scrolling through the data). If given as 0
|
1168
|
+
* then the table will be redrawn whenever the viewport is scrolled, while 1 would not
|
1169
|
+
* redraw the table until the currently loaded data has all been shown. You will want
|
1170
|
+
* something in the middle - the default factor of 0.5 is usually suitable.
|
1171
|
+
* @type float
|
1172
|
+
* @default 0.5
|
1173
|
+
* @static
|
1174
|
+
* @example
|
1175
|
+
* var oTable = $('#example').dataTable( {
|
1176
|
+
* "sScrollY": "200px",
|
1177
|
+
* "sDom": "frtiS",
|
1178
|
+
* "bDeferRender": true,
|
1179
|
+
* "oScroller": {
|
1180
|
+
* "boundaryScale": 0.75
|
1181
|
+
* }
|
1182
|
+
* } );
|
1183
|
+
*/
|
1184
|
+
"boundaryScale": 0.5,
|
1185
|
+
|
1186
|
+
/**
|
1187
|
+
* Show (or not) the loading element in the background of the table. Note that you should
|
1188
|
+
* include the dataTables.scroller.css file for this to be displayed correctly.
|
1189
|
+
* @type boolean
|
1190
|
+
* @default false
|
1191
|
+
* @static
|
1192
|
+
* @example
|
1193
|
+
* var oTable = $('#example').dataTable( {
|
1194
|
+
* "sScrollY": "200px",
|
1195
|
+
* "sDom": "frtiS",
|
1196
|
+
* "bDeferRender": true,
|
1197
|
+
* "oScroller": {
|
1198
|
+
* "loadingIndicator": true
|
1199
|
+
* }
|
1200
|
+
* } );
|
1201
|
+
*/
|
1202
|
+
"loadingIndicator": false
|
1203
|
+
};
|
1204
|
+
|
1205
|
+
Scroller.oDefaults = Scroller.defaults;
|
1206
|
+
|
1207
|
+
|
1208
|
+
|
1209
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
1210
|
+
* Constants
|
1211
|
+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
1212
|
+
|
1213
|
+
/**
|
1214
|
+
* Scroller version
|
1215
|
+
* @type String
|
1216
|
+
* @default See code
|
1217
|
+
* @name Scroller.version
|
1218
|
+
* @static
|
1219
|
+
*/
|
1220
|
+
Scroller.version = "1.4.2";
|
1221
|
+
|
1222
|
+
|
1223
|
+
|
1224
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
1225
|
+
* Initialisation
|
1226
|
+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
1227
|
+
|
1228
|
+
// Legacy `dom` parameter initialisation support
|
1229
|
+
if ( typeof $.fn.dataTable == "function" &&
|
1230
|
+
typeof $.fn.dataTableExt.fnVersionCheck == "function" &&
|
1231
|
+
$.fn.dataTableExt.fnVersionCheck('1.10.0') )
|
1232
|
+
{
|
1233
|
+
$.fn.dataTableExt.aoFeatures.push( {
|
1234
|
+
"fnInit": function( oDTSettings ) {
|
1235
|
+
var init = oDTSettings.oInit;
|
1236
|
+
var opts = init.scroller || init.oScroller || {};
|
1237
|
+
|
1238
|
+
new Scroller( oDTSettings, opts );
|
1239
|
+
},
|
1240
|
+
"cFeature": "S",
|
1241
|
+
"sFeature": "Scroller"
|
1242
|
+
} );
|
1243
|
+
}
|
1244
|
+
else
|
1245
|
+
{
|
1246
|
+
alert( "Warning: Scroller requires DataTables 1.10.0 or greater - www.datatables.net/download");
|
1247
|
+
}
|
1248
|
+
|
1249
|
+
// Attach a listener to the document which listens for DataTables initialisation
|
1250
|
+
// events so we can automatically initialise
|
1251
|
+
$(document).on( 'preInit.dt.dtscroller', function (e, settings) {
|
1252
|
+
if ( e.namespace !== 'dt' ) {
|
1253
|
+
return;
|
1254
|
+
}
|
1255
|
+
|
1256
|
+
var init = settings.oInit.scroller;
|
1257
|
+
var defaults = DataTable.defaults.scroller;
|
1258
|
+
|
1259
|
+
if ( init || defaults ) {
|
1260
|
+
var opts = $.extend( {}, init, defaults );
|
1261
|
+
|
1262
|
+
if ( init !== false ) {
|
1263
|
+
new Scroller( settings, opts );
|
1264
|
+
}
|
1265
|
+
}
|
1266
|
+
} );
|
1267
|
+
|
1268
|
+
|
1269
|
+
// Attach Scroller to DataTables so it can be accessed as an 'extra'
|
1270
|
+
$.fn.dataTable.Scroller = Scroller;
|
1271
|
+
$.fn.DataTable.Scroller = Scroller;
|
1272
|
+
|
1273
|
+
|
1274
|
+
// DataTables 1.10 API method aliases
|
1275
|
+
var Api = $.fn.dataTable.Api;
|
1276
|
+
|
1277
|
+
Api.register( 'scroller()', function () {
|
1278
|
+
return this;
|
1279
|
+
} );
|
1280
|
+
|
1281
|
+
// Undocumented and deprecated - is it actually useful at all?
|
1282
|
+
Api.register( 'scroller().rowToPixels()', function ( rowIdx, intParse, virtual ) {
|
1283
|
+
var ctx = this.context;
|
1284
|
+
|
1285
|
+
if ( ctx.length && ctx[0].oScroller ) {
|
1286
|
+
return ctx[0].oScroller.fnRowToPixels( rowIdx, intParse, virtual );
|
1287
|
+
}
|
1288
|
+
// undefined
|
1289
|
+
} );
|
1290
|
+
|
1291
|
+
// Undocumented and deprecated - is it actually useful at all?
|
1292
|
+
Api.register( 'scroller().pixelsToRow()', function ( pixels, intParse, virtual ) {
|
1293
|
+
var ctx = this.context;
|
1294
|
+
|
1295
|
+
if ( ctx.length && ctx[0].oScroller ) {
|
1296
|
+
return ctx[0].oScroller.fnPixelsToRow( pixels, intParse, virtual );
|
1297
|
+
}
|
1298
|
+
// undefined
|
1299
|
+
} );
|
1300
|
+
|
1301
|
+
// Undocumented and deprecated - use `row().scrollTo()` instead
|
1302
|
+
Api.register( 'scroller().scrollToRow()', function ( row, ani ) {
|
1303
|
+
this.iterator( 'table', function ( ctx ) {
|
1304
|
+
if ( ctx.oScroller ) {
|
1305
|
+
ctx.oScroller.fnScrollToRow( row, ani );
|
1306
|
+
}
|
1307
|
+
} );
|
1308
|
+
|
1309
|
+
return this;
|
1310
|
+
} );
|
1311
|
+
|
1312
|
+
Api.register( 'row().scrollTo()', function ( ani ) {
|
1313
|
+
var that = this;
|
1314
|
+
|
1315
|
+
this.iterator( 'row', function ( ctx, rowIdx ) {
|
1316
|
+
if ( ctx.oScroller ) {
|
1317
|
+
var displayIdx = that
|
1318
|
+
.rows( { order: 'applied', search: 'applied' } )
|
1319
|
+
.indexes()
|
1320
|
+
.indexOf( rowIdx );
|
1321
|
+
|
1322
|
+
ctx.oScroller.fnScrollToRow( displayIdx, ani );
|
1323
|
+
}
|
1324
|
+
} );
|
1325
|
+
|
1326
|
+
return this;
|
1327
|
+
} );
|
1328
|
+
|
1329
|
+
Api.register( 'scroller.measure()', function ( redraw ) {
|
1330
|
+
this.iterator( 'table', function ( ctx ) {
|
1331
|
+
if ( ctx.oScroller ) {
|
1332
|
+
ctx.oScroller.fnMeasure( redraw );
|
1333
|
+
}
|
1334
|
+
} );
|
1335
|
+
|
1336
|
+
return this;
|
1337
|
+
} );
|
1338
|
+
|
1339
|
+
Api.register( 'scroller.page()', function() {
|
1340
|
+
var ctx = this.context;
|
1341
|
+
|
1342
|
+
if ( ctx.length && ctx[0].oScroller ) {
|
1343
|
+
return ctx[0].oScroller.fnPageInfo();
|
1344
|
+
}
|
1345
|
+
// undefined
|
1346
|
+
} );
|
1347
|
+
|
1348
|
+
return Scroller;
|
1349
|
+
}));
|