jquery-datatables-rails 1.9.1.3 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Robin Wenglewski, Sébastien Grosjean, ed al
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Readme.md CHANGED
@@ -44,6 +44,32 @@ $('.datatable').dataTable({
44
44
 
45
45
  ## Plugins
46
46
 
47
- Right now, the only plugin that is available is fnReloadAjax. Check out the [assets directory][assets].
47
+ Only a few plugins are currently available
48
+
49
+ * api
50
+ * fnReloadAjax
51
+ * fnGetColumnData
52
+ * sorting
53
+ * numbersHtml
54
+ * typeDetection
55
+ * numberHtml
56
+
57
+ Check out the [assets directory][assets].
58
+
59
+ ## Extras
60
+
61
+ Only a few extras are currently available:
62
+
63
+ * FixedColumns
64
+ * FixedHeader
65
+
66
+ To add an extra into your application, include it like follow:
67
+
68
+ `//= require dataTables/extras/[ExtraName]`
69
+
70
+ Make sure to also add it's initialization as described on [datatables extras' site][datatables_extras]
71
+
48
72
 
49
73
  [assets]: https://github.com/rweng/jquery-datatables-rails/tree/master/vendor/assets/javascripts
74
+ [extras]: https://github.com/rweng/jquery-datatables-rails/tree/master/vendor/assets/javascripts/dataTables/extras
75
+ [datatables_extras]: http://datatables.net/extras/
@@ -1,7 +1,7 @@
1
1
  module Jquery
2
2
  module Datatables
3
3
  module Rails
4
- VERSION = "1.9.1.3"
4
+ VERSION = "1.10.0"
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,1226 @@
1
+ /**
2
+ * @summary FixedColumns
3
+ * @description Freeze columns in place on a scrolling DataTable
4
+ * @file FixedColumns.js
5
+ * @version 2.0.3
6
+ * @author Allan Jardine (www.sprymedia.co.uk)
7
+ * @license GPL v2 or BSD 3 point style
8
+ * @contact www.sprymedia.co.uk/contact
9
+ *
10
+ * @copyright Copyright 2010-2011 Allan Jardine, all rights reserved.
11
+ *
12
+ * This source file is free software, under either the GPL v2 license or a
13
+ * BSD style license, available at:
14
+ * http://datatables.net/license_gpl2
15
+ * http://datatables.net/license_bsd
16
+ */
17
+
18
+
19
+ /* Global scope for FixedColumns */
20
+ var FixedColumns;
21
+
22
+ (function($, window, document) {
23
+
24
+
25
+ /**
26
+ * When making use of DataTables' x-axis scrolling feature, you may wish to
27
+ * fix the left most column in place. This plug-in for DataTables provides
28
+ * exactly this option (note for non-scrolling tables, please use the
29
+ * FixedHeader plug-in, which can fix headers, footers and columns). Key
30
+ * features include:
31
+ * <ul class="limit_length">
32
+ * <li>Freezes the left or right most columns to the side of the table</li>
33
+ * <li>Option to freeze two or more columns</li>
34
+ * <li>Full integration with DataTables' scrolling options</li>
35
+ * <li>Speed - FixedColumns is fast in its operation</li>
36
+ * </ul>
37
+ *
38
+ * @class
39
+ * @constructor
40
+ * @param {object} oDT DataTables instance
41
+ * @param {object} [oInit={}] Configuration object for FixedColumns. Options are defined by {@link FixedColumns.defaults}
42
+ *
43
+ * @requires jQuery 1.3+
44
+ * @requires DataTables 1.8.0+
45
+ *
46
+ * @example
47
+ * var oTable = $('#example').dataTable( {
48
+ * "sScrollX": "100%"
49
+ * } );
50
+ * new FixedColumns( oTable );
51
+ */
52
+ FixedColumns = function ( oDT, oInit ) {
53
+ /* Sanity check - you just know it will happen */
54
+ if ( ! this instanceof FixedColumns )
55
+ {
56
+ alert( "FixedColumns warning: FixedColumns must be initialised with the 'new' keyword." );
57
+ return;
58
+ }
59
+
60
+ if ( typeof oInit == 'undefined' )
61
+ {
62
+ oInit = {};
63
+ }
64
+
65
+ /**
66
+ * Settings object which contains customisable information for FixedColumns instance
67
+ * @namespace
68
+ * @extends FixedColumns.defaults
69
+ */
70
+ this.s = {
71
+ /**
72
+ * DataTables settings objects
73
+ * @type object
74
+ * @default Obtained from DataTables instance
75
+ */
76
+ "dt": oDT.fnSettings(),
77
+
78
+ /**
79
+ * Number of columns in the DataTable - stored for quick access
80
+ * @type int
81
+ * @default Obtained from DataTables instance
82
+ */
83
+ "iTableColumns": oDT.fnSettings().aoColumns.length,
84
+
85
+ /**
86
+ * Original widths of the columns as rendered by DataTables
87
+ * @type array.<int>
88
+ * @default []
89
+ */
90
+ "aiWidths": [],
91
+
92
+ /**
93
+ * Flag to indicate if we are dealing with IE6/7 as these browsers need a little hack
94
+ * in the odd place
95
+ * @type boolean
96
+ * @default Automatically calculated
97
+ * @readonly
98
+ */
99
+ "bOldIE": ($.browser.msie && ($.browser.version == "6.0" || $.browser.version == "7.0"))
100
+ };
101
+
102
+
103
+ /**
104
+ * DOM elements used by the class instance
105
+ * @namespace
106
+ *
107
+ */
108
+ this.dom = {
109
+ /**
110
+ * DataTables scrolling element
111
+ * @type node
112
+ * @default null
113
+ */
114
+ "scroller": null,
115
+
116
+ /**
117
+ * DataTables header table
118
+ * @type node
119
+ * @default null
120
+ */
121
+ "header": null,
122
+
123
+ /**
124
+ * DataTables body table
125
+ * @type node
126
+ * @default null
127
+ */
128
+ "body": null,
129
+
130
+ /**
131
+ * DataTables footer table
132
+ * @type node
133
+ * @default null
134
+ */
135
+ "footer": null,
136
+
137
+ /**
138
+ * Display grid elements
139
+ * @namespace
140
+ */
141
+ "grid": {
142
+ /**
143
+ * Grid wrapper. This is the container element for the 3x3 grid
144
+ * @type node
145
+ * @default null
146
+ */
147
+ "wrapper": null,
148
+
149
+ /**
150
+ * DataTables scrolling element. This element is the DataTables
151
+ * component in the display grid (making up the main table - i.e.
152
+ * not the fixed columns).
153
+ * @type node
154
+ * @default null
155
+ */
156
+ "dt": null,
157
+
158
+ /**
159
+ * Left fixed column grid components
160
+ * @namespace
161
+ */
162
+ "left": {
163
+ "wrapper": null,
164
+ "head": null,
165
+ "body": null,
166
+ "foot": null
167
+ },
168
+
169
+ /**
170
+ * Right fixed column grid components
171
+ * @namespace
172
+ */
173
+ "right": {
174
+ "wrapper": null,
175
+ "head": null,
176
+ "body": null,
177
+ "foot": null
178
+ }
179
+ },
180
+
181
+ /**
182
+ * Cloned table nodes
183
+ * @namespace
184
+ */
185
+ "clone": {
186
+ /**
187
+ * Left column cloned table nodes
188
+ * @namespace
189
+ */
190
+ "left": {
191
+ /**
192
+ * Cloned header table
193
+ * @type node
194
+ * @default null
195
+ */
196
+ "header": null,
197
+
198
+ /**
199
+ * Cloned body table
200
+ * @type node
201
+ * @default null
202
+ */
203
+ "body": null,
204
+
205
+ /**
206
+ * Cloned footer table
207
+ * @type node
208
+ * @default null
209
+ */
210
+ "footer": null
211
+ },
212
+
213
+ /**
214
+ * Right column cloned table nodes
215
+ * @namespace
216
+ */
217
+ "right": {
218
+ /**
219
+ * Cloned header table
220
+ * @type node
221
+ * @default null
222
+ */
223
+ "header": null,
224
+
225
+ /**
226
+ * Cloned body table
227
+ * @type node
228
+ * @default null
229
+ */
230
+ "body": null,
231
+
232
+ /**
233
+ * Cloned footer table
234
+ * @type node
235
+ * @default null
236
+ */
237
+ "footer": null
238
+ }
239
+ }
240
+ };
241
+
242
+ /* Attach the instance to the DataTables instance so it can be accessed easily */
243
+ this.s.dt.oFixedColumns = this;
244
+
245
+ /* Let's do it */
246
+ this._fnConstruct( oInit );
247
+ };
248
+
249
+
250
+
251
+ FixedColumns.prototype = {
252
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
253
+ * Public methods
254
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
255
+
256
+ /**
257
+ * Update the fixed columns - including headers and footers. Note that FixedColumns will
258
+ * automatically update the display whenever the host DataTable redraws.
259
+ * @returns {void}
260
+ * @example
261
+ * var oTable = $('#example').dataTable( {
262
+ * "sScrollX": "100%"
263
+ * } );
264
+ * var oFC = new FixedColumns( oTable );
265
+ *
266
+ * // at some later point when the table has been manipulated....
267
+ * oFC.fnUpdate();
268
+ */
269
+ "fnUpdate": function ()
270
+ {
271
+ this._fnDraw( true );
272
+ },
273
+
274
+
275
+ /**
276
+ * Recalculate the resizes of the 3x3 grid that FixedColumns uses for display of the table.
277
+ * This is useful if you update the width of the table container. Note that FixedColumns will
278
+ * perform this function automatically when the window.resize event is fired.
279
+ * @returns {void}
280
+ * @example
281
+ * var oTable = $('#example').dataTable( {
282
+ * "sScrollX": "100%"
283
+ * } );
284
+ * var oFC = new FixedColumns( oTable );
285
+ *
286
+ * // Resize the table container and then have FixedColumns adjust its layout....
287
+ * $('#content').width( 1200 );
288
+ * oFC.fnRedrawLayout();
289
+ */
290
+ "fnRedrawLayout": function ()
291
+ {
292
+ this._fnGridLayout();
293
+ },
294
+
295
+
296
+ /**
297
+ * Mark a row such that it's height should be recalculated when using 'semiauto' row
298
+ * height matching. This function will have no effect when 'none' or 'auto' row height
299
+ * matching is used.
300
+ * @param {Node} nTr TR element that should have it's height recalculated
301
+ * @returns {void}
302
+ * @example
303
+ * var oTable = $('#example').dataTable( {
304
+ * "sScrollX": "100%"
305
+ * } );
306
+ * var oFC = new FixedColumns( oTable );
307
+ *
308
+ * // manipulate the table - mark the row as needing an update then update the table
309
+ * // this allows the redraw performed by DataTables fnUpdate to recalculate the row
310
+ * // height
311
+ * oFC.fnRecalculateHeight();
312
+ * oTable.fnUpdate( $('#example tbody tr:eq(0)')[0], ["insert date", 1, 2, 3 ... ]);
313
+ */
314
+ "fnRecalculateHeight": function ( nTr )
315
+ {
316
+ nTr._DTTC_iHeight = null;
317
+ nTr.style.height = 'auto';
318
+ },
319
+
320
+
321
+ /**
322
+ * Set the height of a given row - provides cross browser compatibility
323
+ * @param {Node} nTarget TR element that should have it's height recalculated
324
+ * @param {int} iHeight Height in pixels to set
325
+ * @returns {void}
326
+ * @example
327
+ * var oTable = $('#example').dataTable( {
328
+ * "sScrollX": "100%"
329
+ * } );
330
+ * var oFC = new FixedColumns( oTable );
331
+ *
332
+ * // You may want to do this after manipulating a row in the fixed column
333
+ * oFC.fnSetRowHeight( $('#example tbody tr:eq(0)')[0], 50 );
334
+ */
335
+ "fnSetRowHeight": function ( nTarget, iHeight )
336
+ {
337
+ var jqBoxHack = $(nTarget).children(':first');
338
+ var iBoxHack = jqBoxHack.outerHeight() - jqBoxHack.height();
339
+
340
+ /* Can we use some kind of object detection here?! This is very nasty - damn browsers */
341
+ if ( $.browser.mozilla || $.browser.opera )
342
+ {
343
+ nTarget.style.height = iHeight+"px";
344
+ }
345
+ else
346
+ {
347
+ $(nTarget).children().height( iHeight-iBoxHack );
348
+ }
349
+ },
350
+
351
+
352
+
353
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
354
+ * Private methods (they are of course public in JS, but recommended as private)
355
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
356
+
357
+ /**
358
+ * Initialisation for FixedColumns
359
+ * @param {Object} oInit User settings for initialisation
360
+ * @returns {void}
361
+ * @private
362
+ */
363
+ "_fnConstruct": function ( oInit )
364
+ {
365
+ var i, iLen, iWidth,
366
+ that = this;
367
+
368
+ /* Sanity checking */
369
+ if ( typeof this.s.dt.oInstance.fnVersionCheck != 'function' ||
370
+ this.s.dt.oInstance.fnVersionCheck( '1.8.0' ) !== true )
371
+ {
372
+ alert( "FixedColumns "+FixedColumns.VERSION+" required DataTables 1.8.0 or later. "+
373
+ "Please upgrade your DataTables installation" );
374
+ return;
375
+ }
376
+
377
+ if ( this.s.dt.oScroll.sX === "" )
378
+ {
379
+ this.s.dt.oInstance.oApi._fnLog( this.s.dt, 1, "FixedColumns is not needed (no "+
380
+ "x-scrolling in DataTables enabled), so no action will be taken. Use 'FixedHeader' for "+
381
+ "column fixing when scrolling is not enabled" );
382
+ return;
383
+ }
384
+
385
+ /* Apply the settings from the user / defaults */
386
+ this.s = $.extend( true, this.s, FixedColumns.defaults, oInit );
387
+
388
+ /* Set up the DOM as we need it and cache nodes */
389
+ this.dom.grid.dt = $(this.s.dt.nTable).parents('div.dataTables_scroll')[0];
390
+ this.dom.scroller = $('div.dataTables_scrollBody', this.dom.grid.dt )[0];
391
+
392
+ var iScrollWidth = $(this.dom.grid.dt).width();
393
+ var iLeftWidth = 0;
394
+ var iRightWidth = 0;
395
+
396
+ $('tbody>tr:eq(0)>td', this.s.dt.nTable).each( function (i) {
397
+ iWidth = $(this).outerWidth();
398
+ that.s.aiWidths.push( iWidth );
399
+ if ( i < that.s.iLeftColumns )
400
+ {
401
+ iLeftWidth += iWidth;
402
+ }
403
+ if ( that.s.iTableColumns-that.s.iRightColumns <= i )
404
+ {
405
+ iRightWidth += iWidth;
406
+ }
407
+ } );
408
+
409
+ if ( this.s.iLeftWidth === null )
410
+ {
411
+ this.s.iLeftWidth = this.s.sLeftWidth == 'fixed' ?
412
+ iLeftWidth : (iLeftWidth/iScrollWidth) * 100;
413
+ }
414
+
415
+ if ( this.s.iRightWidth === null )
416
+ {
417
+ this.s.iRightWidth = this.s.sRightWidth == 'fixed' ?
418
+ iRightWidth : (iRightWidth/iScrollWidth) * 100;
419
+ }
420
+
421
+ /* Set up the DOM that we want for the fixed column layout grid */
422
+ this._fnGridSetup();
423
+
424
+ /* Use the DataTables API method fnSetColumnVis to hide the columns we are going to fix */
425
+ for ( i=0 ; i<this.s.iLeftColumns ; i++ )
426
+ {
427
+ this.s.dt.oInstance.fnSetColumnVis( i, false );
428
+ }
429
+ for ( i=this.s.iTableColumns - this.s.iRightColumns ; i<this.s.iTableColumns ; i++ )
430
+ {
431
+ this.s.dt.oInstance.fnSetColumnVis( i, false );
432
+ }
433
+
434
+ /* Event handlers */
435
+ $(this.dom.scroller).scroll( function () {
436
+ that.dom.grid.left.body.scrollTop = that.dom.scroller.scrollTop;
437
+ if ( that.s.iRightColumns > 0 )
438
+ {
439
+ that.dom.grid.right.body.scrollTop = that.dom.scroller.scrollTop;
440
+ }
441
+ } );
442
+
443
+ $(window).resize( function () {
444
+ that._fnGridLayout.call( that );
445
+ } );
446
+
447
+ var bFirstDraw = true;
448
+ this.s.dt.aoDrawCallback = [ {
449
+ "fn": function () {
450
+ that._fnDraw.call( that, bFirstDraw );
451
+ that._fnGridHeight( that );
452
+ bFirstDraw = false;
453
+ },
454
+ "sName": "FixedColumns"
455
+ } ].concat( this.s.dt.aoDrawCallback );
456
+
457
+ /* Get things right to start with - note that due to adjusting the columns, there must be
458
+ * another redraw of the main table. It doesn't need to be a full redraw however.
459
+ */
460
+ this._fnGridLayout();
461
+ this._fnGridHeight();
462
+ this.s.dt.oInstance.fnDraw(false);
463
+ },
464
+
465
+
466
+ /**
467
+ * Set up the DOM for the fixed column. The way the layout works is to create a 1x3 grid
468
+ * for the left column, the DataTable (for which we just reuse the scrolling element DataTable
469
+ * puts into the DOM) and the right column. In each of he two fixed column elements there is a
470
+ * grouping wrapper element and then a head, body and footer wrapper. In each of these we then
471
+ * place the cloned header, body or footer tables. This effectively gives as 3x3 grid structure.
472
+ * @returns {void}
473
+ * @private
474
+ */
475
+ "_fnGridSetup": function ()
476
+ {
477
+ var that = this;
478
+
479
+ this.dom.body = this.s.dt.nTable;
480
+ this.dom.header = this.s.dt.nTHead.parentNode;
481
+ this.dom.header.parentNode.parentNode.style.position = "relative";
482
+
483
+ var nSWrapper =
484
+ $('<div class="DTFC_ScrollWrapper" style="position:relative; clear:both;">'+
485
+ '<div class="DTFC_LeftWrapper" style="position:absolute; top:0; left:0;">'+
486
+ '<div class="DTFC_LeftHeadWrapper" style="position:relative; top:0; left:0; overflow:hidden;"></div>'+
487
+ '<div class="DTFC_LeftBodyWrapper" style="position:relative; top:0; left:0; overflow:hidden;"></div>'+
488
+ '<div class="DTFC_LeftFootWrapper" style="position:relative; top:0; left:0; overflow:hidden;"></div>'+
489
+ '</div>'+
490
+ '<div class="DTFC_RightWrapper" style="position:absolute; top:0; left:0;">'+
491
+ '<div class="DTFC_RightHeadWrapper" style="position:relative; top:0; left:0; overflow:hidden;"></div>'+
492
+ '<div class="DTFC_RightBodyWrapper" style="position:relative; top:0; left:0; overflow:hidden;"></div>'+
493
+ '<div class="DTFC_RightFootWrapper" style="position:relative; top:0; left:0; overflow:hidden;"></div>'+
494
+ '</div>'+
495
+ '</div>')[0];
496
+ nLeft = nSWrapper.childNodes[0];
497
+ nRight = nSWrapper.childNodes[1];
498
+
499
+ this.dom.grid.wrapper = nSWrapper;
500
+ this.dom.grid.left.wrapper = nLeft;
501
+ this.dom.grid.left.head = nLeft.childNodes[0];
502
+ this.dom.grid.left.body = nLeft.childNodes[1];
503
+
504
+ if ( this.s.iRightColumns > 0 )
505
+ {
506
+ this.dom.grid.right.wrapper = nRight;
507
+ this.dom.grid.right.head = nRight.childNodes[0];
508
+ this.dom.grid.right.body = nRight.childNodes[1];
509
+ }
510
+
511
+ if ( this.s.dt.nTFoot )
512
+ {
513
+ this.dom.footer = this.s.dt.nTFoot.parentNode;
514
+ this.dom.grid.left.foot = nLeft.childNodes[2];
515
+ if ( this.s.iRightColumns > 0 )
516
+ {
517
+ this.dom.grid.right.foot = nRight.childNodes[2];
518
+ }
519
+ }
520
+
521
+ nSWrapper.appendChild( nLeft );
522
+ this.dom.grid.dt.parentNode.insertBefore( nSWrapper, this.dom.grid.dt );
523
+ nSWrapper.appendChild( this.dom.grid.dt );
524
+
525
+ this.dom.grid.dt.style.position = "absolute";
526
+ this.dom.grid.dt.style.top = "0px";
527
+ this.dom.grid.dt.style.left = this.s.iLeftWidth+"px";
528
+ this.dom.grid.dt.style.width = ($(this.dom.grid.dt).width()-this.s.iLeftWidth-this.s.iRightWidth)+"px";
529
+ },
530
+
531
+
532
+ /**
533
+ * Style and position the grid used for the FixedColumns layout based on the instance settings.
534
+ * Specifically sLeftWidth ('fixed' or 'absolute'), iLeftWidth (px if fixed, % if absolute) and
535
+ * there 'right' counterparts.
536
+ * @returns {void}
537
+ * @private
538
+ */
539
+ "_fnGridLayout": function ()
540
+ {
541
+ var oGrid = this.dom.grid;
542
+ var iTotal = $(oGrid.wrapper).width();
543
+ var iLeft = 0, iRight = 0, iRemainder = 0;
544
+
545
+ if ( this.s.sLeftWidth == 'fixed' )
546
+ {
547
+ iLeft = this.s.iLeftWidth;
548
+ }
549
+ else
550
+ {
551
+ iLeft = ( this.s.iLeftWidth / 100 ) * iTotal;
552
+ }
553
+
554
+ if ( this.s.sRightWidth == 'fixed' )
555
+ {
556
+ iRight = this.s.iRightWidth;
557
+ }
558
+ else
559
+ {
560
+ iRight = ( this.s.iRightWidth / 100 ) * iTotal;
561
+ }
562
+
563
+ iRemainder = iTotal - iLeft - iRight;
564
+
565
+ oGrid.left.wrapper.style.width = iLeft+"px";
566
+ oGrid.dt.style.width = iRemainder+"px";
567
+ oGrid.dt.style.left = iLeft+"px";
568
+
569
+ if ( this.s.iRightColumns > 0 )
570
+ {
571
+ oGrid.right.wrapper.style.width = iRight+"px";
572
+ oGrid.right.wrapper.style.left = (iTotal-iRight)+"px";
573
+ }
574
+ },
575
+
576
+
577
+ /**
578
+ * Recalculate and set the height of the grid components used for positioning of the
579
+ * FixedColumn display grid.
580
+ * @returns {void}
581
+ * @private
582
+ */
583
+ "_fnGridHeight": function ()
584
+ {
585
+ var oGrid = this.dom.grid;
586
+ var iHeight = $(this.dom.grid.dt).height();
587
+
588
+ oGrid.wrapper.style.height = iHeight+"px";
589
+ oGrid.left.body.style.height = $(this.dom.scroller).height()+"px";
590
+ oGrid.left.wrapper.style.height = iHeight+"px";
591
+
592
+ if ( this.s.iRightColumns > 0 )
593
+ {
594
+ oGrid.right.wrapper.style.height = iHeight+"px";
595
+ oGrid.right.body.style.height = $(this.dom.scroller).height()+"px";
596
+ }
597
+ },
598
+
599
+
600
+ /**
601
+ * Clone and position the fixed columns
602
+ * @returns {void}
603
+ * @param {Boolean} bAll Indicate if the header and footer should be updated as well (true)
604
+ * @private
605
+ */
606
+ "_fnDraw": function ( bAll )
607
+ {
608
+ this._fnCloneLeft( bAll );
609
+ this._fnCloneRight( bAll );
610
+
611
+ /* Draw callback function */
612
+ if ( this.s.fnDrawCallback !== null )
613
+ {
614
+ this.s.fnDrawCallback.call( this, this.dom.clone.left, this.dom.clone.right );
615
+ }
616
+
617
+ /* Event triggering */
618
+ $(this).trigger( 'draw', {
619
+ "leftClone": this.dom.clone.left,
620
+ "rightClone": this.dom.clone.right
621
+ } );
622
+ },
623
+
624
+
625
+ /**
626
+ * Clone the right columns
627
+ * @returns {void}
628
+ * @param {Boolean} bAll Indicate if the header and footer should be updated as well (true)
629
+ * @private
630
+ */
631
+ "_fnCloneRight": function ( bAll )
632
+ {
633
+ if ( this.s.iRightColumns <= 0 )
634
+ {
635
+ return;
636
+ }
637
+
638
+ var that = this,
639
+ i, jq,
640
+ aiColumns = [];
641
+
642
+ for ( i=this.s.iTableColumns-this.s.iRightColumns ; i<this.s.iTableColumns ; i++ )
643
+ {
644
+ aiColumns.push( i );
645
+ }
646
+
647
+ this._fnClone( this.dom.clone.right, this.dom.grid.right, aiColumns, bAll );
648
+ },
649
+
650
+
651
+ /**
652
+ * Clone the left columns
653
+ * @returns {void}
654
+ * @param {Boolean} bAll Indicate if the header and footer should be updated as well (true)
655
+ * @private
656
+ */
657
+ "_fnCloneLeft": function ( bAll )
658
+ {
659
+ if ( this.s.iLeftColumns <= 0 )
660
+ {
661
+ return;
662
+ }
663
+
664
+ var that = this,
665
+ i, jq,
666
+ aiColumns = [];
667
+
668
+ for ( i=0 ; i<this.s.iLeftColumns ; i++ )
669
+ {
670
+ aiColumns.push( i );
671
+ }
672
+
673
+ this._fnClone( this.dom.clone.left, this.dom.grid.left, aiColumns, bAll );
674
+ },
675
+
676
+
677
+ /**
678
+ * Make a copy of the layout object for a header or footer element from DataTables. Note that
679
+ * this method will clone the nodes in the layout object.
680
+ * @returns {Array} Copy of the layout array
681
+ * @param {Object} aoOriginal Layout array from DataTables (aoHeader or aoFooter)
682
+ * @param {Object} aiColumns Columns to copy
683
+ * @private
684
+ */
685
+ "_fnCopyLayout": function ( aoOriginal, aiColumns )
686
+ {
687
+ var aReturn = [];
688
+ var aClones = [];
689
+ var aCloned = [];
690
+
691
+ for ( var i=0, iLen=aoOriginal.length ; i<iLen ; i++ )
692
+ {
693
+ var aRow = [];
694
+ aRow.nTr = $(aoOriginal[i].nTr).clone(true)[0];
695
+
696
+ for ( var j=0, jLen=this.s.iTableColumns ; j<jLen ; j++ )
697
+ {
698
+ if ( $.inArray( j, aiColumns ) === -1 )
699
+ {
700
+ continue;
701
+ }
702
+
703
+ var iCloned = $.inArray( aoOriginal[i][j].cell, aCloned );
704
+ if ( iCloned === -1 )
705
+ {
706
+ var nClone = $(aoOriginal[i][j].cell).clone(true)[0];
707
+ aClones.push( nClone );
708
+ aCloned.push( aoOriginal[i][j].cell );
709
+
710
+ aRow.push( {
711
+ "cell": nClone,
712
+ "unique": aoOriginal[i][j].unique
713
+ } );
714
+ }
715
+ else
716
+ {
717
+ aRow.push( {
718
+ "cell": aClones[ iCloned ],
719
+ "unique": aoOriginal[i][j].unique
720
+ } );
721
+ }
722
+ }
723
+
724
+ aReturn.push( aRow );
725
+ }
726
+
727
+ return aReturn;
728
+ },
729
+
730
+
731
+ /**
732
+ * Clone the DataTable nodes and place them in the DOM (sized correctly)
733
+ * @returns {void}
734
+ * @param {Object} oClone Object containing the header, footer and body cloned DOM elements
735
+ * @param {Object} oGrid Grid object containing the display grid elements for the cloned
736
+ * column (left or right)
737
+ * @param {Array} aiColumns Column indexes which should be operated on from the DataTable
738
+ * @param {Boolean} bAll Indicate if the header and footer should be updated as well (true)
739
+ * @private
740
+ */
741
+ "_fnClone": function ( oClone, oGrid, aiColumns, bAll )
742
+ {
743
+ var that = this,
744
+ i, iLen, j, jLen, jq, nTarget, iColumn, nClone, iIndex;
745
+
746
+ /*
747
+ * Header
748
+ */
749
+ if ( bAll )
750
+ {
751
+ if ( oClone.header !== null )
752
+ {
753
+ oClone.header.parentNode.removeChild( oClone.header );
754
+ }
755
+ oClone.header = $(this.dom.header).clone(true)[0];
756
+ oClone.header.className += " DTFC_Cloned";
757
+ oClone.header.style.width = "100%";
758
+ oGrid.head.appendChild( oClone.header );
759
+
760
+ /* Copy the DataTables layout cache for the header for our floating column */
761
+ var aoCloneLayout = this._fnCopyLayout( this.s.dt.aoHeader, aiColumns );
762
+ var jqCloneThead = $('>thead', oClone.header);
763
+ jqCloneThead.empty();
764
+
765
+ /* Add the created cloned TR elements to the table */
766
+ for ( i=0, iLen=aoCloneLayout.length ; i<iLen ; i++ )
767
+ {
768
+ jqCloneThead[0].appendChild( aoCloneLayout[i].nTr );
769
+ }
770
+
771
+ /* Use the handy _fnDrawHead function in DataTables to do the rowspan/colspan
772
+ * calculations for us
773
+ */
774
+ this.s.dt.oApi._fnDrawHead( this.s.dt, aoCloneLayout, true );
775
+ }
776
+ else
777
+ {
778
+ /* To ensure that we copy cell classes exactly, regardless of colspan, multiple rows
779
+ * etc, we make a copy of the header from the DataTable again, but don't insert the
780
+ * cloned cells, just copy the classes across. To get the matching layout for the
781
+ * fixed component, we use the DataTables _fnDetectHeader method, allowing 1:1 mapping
782
+ */
783
+ var aoCloneLayout = this._fnCopyLayout( this.s.dt.aoHeader, aiColumns );
784
+ var aoCurrHeader=[];
785
+
786
+ this.s.dt.oApi._fnDetectHeader( aoCurrHeader, $('>thead', oClone.header)[0] );
787
+
788
+ for ( i=0, iLen=aoCloneLayout.length ; i<iLen ; i++ )
789
+ {
790
+ for ( j=0, jLen=aoCloneLayout[i].length ; j<jLen ; j++ )
791
+ {
792
+ aoCurrHeader[i][j].cell.className = aoCloneLayout[i][j].cell.className;
793
+
794
+ // If jQuery UI theming is used we need to copy those elements as well
795
+ $('span.DataTables_sort_icon', aoCurrHeader[i][j].cell).each( function () {
796
+ this.className = $('span.DataTables_sort_icon', aoCloneLayout[i][j].cell)[0].className;
797
+ } );
798
+ }
799
+ }
800
+ }
801
+ this._fnEqualiseHeights( 'thead', this.dom.header, oClone.header );
802
+
803
+ /*
804
+ * Body
805
+ */
806
+ if ( this.s.sHeightMatch == 'auto' )
807
+ {
808
+ /* Remove any heights which have been applied already and let the browser figure it out */
809
+ $('>tbody>tr', that.dom.body).css('height', 'auto');
810
+ }
811
+
812
+ if ( oClone.body !== null )
813
+ {
814
+ oClone.body.parentNode.removeChild( oClone.body );
815
+ oClone.body = null;
816
+ }
817
+
818
+ oClone.body = $(this.dom.body).clone(true)[0];
819
+ oClone.body.className += " DTFC_Cloned";
820
+ oClone.body.style.paddingBottom = this.s.dt.oScroll.iBarWidth+"px";
821
+ oClone.body.style.marginBottom = (this.s.dt.oScroll.iBarWidth*2)+"px"; /* For IE */
822
+ if ( oClone.body.getAttribute('id') !== null )
823
+ {
824
+ oClone.body.removeAttribute('id');
825
+ }
826
+
827
+ $('>thead>tr', oClone.body).empty();
828
+ $('>tfoot', oClone.body).remove();
829
+
830
+ var nBody = $('tbody', oClone.body)[0];
831
+ $(nBody).empty();
832
+ if ( this.s.dt.aiDisplay.length > 0 )
833
+ {
834
+ /* Copy the DataTables' header elements to force the column width in exactly the
835
+ * same way that DataTables does it - have the header element, apply the width and
836
+ * colapse it down
837
+ */
838
+ var nInnerThead = $('>thead>tr', oClone.body)[0];
839
+ for ( iIndex=0 ; iIndex<aiColumns.length ; iIndex++ )
840
+ {
841
+ iColumn = aiColumns[iIndex];
842
+
843
+ nClone = this.s.dt.aoColumns[iColumn].nTh;
844
+ nClone.innerHTML = "";
845
+
846
+ oStyle = nClone.style;
847
+ oStyle.paddingTop = "0";
848
+ oStyle.paddingBottom = "0";
849
+ oStyle.borderTopWidth = "0";
850
+ oStyle.borderBottomWidth = "0";
851
+ oStyle.height = 0;
852
+ oStyle.width = that.s.aiWidths[iColumn]+"px";
853
+
854
+ nInnerThead.appendChild( nClone );
855
+ }
856
+
857
+ /* Add in the tbody elements, cloning form the master table */
858
+ $('>tbody>tr', that.dom.body).each( function (z) {
859
+ var n = this.cloneNode(false);
860
+ var i = that.s.dt.oFeatures.bServerSide===false ?
861
+ that.s.dt.aiDisplay[ that.s.dt._iDisplayStart+z ] : z;
862
+ for ( iIndex=0 ; iIndex<aiColumns.length ; iIndex++ )
863
+ {
864
+ iColumn = aiColumns[iIndex];
865
+ if ( typeof that.s.dt.aoData[i]._anHidden[iColumn] != 'undefined' )
866
+ {
867
+ nClone = $(that.s.dt.aoData[i]._anHidden[iColumn]).clone(true)[0];
868
+ n.appendChild( nClone );
869
+ }
870
+ }
871
+ nBody.appendChild( n );
872
+ } );
873
+ }
874
+ else
875
+ {
876
+ $('>tbody>tr', that.dom.body).each( function (z) {
877
+ nClone = this.cloneNode(true);
878
+ nClone.className += ' DTFC_NoData';
879
+ $('td', nClone).html('');
880
+ nBody.appendChild( nClone );
881
+ } );
882
+ }
883
+
884
+ oClone.body.style.width = "100%";
885
+ oGrid.body.appendChild( oClone.body );
886
+
887
+ this._fnEqualiseHeights( 'tbody', that.dom.body, oClone.body );
888
+
889
+ /*
890
+ * Footer
891
+ */
892
+ if ( this.s.dt.nTFoot !== null )
893
+ {
894
+ if ( bAll )
895
+ {
896
+ if ( oClone.footer !== null )
897
+ {
898
+ oClone.footer.parentNode.removeChild( oClone.footer );
899
+ }
900
+ oClone.footer = $(this.dom.footer).clone(true)[0];
901
+ oClone.footer.className += " DTFC_Cloned";
902
+ oClone.footer.style.width = "100%";
903
+ oGrid.foot.appendChild( oClone.footer );
904
+
905
+ /* Copy the footer just like we do for the header */
906
+ var aoCloneLayout = this._fnCopyLayout( this.s.dt.aoFooter, aiColumns );
907
+ var jqCloneTfoot = $('>tfoot', oClone.footer);
908
+ jqCloneTfoot.empty();
909
+
910
+ for ( i=0, iLen=aoCloneLayout.length ; i<iLen ; i++ )
911
+ {
912
+ jqCloneTfoot[0].appendChild( aoCloneLayout[i].nTr );
913
+ }
914
+ this.s.dt.oApi._fnDrawHead( this.s.dt, aoCloneLayout, true );
915
+ }
916
+ else
917
+ {
918
+ var aoCloneLayout = this._fnCopyLayout( this.s.dt.aoFooter, aiColumns );
919
+ var aoCurrFooter=[];
920
+
921
+ this.s.dt.oApi._fnDetectHeader( aoCurrFooter, $('>tfoot', oClone.footer)[0] );
922
+
923
+ for ( i=0, iLen=aoCloneLayout.length ; i<iLen ; i++ )
924
+ {
925
+ for ( j=0, jLen=aoCloneLayout[i].length ; j<jLen ; j++ )
926
+ {
927
+ aoCurrFooter[i][j].cell.className = aoCloneLayout[i][j].cell.className;
928
+ }
929
+ }
930
+ }
931
+ this._fnEqualiseHeights( 'tfoot', this.dom.footer, oClone.footer );
932
+ }
933
+
934
+ /* Equalise the column widths between the header footer and body - body get's priority */
935
+ var anUnique = this.s.dt.oApi._fnGetUniqueThs( this.s.dt, $('>thead', oClone.header)[0] );
936
+ $(anUnique).each( function (i) {
937
+ iColumn = aiColumns[i];
938
+ this.style.width = that.s.aiWidths[iColumn]+"px";
939
+ } );
940
+
941
+ if ( that.s.dt.nTFoot !== null )
942
+ {
943
+ anUnique = this.s.dt.oApi._fnGetUniqueThs( this.s.dt, $('>tfoot', oClone.footer)[0] );
944
+ $(anUnique).each( function (i) {
945
+ iColumn = aiColumns[i];
946
+ this.style.width = that.s.aiWidths[iColumn]+"px";
947
+ } );
948
+ }
949
+ },
950
+
951
+
952
+ /**
953
+ * From a given table node (THEAD etc), get a list of TR direct child elements
954
+ * @param {Node} nIn Table element to search for TR elements (THEAD, TBODY or TFOOT element)
955
+ * @returns {Array} List of TR elements found
956
+ * @private
957
+ */
958
+ "_fnGetTrNodes": function ( nIn )
959
+ {
960
+ var aOut = [];
961
+ for ( var i=0, iLen=nIn.childNodes.length ; i<iLen ; i++ )
962
+ {
963
+ if ( nIn.childNodes[i].nodeName.toUpperCase() == "TR" )
964
+ {
965
+ aOut.push( nIn.childNodes[i] );
966
+ }
967
+ }
968
+ return aOut;
969
+ },
970
+
971
+
972
+ /**
973
+ * Equalise the heights of the rows in a given table node in a cross browser way
974
+ * @returns {void}
975
+ * @param {String} nodeName Node type - thead, tbody or tfoot
976
+ * @param {Node} original Original node to take the heights from
977
+ * @param {Node} clone Copy the heights to
978
+ * @private
979
+ */
980
+ "_fnEqualiseHeights": function ( nodeName, original, clone )
981
+ {
982
+ if ( this.s.sHeightMatch == 'none' && nodeName !== 'thead' && nodeName !== 'tfoot' )
983
+ {
984
+ return;
985
+ }
986
+
987
+ var that = this,
988
+ i, iLen, iHeight, iHeight2, iHeightOriginal, iHeightClone,
989
+ rootOriginal = original.getElementsByTagName(nodeName)[0],
990
+ rootClone = clone.getElementsByTagName(nodeName)[0],
991
+ jqBoxHack = $('>'+nodeName+'>tr:eq(0)', original).children(':first'),
992
+ iBoxHack = jqBoxHack.outerHeight() - jqBoxHack.height(),
993
+ anOriginal = this._fnGetTrNodes( rootOriginal ),
994
+ anClone = this._fnGetTrNodes( rootClone );
995
+
996
+ for ( i=0, iLen=anClone.length ; i<iLen ; i++ )
997
+ {
998
+ if ( this.s.sHeightMatch == 'semiauto' && typeof anOriginal[i]._DTTC_iHeight != 'undefined' &&
999
+ anOriginal[i]._DTTC_iHeight !== null )
1000
+ {
1001
+ /* Oddly enough, IE / Chrome seem not to copy the style height - Mozilla and Opera keep it */
1002
+ if ( $.browser.msie )
1003
+ {
1004
+ $(anClone[i]).children().height( anOriginal[i]._DTTC_iHeight-iBoxHack );
1005
+ }
1006
+ continue;
1007
+ }
1008
+
1009
+ iHeightOriginal = anOriginal[i].offsetHeight;
1010
+ iHeightClone = anClone[i].offsetHeight;
1011
+ iHeight = iHeightClone > iHeightOriginal ? iHeightClone : iHeightOriginal;
1012
+
1013
+ if ( this.s.sHeightMatch == 'semiauto' )
1014
+ {
1015
+ anOriginal[i]._DTTC_iHeight = iHeight;
1016
+ }
1017
+
1018
+ /* Can we use some kind of object detection here?! This is very nasty - damn browsers */
1019
+ if ( $.browser.msie && $.browser.version < 8 )
1020
+ {
1021
+ $(anClone[i]).children().height( iHeight-iBoxHack );
1022
+ $(anOriginal[i]).children().height( iHeight-iBoxHack );
1023
+ }
1024
+ else
1025
+ {
1026
+ anClone[i].style.height = iHeight+"px";
1027
+ anOriginal[i].style.height = iHeight+"px";
1028
+ }
1029
+ }
1030
+ }
1031
+ };
1032
+
1033
+
1034
+
1035
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1036
+ * Statics
1037
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1038
+
1039
+
1040
+ /**
1041
+ * FixedColumns default settings for initialisation
1042
+ * @namespace
1043
+ * @static
1044
+ */
1045
+ FixedColumns.defaults = {
1046
+ /**
1047
+ * Number of left hand columns to fix in position
1048
+ * @type int
1049
+ * @default 1
1050
+ * @static
1051
+ * @example
1052
+ * var oTable = $('#example').dataTable( {
1053
+ * "sScrollX": "100%"
1054
+ * } );
1055
+ * new FixedColumns( oTable, {
1056
+ * "iLeftColumns": 2
1057
+ * } );
1058
+ */
1059
+ "iLeftColumns": 1,
1060
+
1061
+ /**
1062
+ * Number of right hand columns to fix in position
1063
+ * @type int
1064
+ * @default 0
1065
+ * @static
1066
+ * @example
1067
+ * var oTable = $('#example').dataTable( {
1068
+ * "sScrollX": "100%"
1069
+ * } );
1070
+ * new FixedColumns( oTable, {
1071
+ * "iRightColumns": 1
1072
+ * } );
1073
+ */
1074
+ "iRightColumns": 0,
1075
+
1076
+ /**
1077
+ * Draw callback function which is called when FixedColumns has redrawn the fixed assets
1078
+ * @type function(object, object):void
1079
+ * @default null
1080
+ * @static
1081
+ * @example
1082
+ * var oTable = $('#example').dataTable( {
1083
+ * "sScrollX": "100%"
1084
+ * } );
1085
+ * new FixedColumns( oTable, {
1086
+ * "fnDrawCallback": function () {
1087
+ * alert( "FixedColumns redraw" );
1088
+ * }
1089
+ * } );
1090
+ */
1091
+ "fnDrawCallback": null,
1092
+
1093
+ /**
1094
+ * Type of left column size calculation. Can take the values of "fixed", whereby the iLeftWidth
1095
+ * value will be treated as a pixel value, or "relative" for which case iLeftWidth will be
1096
+ * treated as a percentage value.
1097
+ * @type string
1098
+ * @default fixed
1099
+ * @static
1100
+ * @example
1101
+ * var oTable = $('#example').dataTable( {
1102
+ * "sScrollX": "100%"
1103
+ * } );
1104
+ * new FixedColumns( oTable, {
1105
+ * "sLeftWidth": "relative",
1106
+ * "iLeftWidth": 10 // percentage
1107
+ * } );
1108
+ */
1109
+ "sLeftWidth": "fixed",
1110
+
1111
+ /**
1112
+ * Width to set for the width of the left fixed column(s) - note that the behaviour of this
1113
+ * property is directly effected by the sLeftWidth property. If not defined then this property
1114
+ * is calculated automatically from what has been assigned by DataTables.
1115
+ * @type int
1116
+ * @default null
1117
+ * @static
1118
+ * @example
1119
+ * var oTable = $('#example').dataTable( {
1120
+ * "sScrollX": "100%"
1121
+ * } );
1122
+ * new FixedColumns( oTable, {
1123
+ * "iLeftWidth": 100 // pixels
1124
+ * } );
1125
+ */
1126
+ "iLeftWidth": null,
1127
+
1128
+ /**
1129
+ * Type of right column size calculation. Can take the values of "fixed", whereby the
1130
+ * iRightWidth value will be treated as a pixel value, or "relative" for which case
1131
+ * iRightWidth will be treated as a percentage value.
1132
+ * @type string
1133
+ * @default fixed
1134
+ * @static
1135
+ * @example
1136
+ * var oTable = $('#example').dataTable( {
1137
+ * "sScrollX": "100%"
1138
+ * } );
1139
+ * new FixedColumns( oTable, {
1140
+ * "sRightWidth": "relative",
1141
+ * "iRightWidth": 10 // percentage
1142
+ * } );
1143
+ */
1144
+ "sRightWidth": "fixed",
1145
+
1146
+ /**
1147
+ * Width to set for the width of the right fixed column(s) - note that the behaviour of this
1148
+ * property is directly effected by the sRightWidth property. If not defined then this property
1149
+ * is calculated automatically from what has been assigned by DataTables.
1150
+ * @type int
1151
+ * @default null
1152
+ * @static
1153
+ * @example
1154
+ * var oTable = $('#example').dataTable( {
1155
+ * "sScrollX": "100%"
1156
+ * } );
1157
+ * new FixedColumns( oTable, {
1158
+ * "iRightWidth": 200 // pixels
1159
+ * } );
1160
+ */
1161
+ "iRightWidth": null,
1162
+
1163
+ /**
1164
+ * Height matching algorthim to use. This can be "none" which will result in no height
1165
+ * matching being applied by FixedColumns (height matching could be forced by CSS in this
1166
+ * case), "semiauto" whereby the height calculation will be performed once, and the result
1167
+ * cached to be used again (fnRecalculateHeight can be used to force recalculation), or
1168
+ * "auto" when height matching is performed on every draw (slowest but must accurate)
1169
+ * @type string
1170
+ * @default semiauto
1171
+ * @static
1172
+ * @example
1173
+ * var oTable = $('#example').dataTable( {
1174
+ * "sScrollX": "100%"
1175
+ * } );
1176
+ * new FixedColumns( oTable, {
1177
+ * "sHeightMatch": "auto"
1178
+ * } );
1179
+ */
1180
+ "sHeightMatch": "semiauto"
1181
+ };
1182
+
1183
+
1184
+
1185
+
1186
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1187
+ * Constants
1188
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1189
+
1190
+
1191
+ /**
1192
+ * Name of this class
1193
+ * @constant CLASS
1194
+ * @type String
1195
+ * @default FixedColumns
1196
+ */
1197
+ FixedColumns.prototype.CLASS = "FixedColumns";
1198
+
1199
+
1200
+ /**
1201
+ * FixedColumns version
1202
+ * @constant FixedColumns.VERSION
1203
+ * @type String
1204
+ * @default See code
1205
+ * @static
1206
+ */
1207
+ FixedColumns.VERSION = "2.0.3";
1208
+
1209
+
1210
+
1211
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1212
+ * Fired events (for documentation)
1213
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1214
+
1215
+
1216
+ /**
1217
+ * Event fired whenever FixedColumns redraws the fixed columns (i.e. clones the table elements from the main DataTable). This will occur whenever the DataTable that the FixedColumns instance is attached does its own draw.
1218
+ * @name FixedColumns#draw
1219
+ * @event
1220
+ * @param {event} e jQuery event object
1221
+ * @param {object} o Event parameters from FixedColumns
1222
+ * @param {object} o.leftClone Instance's object dom.clone.left for easy reference. This object contains references to the left fixed clumn column's nodes
1223
+ * @param {object} o.rightClone Instance's object dom.clone.right for easy reference. This object contains references to the right fixed clumn column's nodes
1224
+ */
1225
+
1226
+ })(jQuery, window, document);