jquery-datatables-rails 1.12.2 → 2.1.10.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/dataTables/extras/filler.png +0 -0
  3. data/app/assets/images/dataTables/extras/loading-background.png +0 -0
  4. data/app/assets/images/dataTables/sort_asc_disabled.png +0 -0
  5. data/app/assets/javascripts/dataTables/extras/dataTables.autoFill.js +851 -0
  6. data/app/assets/javascripts/dataTables/extras/{ColReorder.js → dataTables.colReorder.js} +558 -223
  7. data/app/assets/javascripts/dataTables/extras/dataTables.colVis.js +1096 -0
  8. data/app/assets/javascripts/dataTables/extras/{FixedColumns.js → dataTables.fixedColumns.js} +163 -113
  9. data/app/assets/javascripts/dataTables/extras/{FixedHeader.js → dataTables.fixedHeader.js} +306 -219
  10. data/app/assets/javascripts/dataTables/extras/{KeyTable.js → dataTables.keyTable.js} +155 -95
  11. data/app/assets/javascripts/dataTables/extras/{Scroller.js → dataTables.scroller.js} +469 -188
  12. data/app/assets/javascripts/dataTables/extras/{TableTools.js → dataTables.tableTools.js} +949 -341
  13. data/app/assets/javascripts/dataTables/jquery.dataTables.foundation.js +4 -4
  14. data/app/assets/javascripts/dataTables/jquery.dataTables.js +10711 -8427
  15. data/app/assets/media/dataTables/extras/swf/copy_csv_xls.swf +0 -0
  16. data/app/assets/media/dataTables/extras/swf/copy_csv_xls_pdf.swf +0 -0
  17. data/app/assets/stylesheets/dataTables/extras/dataTables.autoFill.css.scss +24 -0
  18. data/app/assets/stylesheets/dataTables/extras/dataTables.colReorder.css.scss +14 -0
  19. data/app/assets/stylesheets/dataTables/extras/dataTables.colVis.css.scss +184 -0
  20. data/app/assets/stylesheets/dataTables/extras/dataTables.colvis.jqueryui.css.scss +23 -0
  21. data/app/assets/stylesheets/dataTables/extras/dataTables.fixedColumns.css.scss +24 -0
  22. data/app/assets/stylesheets/dataTables/extras/dataTables.fixedHeader.css.scss +7 -0
  23. data/app/assets/stylesheets/dataTables/extras/dataTables.keyTable.css.scss +7 -0
  24. data/app/assets/stylesheets/dataTables/extras/dataTables.scroller.css.scss +44 -0
  25. data/app/assets/stylesheets/dataTables/extras/{TableTools.css.erb → dataTables.tableTools.css.scss} +30 -15
  26. data/app/assets/stylesheets/dataTables/jquery.dataTables.bootstrap.css.scss +6 -0
  27. data/app/assets/stylesheets/dataTables/jquery.dataTables.css.scss +363 -184
  28. data/app/assets/stylesheets/dataTables/src/jquery.dataTables_themeroller.css +307 -220
  29. data/lib/jquery/datatables/rails/version.rb +1 -1
  30. metadata +42 -22
  31. data/app/assets/javascripts/dataTables/extras/AutoFill.js +0 -820
  32. data/app/assets/javascripts/dataTables/extras/ColVis.js +0 -1005
  33. data/app/assets/javascripts/dataTables/extras/TableTools.min.js +0 -77
  34. data/app/assets/stylesheets/dataTables/extras/ColReorder.css.erb +0 -21
  35. data/app/assets/stylesheets/dataTables/extras/ColVis.css +0 -76
  36. data/app/assets/stylesheets/dataTables/extras/ColVisAlt.css.erb +0 -104
@@ -1,42 +1,63 @@
1
- /*
2
- * File: FixedHeader.js
3
- * Version: 2.0.6
4
- * Description: "Fix" a header at the top of the table, so it scrolls with the table
5
- * Author: Allan Jardine (www.sprymedia.co.uk)
6
- * Created: Wed 16 Sep 2009 19:46:30 BST
7
- * Language: Javascript
8
- * License: GPL v2 or BSD 3 point style
9
- * Project: Just a little bit of fun - enjoy :-)
10
- * Contact: www.sprymedia.co.uk/contact
1
+ /*! FixedHeader 2.1.1
2
+ * ©2010-2014 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ /**
6
+ * @summary FixedHeader
7
+ * @description Fix a table's header or footer, so it is always visible while
8
+ * Scrolling
9
+ * @version 2.1.1
10
+ * @file dataTables.fixedHeader.js
11
+ * @author SpryMedia Ltd (www.sprymedia.co.uk)
12
+ * @contact www.sprymedia.co.uk/contact
13
+ * @copyright Copyright 2009-2014 SpryMedia Ltd.
14
+ *
15
+ * This source file is free software, available under the following license:
16
+ * MIT license - http://datatables.net/license/mit
11
17
  *
12
- * Copyright 2009-2012 Allan Jardine, all rights reserved.
18
+ * This source file is distributed in the hope that it will be useful, but
19
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
13
21
  *
14
- * This source file is free software, under either the GPL v2 license or a
15
- * BSD style license, available at:
16
- * http://datatables.net/license_gpl2
17
- * http://datatables.net/license_bsd
22
+ * For details please refer to: http://www.datatables.net
18
23
  */
19
24
 
