jquery-datatables-rails 1.12.2 → 2.1.10.0.0

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.
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
+