25
+ /* Global scope for FixedColumns for backwards compatibility - will be removed
26
+ * in future. Not documented in 1.1.x.
27
+ */
28
+
29
+ /* Global scope for FixedColumns */
30
+ var FixedHeader;
31
+
32
+ (function(window, document, undefined) {
33
+
34
+
35
+ var factory = function( $, DataTable ) {
36
+ "use strict";
37
+
20
38
  /*
21
39
  * Function: FixedHeader
22
- * Purpose: Provide 'fixed' header, footer and columns on an HTML table
40
+ * Purpose: Provide 'fixed' header, footer and columns for a DataTable
23
41
  * Returns: object:FixedHeader - must be called with 'new'
24
42
  * Inputs: mixed:mTable - target table
25
- * 1. DataTable object - when using FixedHeader with DataTables, or
26
- * 2. HTML table node - when using FixedHeader without DataTables
27
- * object:oInit - initialisation settings, with the following properties (each optional)
28
- * bool:top - fix the header (default true)
29
- * bool:bottom - fix the footer (default false)
30
- * bool:left - fix the left most column (default false)
31
- * bool:right - fix the right most column (default false)
32
- * int:zTop - fixed header zIndex
33
- * int:zBottom - fixed footer zIndex
34
- * int:zLeft - fixed left zIndex
35
- * int:zRight - fixed right zIndex
43
+ * @param {object} dt DataTables instance or HTML table node. With DataTables
44
+ * 1.10 this can also be a jQuery collection (with just a single table in its
45
+ * result set), a jQuery selector, DataTables API instance or settings
46
+ * object.
47
+ * @param {object} [oInit] initialisation settings, with the following
48
+ * properties (each optional)
49
+ * * bool:top - fix the header (default true)
50
+ * * bool:bottom - fix the footer (default false)
51
+ * * int:left - fix the left column(s) (default 0)
52
+ * * int:right - fix the right column(s) (default 0)
53
+ * * int:zTop - fixed header zIndex
54
+ * * int:zBottom - fixed footer zIndex
55
+ * * int:zLeft - fixed left zIndex
56
+ * * int:zRight - fixed right zIndex
36
57
  */
37
- var FixedHeader = function ( mTable, oInit ) {
58
+ FixedHeader = function ( mTable, oInit ) {
38
59
  /* Sanity check - you just know it will happen */
39
- if ( typeof this.fnInit != 'function' )
60
+ if ( ! this instanceof FixedHeader )
40
61
  {
41
62
  alert( "FixedHeader warning: FixedHeader must be initialised with the 'new' keyword." );
42
63
  return;
@@ -48,8 +69,8 @@ var FixedHeader = function ( mTable, oInit ) {
48
69
  "oSides": {
49
70
  "top": true,
50
71
  "bottom": false,
51
- "left": false,
52
- "right": false
72
+ "left": 0,
73
+ "right": 0
53
74
  },
54
75
  "oZIndexes": {
55
76
  "top": 104,
@@ -57,6 +78,12 @@ var FixedHeader = function ( mTable, oInit ) {
57
78
  "left": 102,
58
79
  "right": 101
59
80
  },
81
+ "oCloneOnDraw": {
82
+ "top": false,
83
+ "bottom": false,
84
+ "left": true,
85
+ "right": true
86
+ },
60
87
  "oMes": {
61
88
  "iTableWidth": 0,
62
89
  "iTableHeight": 0,
@@ -69,8 +96,8 @@ var FixedHeader = function ( mTable, oInit ) {
69
96
  "top": 0
70
97
  },
71
98
  "nTable": null,
72
- "bUseAbsPos": false,
73
- "bFooter": false
99
+ "bFooter": false,
100
+ "bInitComplete": false
74
101
  };
75
102
 
76
103
  /*
@@ -104,14 +131,16 @@ var FixedHeader = function ( mTable, oInit ) {
104
131
  this._fnUpdatePositions();
105
132
  };
106
133
 
134
+
135
+ var dt = $.fn.dataTable.Api ?
136
+ new $.fn.dataTable.Api( mTable ).settings()[0] :
137
+ mTable.fnSettings();
138
+
139
+ dt._oPluginFixedHeader = this;
140
+
107
141
  /* Let's do it */
108
- this.fnInit( mTable, oInit );
142
+ this.fnInit( dt, oInit );
109
143
 
110
- /* Store the instance on the DataTables object for easy access */
111
- if ( typeof mTable.fnSettings == 'function' )
112
- {
113
- mTable._oPluginFixedHeader = this;
114
- }
115
144
  };
116
145
 
117
146
 
@@ -131,7 +160,7 @@ FixedHeader.prototype = {
131
160
  * Returns: -
132
161
  * Inputs: {as FixedHeader function}
133
162
  */
134
- fnInit: function ( oTable, oInit )
163
+ fnInit: function ( oDtSettings, oInit )
135
164
  {
136
165
  var s = this.fnGetSettings();
137
166
  var that = this;
@@ -139,44 +168,23 @@ FixedHeader.prototype = {
139
168
  /* Record the user definable settings */
140
169
  this.fnInitSettings( s, oInit );
141
170
 
142
- /* DataTables specific stuff */
143
- if ( typeof oTable.fnSettings == 'function' )
171
+ if ( oDtSettings.oScroll.sX !== "" || oDtSettings.oScroll.sY !== "" )
144
172
  {
145
- if ( typeof oTable.fnVersionCheck == 'functon' &&
146
- oTable.fnVersionCheck( '1.6.0' ) !== true )
147
- {
148
- alert( "FixedHeader 2 required DataTables 1.6.0 or later. "+
149
- "Please upgrade your DataTables installation" );
150
- return;
151
- }
152
-
153
- var oDtSettings = oTable.fnSettings();
154
-
155
- if ( oDtSettings.oScroll.sX != "" || oDtSettings.oScroll.sY != "" )
156
- {
157
- alert( "FixedHeader 2 is not supported with DataTables' scrolling mode at this time" );
158
- return;
159
- }
160
-
161
- s.nTable = oDtSettings.nTable;
162
- oDtSettings.aoDrawCallback.push( {
163
- "fn": function () {
164
- FixedHeader.fnMeasure();
165
- that._fnUpdateClones.call(that);
166
- that._fnUpdatePositions.call(that);
167
- },
168
- "sName": "FixedHeader"
169
- } );
170
- }
171
- else
172
- {
173
- s.nTable = oTable;
173
+ alert( "FixedHeader 2 is not supported with DataTables' scrolling mode at this time" );
174
+ return;
174
175
  }
175
176
 
176
- s.bFooter = ($('>tfoot', s.nTable).length > 0) ? true : false;
177
+ s.nTable = oDtSettings.nTable;
178
+ oDtSettings.aoDrawCallback.unshift( {
179
+ "fn": function () {
180
+ FixedHeader.fnMeasure();
181
+ that._fnUpdateClones.call(that);
182
+ that._fnUpdatePositions.call(that);
183
+ },
184
+ "sName": "FixedHeader"
185
+ } );
177
186
 
178
- /* "Detect" browsers that don't support absolute positioing - or have bugs */
179
- s.bUseAbsPos = (jQuery.browser.msie && (jQuery.browser.version=="6.0"||jQuery.browser.version=="7.0"));
187
+ s.bFooter = ($('>tfoot', s.nTable).length > 0) ? true : false;
180
188
 
181
189
  /* Add the 'sides' that are fixed */
182
190
  if ( s.oSides.top )
@@ -189,11 +197,11 @@ FixedHeader.prototype = {
189
197
  }
190
198
  if ( s.oSides.left )
191
199
  {
192
- s.aoCache.push( that._fnCloneTable( "fixedLeft", "FixedHeader_Left", that._fnCloneTLeft ) );
200
+ s.aoCache.push( that._fnCloneTable( "fixedLeft", "FixedHeader_Left", that._fnCloneTLeft, s.oSides.left ) );
193
201
  }
194
202
  if ( s.oSides.right )
195
203
  {
196
- s.aoCache.push( that._fnCloneTable( "fixedRight", "FixedHeader_Right", that._fnCloneTRight ) );
204
+ s.aoCache.push( that._fnCloneTable( "fixedRight", "FixedHeader_Right", that._fnCloneTRight, s.oSides.right ) );
197
205
  }
198
206
 
199
207
  /* Event listeners for window movement */
@@ -201,16 +209,30 @@ FixedHeader.prototype = {
201
209
  that._fnUpdatePositions.call(that);
202
210
  } );
203
211
 
204
- jQuery(window).resize( function () {
212
+ $(window).resize( function () {
205
213
  FixedHeader.fnMeasure();
206
214
  that._fnUpdateClones.call(that);
207
215
  that._fnUpdatePositions.call(that);
208
216
  } );
209
217
 
218
+ $(s.nTable)
219
+ .on('column-reorder.dt', function () {
220
+ FixedHeader.fnMeasure();
221
+ that._fnUpdateClones( true );
222
+ that._fnUpdatePositions();
223
+ } )
224
+ .on('column-visibility.dt', function () {
225
+ FixedHeader.fnMeasure();
226
+ that._fnUpdateClones( true );
227
+ that._fnUpdatePositions();
228
+ } );
229
+
210
230
  /* Get things right to start with */
211
231
  FixedHeader.fnMeasure();
212
232
  that._fnUpdateClones();
213
233
  that._fnUpdatePositions();
234
+
235
+ s.bInitComplete = true;
214
236
  },
215
237
 
216
238
 
@@ -227,45 +249,56 @@ FixedHeader.prototype = {
227
249
  */
228
250
  fnInitSettings: function ( s, oInit )
229
251
  {
230
- if ( typeof oInit != 'undefined' )
252
+ if ( oInit !== undefined )
231
253
  {
232
- if ( typeof oInit.top != 'undefined' ) {
254
+ if ( oInit.top !== undefined ) {
233
255
  s.oSides.top = oInit.top;
234
256
  }
235
- if ( typeof oInit.bottom != 'undefined' ) {
257
+ if ( oInit.bottom !== undefined ) {
236
258
  s.oSides.bottom = oInit.bottom;
237
259
  }
238
- if ( typeof oInit.left != 'undefined' ) {
260
+ if ( typeof oInit.left == 'boolean' ) {
261
+ s.oSides.left = oInit.left ? 1 : 0;
262
+ }
263
+ else if ( oInit.left !== undefined ) {
239
264
  s.oSides.left = oInit.left;
240
265
  }
241
- if ( typeof oInit.right != 'undefined' ) {
266
+ if ( typeof oInit.right == 'boolean' ) {
267
+ s.oSides.right = oInit.right ? 1 : 0;
268
+ }
269
+ else if ( oInit.right !== undefined ) {
242
270
  s.oSides.right = oInit.right;
243
271
  }
244
272
 
245
- if ( typeof oInit.zTop != 'undefined' ) {
273
+ if ( oInit.zTop !== undefined ) {
246
274
  s.oZIndexes.top = oInit.zTop;
247
275
  }
248
- if ( typeof oInit.zBottom != 'undefined' ) {
276
+ if ( oInit.zBottom !== undefined ) {
249
277
  s.oZIndexes.bottom = oInit.zBottom;
250
278
  }
251
- if ( typeof oInit.zLeft != 'undefined' ) {
279
+ if ( oInit.zLeft !== undefined ) {
252
280
  s.oZIndexes.left = oInit.zLeft;
253
281
  }
254
- if ( typeof oInit.zRight != 'undefined' ) {
282
+ if ( oInit.zRight !== undefined ) {
255
283
  s.oZIndexes.right = oInit.zRight;
256
284
  }
257
285
 
258
- if ( typeof oInit.offsetTop != 'undefined' ) {
286
+ if ( oInit.offsetTop !== undefined ) {
259
287
  s.oOffset.top = oInit.offsetTop;
260
288
  }
289
+ if ( oInit.alwaysCloneTop !== undefined ) {
290
+ s.oCloneOnDraw.top = oInit.alwaysCloneTop;
291
+ }
292
+ if ( oInit.alwaysCloneBottom !== undefined ) {
293
+ s.oCloneOnDraw.bottom = oInit.alwaysCloneBottom;
294
+ }
295
+ if ( oInit.alwaysCloneLeft !== undefined ) {
296
+ s.oCloneOnDraw.left = oInit.alwaysCloneLeft;
297
+ }
298
+ if ( oInit.alwaysCloneRight !== undefined ) {
299
+ s.oCloneOnDraw.right = oInit.alwaysCloneRight;
300
+ }
261
301
  }
262
-
263
- /* Detect browsers which have poor position:fixed support so we can use absolute positions.
264
- * This is much slower since the position must be updated for each scroll, but widens
265
- * compatibility
266
- */
267
- s.bUseAbsPos = (jQuery.browser.msie &&
268
- (jQuery.browser.version=="6.0"||jQuery.browser.version=="7.0"));
269
302
  },
270
303
 
271
304
  /*
@@ -274,7 +307,7 @@ FixedHeader.prototype = {
274
307
  * Returns: -
275
308
  * Inputs: -
276
309
  */
277
- _fnCloneTable: function ( sType, sClass, fnClone )
310
+ _fnCloneTable: function ( sType, sClass, fnClone, iCells )
278
311
  {
279
312
  var s = this.fnGetSettings();
280
313
  var nCTable;
@@ -283,7 +316,7 @@ FixedHeader.prototype = {
283
316
  * DataTables works. Therefore, we can set this to be relatively position (if it is not
284
317
  * alreadu absolute, and use this as the base point for the cloned header
285
318
  */
286
- if ( jQuery(s.nTable.parentNode).css('position') != "absolute" )
319
+ if ( $(s.nTable.parentNode).css('position') != "absolute" )
287
320
  {
288
321
  s.nTable.parentNode.style.position = "relative";
289
322
  }
@@ -316,7 +349,7 @@ FixedHeader.prototype = {
316
349
  nDiv.style.zIndex = s.oZIndexes.right;
317
350
  }
318
351
 
319
- /* remove margins since we are going to poistion it absolutely */
352
+ /* remove margins since we are going to position it absolutely */
320
353
  nCTable.style.margin = "0";
321
354
 
322
355
  /* Insert the newly cloned table into the DOM, on top of the "real" header */
@@ -330,12 +363,13 @@ FixedHeader.prototype = {
330
363
  "sPosition": "",
331
364
  "sTop": "",
332
365
  "sLeft": "",
333
- "fnClone": fnClone
366
+ "fnClone": fnClone,
367
+ "iCells": iCells
334
368
  };
335
369
  },
336
370
 
337
371
  /*
338
- * Function: _fnUpdatePositions
372
+ * Function: _fnMeasure
339
373
  * Purpose: Get the current positioning of the table in the DOM
340
374
  * Returns: -
341
375
  * Inputs: -
@@ -345,7 +379,7 @@ FixedHeader.prototype = {
345
379
  var
346
380
  s = this.fnGetSettings(),
347
381
  m = s.oMes,
348
- jqTable = jQuery(s.nTable),
382
+ jqTable = $(s.nTable),
349
383
  oOffset = jqTable.offset(),
350
384
  iParentScrollTop = this._fnSumScroll( s.nTable.parentNode, 'scrollTop' ),
351
385
  iParentScrollLeft = this._fnSumScroll( s.nTable.parentNode, 'scrollLeft' );
@@ -418,13 +452,25 @@ FixedHeader.prototype = {
418
452
  * Returns: -
419
453
  * Inputs: -
420
454
  */
421
- _fnUpdateClones: function ()
455
+ _fnUpdateClones: function ( full )
422
456
  {
423
457
  var s = this.fnGetSettings();
458
+
459
+ if ( full ) {
460
+ // This is a little bit of a hack to force a full clone draw. When
461
+ // `full` is set to true, we want to reclone the source elements,
462
+ // regardless of the clone-on-draw settings
463
+ s.bInitComplete = false;
464
+ }
465
+
424
466
  for ( var i=0, iLen=s.aoCache.length ; i<iLen ; i++ )
425
467
  {
426
468
  s.aoCache[i].fnClone.call( this, s.aoCache[i] );
427
469
  }
470
+
471
+ if ( full ) {
472
+ s.bInitComplete = true;
473
+ }
428
474
  },
429
475
 
430
476
 
@@ -436,7 +482,7 @@ FixedHeader.prototype = {
436
482
  * Function: _fnScrollHorizontalLeft
437
483
  * Purpose: Update the positioning of the scrolling elements
438
484
  * Returns: -
439
- * Inputs: object:oCache - the cahced values for this fixed element
485
+ * Inputs: object:oCache - the cached values for this fixed element
440
486
  */
441
487
  _fnScrollHorizontalRight: function ( oCache )
442
488
  {
@@ -446,7 +492,7 @@ FixedHeader.prototype = {
446
492
  oWin = FixedHeader.oWin,
447
493
  oDoc = FixedHeader.oDoc,
448
494
  nTable = oCache.nWrapper,
449
- iFixedWidth = jQuery(nTable).outerWidth();
495
+ iFixedWidth = $(nTable).outerWidth();
450
496
 
451
497
  if ( oWin.iScrollRight < oMes.iTableRight )
452
498
  {
@@ -458,18 +504,9 @@ FixedHeader.prototype = {
458
504
  else if ( oMes.iTableLeft < oDoc.iWidth-oWin.iScrollRight-iFixedWidth )
459
505
  {
460
506
  /* Middle */
461
- if ( s.bUseAbsPos )
462
- {
463
- this._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );
464
- this._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+"px", 'top', nTable.style );
465
- this._fnUpdateCache( oCache, 'sLeft', (oDoc.iWidth-oWin.iScrollRight-iFixedWidth)+"px", 'left', nTable.style );
466
- }
467
- else
468
- {
469
- this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );
470
- this._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop-oWin.iScrollTop)+"px", 'top', nTable.style );
471
- this._fnUpdateCache( oCache, 'sLeft', (oWin.iWidth-iFixedWidth)+"px", 'left', nTable.style );
472
- }
507
+ this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );
508
+ this._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop-oWin.iScrollTop)+"px", 'top', nTable.style );
509
+ this._fnUpdateCache( oCache, 'sLeft', (oWin.iWidth-iFixedWidth)+"px", 'left', nTable.style );
473
510
  }
474
511
  else
475
512
  {
@@ -484,7 +521,7 @@ FixedHeader.prototype = {
484
521
  * Function: _fnScrollHorizontalLeft
485
522
  * Purpose: Update the positioning of the scrolling elements
486
523
  * Returns: -
487
- * Inputs: object:oCache - the cahced values for this fixed element
524
+ * Inputs: object:oCache - the cached values for this fixed element
488
525
  */
489
526
  _fnScrollHorizontalLeft: function ( oCache )
490
527
  {
@@ -494,7 +531,7 @@ FixedHeader.prototype = {
494
531
  oWin = FixedHeader.oWin,
495
532
  oDoc = FixedHeader.oDoc,
496
533
  nTable = oCache.nWrapper,
497
- iCellWidth = jQuery(nTable).outerWidth();
534
+ iCellWidth = $(nTable).outerWidth();
498
535
 
499
536
  if ( oWin.iScrollLeft < oMes.iTableLeft )
500
537
  {
@@ -505,19 +542,9 @@ FixedHeader.prototype = {
505
542
  }
506
543
  else if ( oWin.iScrollLeft < oMes.iTableLeft+oMes.iTableWidth-iCellWidth )
507
544
  {
508
- /* Middle */
509
- if ( s.bUseAbsPos )
510
- {
511
- this._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );
512
- this._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+"px", 'top', nTable.style );
513
- this._fnUpdateCache( oCache, 'sLeft', oWin.iScrollLeft+"px", 'left', nTable.style );
514
- }
515
- else
516
- {
517
- this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );
518
- this._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop-oWin.iScrollTop)+"px", 'top', nTable.style );
519
- this._fnUpdateCache( oCache, 'sLeft', "0px", 'left', nTable.style );
520
- }
545
+ this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );
546
+ this._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop-oWin.iScrollTop)+"px", 'top', nTable.style );
547
+ this._fnUpdateCache( oCache, 'sLeft', "0px", 'left', nTable.style );
521
548
  }
522
549
  else
523
550
  {
@@ -532,7 +559,7 @@ FixedHeader.prototype = {
532
559
  * Function: _fnScrollFixedFooter
533
560
  * Purpose: Update the positioning of the scrolling elements
534
561
  * Returns: -
535
- * Inputs: object:oCache - the cahced values for this fixed element
562
+ * Inputs: object:oCache - the cached values for this fixed element
536
563
  */
537
564
  _fnScrollFixedFooter: function ( oCache )
538
565
  {
@@ -542,8 +569,8 @@ FixedHeader.prototype = {
542
569
  oWin = FixedHeader.oWin,
543
570
  oDoc = FixedHeader.oDoc,
544
571
  nTable = oCache.nWrapper,
545
- iTheadHeight = jQuery("thead", s.nTable).outerHeight(),
546
- iCellHeight = jQuery(nTable).outerHeight();
572
+ iTheadHeight = $("thead", s.nTable).outerHeight(),
573
+ iCellHeight = $(nTable).outerHeight();
547
574
 
548
575
  if ( oWin.iScrollBottom < oMes.iTableBottom )
549
576
  {
@@ -554,19 +581,9 @@ FixedHeader.prototype = {
554
581
  }
555
582
  else if ( oWin.iScrollBottom < oMes.iTableBottom+oMes.iTableHeight-iCellHeight-iTheadHeight )
556
583
  {
557
- /* Middle */
558
- if ( s.bUseAbsPos )
559
- {
560
- this._fnUpdateCache( oCache, 'sPosition', "absolute", 'position', nTable.style );
561
- this._fnUpdateCache( oCache, 'sTop', (oDoc.iHeight-oWin.iScrollBottom-iCellHeight)+"px", 'top', nTable.style );
562
- this._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+"px", 'left', nTable.style );
563
- }
564
- else
565
- {
566
- this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );
567
- this._fnUpdateCache( oCache, 'sTop', (oWin.iHeight-iCellHeight)+"px", 'top', nTable.style );
568
- this._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft-oWin.iScrollLeft)+"px", 'left', nTable.style );
569
- }
584
+ this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );
585
+ this._fnUpdateCache( oCache, 'sTop', (oWin.iHeight-iCellHeight)+"px", 'top', nTable.style );
586
+ this._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft-oWin.iScrollLeft)+"px", 'left', nTable.style );
570
587
  }
571
588
  else
572
589
  {
@@ -581,7 +598,7 @@ FixedHeader.prototype = {
581
598
  * Function: _fnScrollFixedHeader
582
599
  * Purpose: Update the positioning of the scrolling elements
583
600
  * Returns: -
584
- * Inputs: object:oCache - the cahced values for this fixed element
601
+ * Inputs: object:oCache - the cached values for this fixed element
585
602
  */
586
603
  _fnScrollFixedHeader: function ( oCache )
587
604
  {
@@ -615,18 +632,9 @@ FixedHeader.prototype = {
615
632
  else
616
633
  {
617
634
  /* In the middle of the table */
618
- if ( s.bUseAbsPos )
619
- {
620
- this._fnUpdateCache( oCache, 'sPosition', "absolute", 'position', nTable.style );
621
- this._fnUpdateCache( oCache, 'sTop', oWin.iScrollTop+"px", 'top', nTable.style );
622
- this._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+"px", 'left', nTable.style );
623
- }
624
- else
625
- {
626
- this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );
627
- this._fnUpdateCache( oCache, 'sTop', s.oOffset.top+"px", 'top', nTable.style );
628
- this._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft-oWin.iScrollLeft)+"px", 'left', nTable.style );
629
- }
635
+ this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );
636
+ this._fnUpdateCache( oCache, 'sTop', s.oOffset.top+"px", 'top', nTable.style );
637
+ this._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft-oWin.iScrollLeft)+"px", 'left', nTable.style );
630
638
  }
631
639
  },
632
640
 
@@ -651,6 +659,29 @@ FixedHeader.prototype = {
651
659
 
652
660
 
653
661
 
662
+ /**
663
+ * Copy the classes of all child nodes from one element to another. This implies
664
+ * that the two have identical structure - no error checking is performed to that
665
+ * fact.
666
+ * @param {element} source Node to copy classes from
667
+ * @param {element} dest Node to copy classes too
668
+ */
669
+ _fnClassUpdate: function ( source, dest )
670
+ {
671
+ var that = this;
672
+
673
+ if ( source.nodeName.toUpperCase() === "TR" || source.nodeName.toUpperCase() === "TH" ||
674
+ source.nodeName.toUpperCase() === "TD" || source.nodeName.toUpperCase() === "SPAN" )
675
+ {
676
+ dest.className = source.className;
677
+ }
678
+
679
+ $(source).children().each( function (i) {
680
+ that._fnClassUpdate( $(source).children()[i], $(dest).children()[i] );
681
+ } );
682
+ },
683
+
684
+
654
685
  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
655
686
  * Cloning functions
656
687
  */
@@ -659,34 +690,61 @@ FixedHeader.prototype = {
659
690
  * Function: _fnCloneThead
660
691
  * Purpose: Clone the thead element
661
692
  * Returns: -
662
- * Inputs: object:oCache - the cahced values for this fixed element
693
+ * Inputs: object:oCache - the cached values for this fixed element
663
694
  */
664
695
  _fnCloneThead: function ( oCache )
665
696
  {
666
697
  var s = this.fnGetSettings();
667
698
  var nTable = oCache.nNode;
668
699
 
700
+ if ( s.bInitComplete && !s.oCloneOnDraw.top )
701
+ {
702
+ this._fnClassUpdate( $('thead', s.nTable)[0], $('thead', nTable)[0] );
703
+ return;
704
+ }
705
+
669
706
  /* Set the wrapper width to match that of the cloned table */
670
- oCache.nWrapper.style.width = jQuery(s.nTable).outerWidth()+"px";
707
+ var iDtWidth = $(s.nTable).outerWidth();
708
+ oCache.nWrapper.style.width = iDtWidth+"px";
709
+ nTable.style.width = iDtWidth+"px";
671
710
 
672
711
  /* Remove any children the cloned table has */
673
712
  while ( nTable.childNodes.length > 0 )
674
713
  {
675
- jQuery('thead th', nTable).unbind( 'click' );
714
+ $('thead th', nTable).unbind( 'click' );
676
715
  nTable.removeChild( nTable.childNodes[0] );
677
716
  }
678
717
 
679
718
  /* Clone the DataTables header */
680
- var nThead = jQuery('thead', s.nTable).clone(true)[0];
719
+ var nThead = $('thead', s.nTable).clone(true)[0];
681
720
  nTable.appendChild( nThead );
682
721
 
683
722
  /* Copy the widths across - apparently a clone isn't good enough for this */
684
- jQuery("thead>tr th", s.nTable).each( function (i) {
685
- jQuery("thead>tr th:eq("+i+")", nTable).width( jQuery(this).width() );
723
+ var a = [];
724
+ var b = [];
725
+
726
+ $("thead>tr th", s.nTable).each( function (i) {
727
+ a.push( $(this).width() );
686
728
  } );
687
729
 
688
- jQuery("thead>tr td", s.nTable).each( function (i) {
689
- jQuery("thead>tr td:eq("+i+")", nTable).width( jQuery(this).width() );
730
+ $("thead>tr td", s.nTable).each( function (i) {
731
+ b.push( $(this).width() );
732
+ } );
733
+
734
+ $("thead>tr th", s.nTable).each( function (i) {
735
+ $("thead>tr th:eq("+i+")", nTable).width( a[i] );
736
+ $(this).width( a[i] );
737
+ } );
738
+
739
+ $("thead>tr td", s.nTable).each( function (i) {
740
+ $("thead>tr td:eq("+i+")", nTable).width( b[i] );
741
+ $(this).width( b[i] );
742
+ } );
743
+
744
+ // Stop DataTables 1.9 from putting a focus ring on the headers when
745
+ // clicked to sort
746
+ $('th.sorting, th.sorting_desc, th.sorting_asc', nTable).bind( 'click', function () {
747
+ this.blur();
690
748
  } );
691
749
  },
692
750
 
@@ -694,7 +752,7 @@ FixedHeader.prototype = {
694
752
  * Function: _fnCloneTfoot
695
753
  * Purpose: Clone the tfoot element
696
754
  * Returns: -
697
- * Inputs: object:oCache - the cahced values for this fixed element
755
+ * Inputs: object:oCache - the cached values for this fixed element
698
756
  */
699
757
  _fnCloneTfoot: function ( oCache )
700
758
  {
@@ -702,7 +760,7 @@ FixedHeader.prototype = {
702
760
  var nTable = oCache.nNode;
703
761
 
704
762
  /* Set the wrapper width to match that of the cloned table */
705
- oCache.nWrapper.style.width = jQuery(s.nTable).outerWidth()+"px";
763
+ oCache.nWrapper.style.width = $(s.nTable).outerWidth()+"px";
706
764
 
707
765
  /* Remove any children the cloned table has */
708
766
  while ( nTable.childNodes.length > 0 )
@@ -711,22 +769,22 @@ FixedHeader.prototype = {
711
769
  }
712
770
 
713
771
  /* Clone the DataTables footer */
714
- var nTfoot = jQuery('tfoot', s.nTable).clone(true)[0];
772
+ var nTfoot = $('tfoot', s.nTable).clone(true)[0];
715
773
  nTable.appendChild( nTfoot );
716
774
 
717
775
  /* Copy the widths across - apparently a clone isn't good enough for this */
718
- jQuery("tfoot:eq(0)>tr th", s.nTable).each( function (i) {
719
- jQuery("tfoot:eq(0)>tr th:eq("+i+")", nTable).width( jQuery(this).width() );
776
+ $("tfoot:eq(0)>tr th", s.nTable).each( function (i) {
777
+ $("tfoot:eq(0)>tr th:eq("+i+")", nTable).width( $(this).width() );
720
778
  } );
721
779
 
722
- jQuery("tfoot:eq(0)>tr td", s.nTable).each( function (i) {
723
- jQuery("tfoot:eq(0)>tr th:eq("+i+")", nTable)[0].style.width( jQuery(this).width() );
780
+ $("tfoot:eq(0)>tr td", s.nTable).each( function (i) {
781
+ $("tfoot:eq(0)>tr td:eq("+i+")", nTable).width( $(this).width() );
724
782
  } );
725
783
  },
726
784
 
727
785
  /*
728
786
  * Function: _fnCloneTLeft
729
- * Purpose: Clone the left column
787
+ * Purpose: Clone the left column(s)
730
788
  * Returns: -
731
789
  * Inputs: object:oCache - the cached values for this fixed element
732
790
  */
@@ -735,8 +793,6 @@ FixedHeader.prototype = {
735
793
  var s = this.fnGetSettings();
736
794
  var nTable = oCache.nNode;
737
795
  var nBody = $('tbody', s.nTable)[0];
738
- var iCols = $('tbody tr:eq(0) td', s.nTable).length;
739
- var bRubbishOldIE = ($.browser.msie && ($.browser.version == "6.0" || $.browser.version == "7.0"));
740
796
 
741
797
  /* Remove any children the cloned table has */
742
798
  while ( nTable.childNodes.length > 0 )
@@ -745,46 +801,51 @@ FixedHeader.prototype = {
745
801
  }
746
802
 
747
803
  /* Is this the most efficient way to do this - it looks horrible... */
748
- nTable.appendChild( jQuery("thead", s.nTable).clone(true)[0] );
749
- nTable.appendChild( jQuery("tbody", s.nTable).clone(true)[0] );
804
+ nTable.appendChild( $("thead", s.nTable).clone(true)[0] );
805
+ nTable.appendChild( $("tbody", s.nTable).clone(true)[0] );
750
806
  if ( s.bFooter )
751
807
  {
752
- nTable.appendChild( jQuery("tfoot", s.nTable).clone(true)[0] );
808
+ nTable.appendChild( $("tfoot", s.nTable).clone(true)[0] );
753
809
  }
754
810
 
755
811
  /* Remove unneeded cells */
812
+ var sSelector = 'gt(' + (oCache.iCells - 1) + ')';
756
813
  $('thead tr', nTable).each( function (k) {
757
- $('th:gt(0)', this).remove();
814
+ $('th:' + sSelector, this).remove();
758
815
  } );
759
816
 
760
817
  $('tfoot tr', nTable).each( function (k) {
761
- $('th:gt(0)', this).remove();
818
+ $('th:' + sSelector, this).remove();
762
819
  } );
763
820
 
764
821
  $('tbody tr', nTable).each( function (k) {
765
- $('td:gt(0)', this).remove();
822
+ $('td:' + sSelector, this).remove();
766
823
  } );
767
824
 
825
+ this.fnEqualiseHeights( 'thead', nBody.parentNode, nTable );
768
826
  this.fnEqualiseHeights( 'tbody', nBody.parentNode, nTable );
827
+ this.fnEqualiseHeights( 'tfoot', nBody.parentNode, nTable );
769
828
 
770
- var iWidth = jQuery('thead tr th:eq(0)', s.nTable).outerWidth();
829
+ var iWidth = 0;
830
+ for (var i = 0; i < oCache.iCells; i++) {
831
+ iWidth += $('thead tr th:eq(' + i + ')', s.nTable).outerWidth();
832
+ }
771
833
  nTable.style.width = iWidth+"px";
772
834
  oCache.nWrapper.style.width = iWidth+"px";
773
835
  },
774
836
 
775
837
  /*
776
838
  * Function: _fnCloneTRight
777
- * Purpose: Clone the right most colun
839
+ * Purpose: Clone the right most column(s)
778
840
  * Returns: -
779
- * Inputs: object:oCache - the cahced values for this fixed element
841
+ * Inputs: object:oCache - the cached values for this fixed element
780
842
  */
781
843
  _fnCloneTRight: function ( oCache )
782
844
  {
783
845
  var s = this.fnGetSettings();
784
846
  var nBody = $('tbody', s.nTable)[0];
785
847
  var nTable = oCache.nNode;
786
- var iCols = jQuery('tbody tr:eq(0) td', s.nTable).length;
787
- var bRubbishOldIE = ($.browser.msie && ($.browser.version == "6.0" || $.browser.version == "7.0"));
848
+ var iCols = $('tbody tr:eq(0) td', s.nTable).length;
788
849
 
789
850
  /* Remove any children the cloned table has */
790
851
  while ( nTable.childNodes.length > 0 )
@@ -793,23 +854,28 @@ FixedHeader.prototype = {
793
854
  }
794
855
 
795
856
  /* Is this the most efficient way to do this - it looks horrible... */
796
- nTable.appendChild( jQuery("thead", s.nTable).clone(true)[0] );
797
- nTable.appendChild( jQuery("tbody", s.nTable).clone(true)[0] );
857
+ nTable.appendChild( $("thead", s.nTable).clone(true)[0] );
858
+ nTable.appendChild( $("tbody", s.nTable).clone(true)[0] );
798
859
  if ( s.bFooter )
799
860
  {
800
- nTable.appendChild( jQuery("tfoot", s.nTable).clone(true)[0] );
861
+ nTable.appendChild( $("tfoot", s.nTable).clone(true)[0] );
801
862
  }
802
- jQuery('thead tr th:not(:nth-child('+iCols+'n))', nTable).remove();
803
- jQuery('tfoot tr th:not(:nth-child('+iCols+'n))', nTable).remove();
863
+ $('thead tr th:lt('+(iCols-oCache.iCells)+')', nTable).remove();
864
+ $('tfoot tr th:lt('+(iCols-oCache.iCells)+')', nTable).remove();
804
865
 
805
866
  /* Remove unneeded cells */
806
867
  $('tbody tr', nTable).each( function (k) {
807
- $('td:lt('+(iCols-1)+')', this).remove();
868
+ $('td:lt('+(iCols-oCache.iCells)+')', this).remove();
808
869
  } );
809
870
 
871
+ this.fnEqualiseHeights( 'thead', nBody.parentNode, nTable );
810
872
  this.fnEqualiseHeights( 'tbody', nBody.parentNode, nTable );
873
+ this.fnEqualiseHeights( 'tfoot', nBody.parentNode, nTable );
811
874
 
812
- var iWidth = jQuery('thead tr th:eq('+(iCols-1)+')', s.nTable).outerWidth();
875
+ var iWidth = 0;
876
+ for (var i = 0; i < oCache.iCells; i++) {
877
+ iWidth += $('thead tr th:eq('+(iCols-1-i)+')', s.nTable).outerWidth();
878
+ }
813
879
  nTable.style.width = iWidth+"px";
814
880
  oCache.nWrapper.style.width = iWidth+"px";
815
881
  },
@@ -827,27 +893,27 @@ FixedHeader.prototype = {
827
893
  */
828
894
  "fnEqualiseHeights": function ( parent, original, clone )
829
895
  {
830
- var that = this,
831
- jqBoxHack = $(parent+' tr:eq(0)', original).children(':eq(0)'),
832
- iBoxHack = jqBoxHack.outerHeight() - jqBoxHack.height(),
833
- bRubbishOldIE = ($.browser.msie && ($.browser.version == "6.0" || $.browser.version == "7.0"));
896
+ var that = this;
897
+ var originals = $(parent +' tr', original);
898
+ var height;
834
899
 
835
- /* Remove cells which are not needed and copy the height from the original table */
836
900
  $(parent+' tr', clone).each( function (k) {
837
- /* Can we use some kind of object detection here?! This is very nasty - damn browsers */
838
- if ( $.browser.mozilla || $.browser.opera )
839
- {
840
- $(this).children().height( $(parent+' tr:eq('+k+')', original).outerHeight() );
841
- }
842
- else
843
- {
844
- $(this).children().height( $(parent+' tr:eq('+k+')', original).outerHeight() - iBoxHack );
901
+ height = originals.eq( k ).css('height');
902
+
903
+ // This is nasty :-(. IE has a sub-pixel error even when setting
904
+ // the height below (the Firefox fix) which causes the fixed column
905
+ // to go out of alignment. Need to add a pixel before the assignment
906
+ // Can this be feature detected? Not sure how...
907
+ if ( navigator.appName == 'Microsoft Internet Explorer' ) {
908
+ height = parseInt( height, 10 ) + 1;
845
909
  }
846
910
 
847
- if ( !bRubbishOldIE )
848
- {
849
- $(parent+' tr:eq('+k+')', original).height( $(parent+' tr:eq('+k+')', original).outerHeight() );
850
- }
911
+ $(this).css( 'height', height );
912
+
913
+ // For Firefox to work, we need to also set the height of the
914
+ // original row, to the value that we read from it! Otherwise there
915
+ // is a sub-pixel rounding error
916
+ originals.eq( k ).css( 'height', height );
851
917
  } );
852
918
  }
853
919
  };
@@ -899,8 +965,8 @@ FixedHeader.afnScroll = [];
899
965
  FixedHeader.fnMeasure = function ()
900
966
  {
901
967
  var
902
- jqWin = jQuery(window),
903
- jqDoc = jQuery(document),
968
+ jqWin = $(window),
969
+ jqDoc = $(document),
904
970
  oWin = FixedHeader.oWin,
905
971
  oDoc = FixedHeader.oDoc;
906
972
 
@@ -916,8 +982,7 @@ FixedHeader.fnMeasure = function ()
916
982
  };
917
983
 
918
984
 
919
- FixedHeader.VERSION = "2.0.6";
920
- FixedHeader.prototype.VERSION = FixedHeader.VERSION;
985
+ FixedHeader.version = "2.1.1";
921
986
 
922
987
 
923
988
  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -928,10 +993,32 @@ FixedHeader.prototype.VERSION = FixedHeader.VERSION;
928
993
  * Just one 'scroll' event handler in FixedHeader, which calls the required components. This is
929
994
  * done as an optimisation, to reduce calculation and proagation time
930
995
  */
931
- jQuery(window).scroll( function () {
996
+ $(window).scroll( function () {
932
997
  FixedHeader.fnMeasure();
933
- for ( var i=0, iLen=FixedHeader.afnScroll.length ; i<iLen ; i++ )
934
- {
998
+
999
+ for ( var i=0, iLen=FixedHeader.afnScroll.length ; i<iLen ; i++ ) {
935
1000
  FixedHeader.afnScroll[i]();
936
1001
  }
937
1002
  } );
1003
+
1004
+
1005
+ $.fn.dataTable.FixedHeader = FixedHeader;
1006
+ $.fn.DataTable.FixedHeader = FixedHeader;
1007
+
1008
+
1009
+ return FixedHeader;
1010
+ }; // /factory
1011
+
1012
+
1013
+ // Define as an AMD module if possible
1014
+ if ( typeof define === 'function' && define.amd ) {
1015
+ define( 'datatables-fixedheader', ['jquery', 'datatables'], factory );
1016
+ }
1017
+ else if ( jQuery && !jQuery.fn.dataTable.FixedHeader ) {
1018
+ // Otherwise simply initialise as normal, stopping multiple evaluation
1019
+ factory( jQuery, jQuery.fn.dataTable );
1020
+ }
1021
+
1022
+
1023
+ })(window, document);
1024
+