]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/static/AdminLTE-2.3.7/plugins/datatables/extensions/FixedHeader/js/dataTables.fixedHeader.js
2 * ©2010-2014 SpryMedia Ltd - datatables.net/license
7 * @description Fix a table's header or footer, so it is always visible while
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.
15 * This source file is free software, available under the following license:
16 * MIT license - http://datatables.net/license/mit
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.
22 * For details please refer to: http://www.datatables.net
25 /* Global scope for FixedColumns for backwards compatibility - will be removed
26 * in future. Not documented in 1.1.x.
29 /* Global scope for FixedColumns */
32 (function(window
, document
, undefined) {
35 var factory = function( $, DataTable
) {
39 * Function: FixedHeader
40 * Purpose: Provide 'fixed' header, footer and columns for a DataTable
41 * Returns: object:FixedHeader - must be called with 'new'
42 * Inputs: mixed:mTable - target table
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
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
58 FixedHeader = function ( mTable
, oInit
) {
59 /* Sanity check - you just know it will happen */
60 if ( ! this instanceof FixedHeader
)
62 alert( "FixedHeader warning: FixedHeader must be initialised with the 'new' keyword." );
91 "iTableRight": 0, /* note this is left+width, not actually "right" */
93 "iTableBottom": 0 /* note this is top+height, not actually "bottom" */
100 "bInitComplete": false
104 * Function: fnGetSettings
105 * Purpose: Get the settings for this object
106 * Returns: object: - settings object
109 this.fnGetSettings = function () {
115 * Purpose: Update the positioning and copies of the fixed elements
119 this.fnUpdate = function () {
120 this._fnUpdateClones();
121 this._fnUpdatePositions();
125 * Function: fnPosition
126 * Purpose: Update the positioning of the fixed elements
130 this.fnPosition = function () {
131 this._fnUpdatePositions();
135 var dt
= $.fn
.dataTable
.Api
?
136 new $.fn
.dataTable
.Api( mTable
).settings()[0] :
139 dt
._oPluginFixedHeader
= this;
142 this.fnInit( dt
, oInit
);
148 * Variable: FixedHeader
149 * Purpose: Prototype for FixedHeader
152 FixedHeader
.prototype = {
153 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
159 * Purpose: The "constructor"
161 * Inputs: {as FixedHeader function}
163 fnInit: function ( oDtSettings
, oInit
)
165 var s
= this.fnGetSettings();
168 /* Record the user definable settings */
169 this.fnInitSettings( s
, oInit
);
171 if ( oDtSettings
.oScroll
.sX
!== "" || oDtSettings
.oScroll
.sY
!== "" )
173 alert( "FixedHeader 2 is not supported with DataTables' scrolling mode at this time" );
177 s
.nTable
= oDtSettings
.nTable
;
178 oDtSettings
.aoDrawCallback
.unshift( {
180 FixedHeader
.fnMeasure();
181 that
._fnUpdateClones
.call(that
);
182 that
._fnUpdatePositions
.call(that
);
184 "sName": "FixedHeader"
187 s
.bFooter
= ($('>tfoot', s
.nTable
).length
> 0) ? true : false;
189 /* Add the 'sides' that are fixed */
192 s
.aoCache
.push( that
._fnCloneTable( "fixedHeader", "FixedHeader_Header", that
._fnCloneThead
) );
194 if ( s
.oSides
.bottom
)
196 s
.aoCache
.push( that
._fnCloneTable( "fixedFooter", "FixedHeader_Footer", that
._fnCloneTfoot
) );
200 s
.aoCache
.push( that
._fnCloneTable( "fixedLeft", "FixedHeader_Left", that
._fnCloneTLeft
, s
.oSides
.left
) );
202 if ( s
.oSides
.right
)
204 s
.aoCache
.push( that
._fnCloneTable( "fixedRight", "FixedHeader_Right", that
._fnCloneTRight
, s
.oSides
.right
) );
207 /* Event listeners for window movement */
208 FixedHeader
.afnScroll
.push( function () {
209 that
._fnUpdatePositions
.call(that
);
212 $(window
).resize( function () {
213 FixedHeader
.fnMeasure();
214 that
._fnUpdateClones
.call(that
);
215 that
._fnUpdatePositions
.call(that
);
219 .on('column-reorder.dt', function () {
220 FixedHeader
.fnMeasure();
221 that
._fnUpdateClones( true );
222 that
._fnUpdatePositions();
224 .on('column-visibility.dt', function () {
225 FixedHeader
.fnMeasure();
226 that
._fnUpdateClones( true );
227 that
._fnUpdatePositions();
230 /* Get things right to start with */
231 FixedHeader
.fnMeasure();
232 that
._fnUpdateClones();
233 that
._fnUpdatePositions();
235 s
.bInitComplete
= true;
239 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
244 * Function: fnInitSettings
245 * Purpose: Take the user's settings and copy them to our local store
247 * Inputs: object:s - the local settings object
248 * object:oInit - the user's settings object
250 fnInitSettings: function ( s
, oInit
)
252 if ( oInit
!== undefined )
254 if ( oInit
.top
!== undefined ) {
255 s
.oSides
.top
= oInit
.top
;
257 if ( oInit
.bottom
!== undefined ) {
258 s
.oSides
.bottom
= oInit
.bottom
;
260 if ( typeof oInit
.left
== 'boolean' ) {
261 s
.oSides
.left
= oInit
.left
? 1 : 0;
263 else if ( oInit
.left
!== undefined ) {
264 s
.oSides
.left
= oInit
.left
;
266 if ( typeof oInit
.right
== 'boolean' ) {
267 s
.oSides
.right
= oInit
.right
? 1 : 0;
269 else if ( oInit
.right
!== undefined ) {
270 s
.oSides
.right
= oInit
.right
;
273 if ( oInit
.zTop
!== undefined ) {
274 s
.oZIndexes
.top
= oInit
.zTop
;
276 if ( oInit
.zBottom
!== undefined ) {
277 s
.oZIndexes
.bottom
= oInit
.zBottom
;
279 if ( oInit
.zLeft
!== undefined ) {
280 s
.oZIndexes
.left
= oInit
.zLeft
;
282 if ( oInit
.zRight
!== undefined ) {
283 s
.oZIndexes
.right
= oInit
.zRight
;
286 if ( oInit
.offsetTop
!== undefined ) {
287 s
.oOffset
.top
= oInit
.offsetTop
;
289 if ( oInit
.alwaysCloneTop
!== undefined ) {
290 s
.oCloneOnDraw
.top
= oInit
.alwaysCloneTop
;
292 if ( oInit
.alwaysCloneBottom
!== undefined ) {
293 s
.oCloneOnDraw
.bottom
= oInit
.alwaysCloneBottom
;
295 if ( oInit
.alwaysCloneLeft
!== undefined ) {
296 s
.oCloneOnDraw
.left
= oInit
.alwaysCloneLeft
;
298 if ( oInit
.alwaysCloneRight
!== undefined ) {
299 s
.oCloneOnDraw
.right
= oInit
.alwaysCloneRight
;
305 * Function: _fnCloneTable
306 * Purpose: Clone the table node and do basic initialisation
310 _fnCloneTable: function ( sType
, sClass
, fnClone
, iCells
)
312 var s
= this.fnGetSettings();
315 /* We know that the table _MUST_ has a DIV wrapped around it, because this is simply how
316 * DataTables works. Therefore, we can set this to be relatively position (if it is not
317 * alreadu absolute, and use this as the base point for the cloned header
319 if ( $(s
.nTable
.parentNode
).css('position') != "absolute" )
321 s
.nTable
.parentNode
.style
.position
= "relative";
324 /* Just a shallow clone will do - we only want the table node */
325 nCTable
= s
.nTable
.cloneNode( false );
326 nCTable
.removeAttribute( 'id' );
328 var nDiv
= document
.createElement( 'div' );
329 nDiv
.style
.position
= "absolute";
330 nDiv
.style
.top
= "0px";
331 nDiv
.style
.left
= "0px";
332 nDiv
.className
+= " FixedHeader_Cloned "+sType
+" "+sClass
;
334 /* Set the zIndexes */
335 if ( sType
== "fixedHeader" )
337 nDiv
.style
.zIndex
= s
.oZIndexes
.top
;
339 if ( sType
== "fixedFooter" )
341 nDiv
.style
.zIndex
= s
.oZIndexes
.bottom
;
343 if ( sType
== "fixedLeft" )
345 nDiv
.style
.zIndex
= s
.oZIndexes
.left
;
347 else if ( sType
== "fixedRight" )
349 nDiv
.style
.zIndex
= s
.oZIndexes
.right
;
352 /* remove margins since we are going to position it absolutely */
353 nCTable
.style
.margin
= "0";
355 /* Insert the newly cloned table into the DOM, on top of the "real" header */
356 nDiv
.appendChild( nCTable
);
357 document
.body
.appendChild( nDiv
);
372 * Function: _fnMeasure
373 * Purpose: Get the current positioning of the table in the DOM
377 _fnMeasure: function ()
380 s
= this.fnGetSettings(),
382 jqTable
= $(s
.nTable
),
383 oOffset
= jqTable
.offset(),
384 iParentScrollTop
= this._fnSumScroll( s
.nTable
.parentNode
, 'scrollTop' ),
385 iParentScrollLeft
= this._fnSumScroll( s
.nTable
.parentNode
, 'scrollLeft' );
387 m
.iTableWidth
= jqTable
.outerWidth();
388 m
.iTableHeight
= jqTable
.outerHeight();
389 m
.iTableLeft
= oOffset
.left
+ s
.nTable
.parentNode
.scrollLeft
;
390 m
.iTableTop
= oOffset
.top
+ iParentScrollTop
;
391 m
.iTableRight
= m
.iTableLeft
+ m
.iTableWidth
;
392 m
.iTableRight
= FixedHeader
.oDoc
.iWidth
- m
.iTableLeft
- m
.iTableWidth
;
393 m
.iTableBottom
= FixedHeader
.oDoc
.iHeight
- m
.iTableTop
- m
.iTableHeight
;
397 * Function: _fnSumScroll
398 * Purpose: Sum node parameters all the way to the top
400 * Inputs: node:n - node to consider
401 * string:side - scrollTop or scrollLeft
403 _fnSumScroll: function ( n
, side
)
406 while ( n
= n
.parentNode
)
408 if ( n
.nodeName
== 'HTML' || n
.nodeName
== 'BODY' )
418 * Function: _fnUpdatePositions
419 * Purpose: Loop over the fixed elements for this table and update their positions
423 _fnUpdatePositions: function ()
425 var s
= this.fnGetSettings();
428 for ( var i
=0, iLen
=s
.aoCache
.length
; i
<iLen
; i
++ )
430 if ( s
.aoCache
[i
].sType
== "fixedHeader" )
432 this._fnScrollFixedHeader( s
.aoCache
[i
] );
434 else if ( s
.aoCache
[i
].sType
== "fixedFooter" )
436 this._fnScrollFixedFooter( s
.aoCache
[i
] );
438 else if ( s
.aoCache
[i
].sType
== "fixedLeft" )
440 this._fnScrollHorizontalLeft( s
.aoCache
[i
] );
444 this._fnScrollHorizontalRight( s
.aoCache
[i
] );
450 * Function: _fnUpdateClones
451 * Purpose: Loop over the fixed elements for this table and call their cloning functions
455 _fnUpdateClones: function ( full
)
457 var s
= this.fnGetSettings();
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;
466 for ( var i
=0, iLen
=s
.aoCache
.length
; i
<iLen
; i
++ )
468 s
.aoCache
[i
].fnClone
.call( this, s
.aoCache
[i
] );
472 s
.bInitComplete
= true;
477 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
478 * Scrolling functions
482 * Function: _fnScrollHorizontalLeft
483 * Purpose: Update the positioning of the scrolling elements
485 * Inputs: object:oCache - the cached values for this fixed element
487 _fnScrollHorizontalRight: function ( oCache
)
490 s
= this.fnGetSettings(),
492 oWin
= FixedHeader
.oWin
,
493 oDoc
= FixedHeader
.oDoc
,
494 nTable
= oCache
.nWrapper
,
495 iFixedWidth
= $(nTable
).outerWidth();
497 if ( oWin
.iScrollRight
< oMes
.iTableRight
)
499 /* Fully right aligned */
500 this._fnUpdateCache( oCache
, 'sPosition', 'absolute', 'position', nTable
.style
);
501 this._fnUpdateCache( oCache
, 'sTop', oMes
.iTableTop
+"px", 'top', nTable
.style
);
502 this._fnUpdateCache( oCache
, 'sLeft', (oMes
.iTableLeft
+oMes
.iTableWidth
-iFixedWidth
)+"px", 'left', nTable
.style
);
504 else if ( oMes
.iTableLeft
< oDoc
.iWidth
-oWin
.iScrollRight
-iFixedWidth
)
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
);
513 /* Fully left aligned */
514 this._fnUpdateCache( oCache
, 'sPosition', 'absolute', 'position', nTable
.style
);
515 this._fnUpdateCache( oCache
, 'sTop', oMes
.iTableTop
+"px", 'top', nTable
.style
);
516 this._fnUpdateCache( oCache
, 'sLeft', oMes
.iTableLeft
+"px", 'left', nTable
.style
);
521 * Function: _fnScrollHorizontalLeft
522 * Purpose: Update the positioning of the scrolling elements
524 * Inputs: object:oCache - the cached values for this fixed element
526 _fnScrollHorizontalLeft: function ( oCache
)
529 s
= this.fnGetSettings(),
531 oWin
= FixedHeader
.oWin
,
532 oDoc
= FixedHeader
.oDoc
,
533 nTable
= oCache
.nWrapper
,
534 iCellWidth
= $(nTable
).outerWidth();
536 if ( oWin
.iScrollLeft
< oMes
.iTableLeft
)
538 /* Fully left align */
539 this._fnUpdateCache( oCache
, 'sPosition', 'absolute', 'position', nTable
.style
);
540 this._fnUpdateCache( oCache
, 'sTop', oMes
.iTableTop
+"px", 'top', nTable
.style
);
541 this._fnUpdateCache( oCache
, 'sLeft', oMes
.iTableLeft
+"px", 'left', nTable
.style
);
543 else if ( oWin
.iScrollLeft
< oMes
.iTableLeft
+oMes
.iTableWidth
-iCellWidth
)
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
);
551 /* Fully right align */
552 this._fnUpdateCache( oCache
, 'sPosition', 'absolute', 'position', nTable
.style
);
553 this._fnUpdateCache( oCache
, 'sTop', oMes
.iTableTop
+"px", 'top', nTable
.style
);
554 this._fnUpdateCache( oCache
, 'sLeft', (oMes
.iTableLeft
+oMes
.iTableWidth
-iCellWidth
)+"px", 'left', nTable
.style
);
559 * Function: _fnScrollFixedFooter
560 * Purpose: Update the positioning of the scrolling elements
562 * Inputs: object:oCache - the cached values for this fixed element
564 _fnScrollFixedFooter: function ( oCache
)
567 s
= this.fnGetSettings(),
569 oWin
= FixedHeader
.oWin
,
570 oDoc
= FixedHeader
.oDoc
,
571 nTable
= oCache
.nWrapper
,
572 iTheadHeight
= $("thead", s
.nTable
).outerHeight(),
573 iCellHeight
= $(nTable
).outerHeight();
575 if ( oWin
.iScrollBottom
< oMes
.iTableBottom
)
578 this._fnUpdateCache( oCache
, 'sPosition', 'absolute', 'position', nTable
.style
);
579 this._fnUpdateCache( oCache
, 'sTop', (oMes
.iTableTop
+oMes
.iTableHeight
-iCellHeight
)+"px", 'top', nTable
.style
);
580 this._fnUpdateCache( oCache
, 'sLeft', oMes
.iTableLeft
+"px", 'left', nTable
.style
);
582 else if ( oWin
.iScrollBottom
< oMes
.iTableBottom
+oMes
.iTableHeight
-iCellHeight
-iTheadHeight
)
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
);
591 this._fnUpdateCache( oCache
, 'sPosition', 'absolute', 'position', nTable
.style
);
592 this._fnUpdateCache( oCache
, 'sTop', (oMes
.iTableTop
+iCellHeight
)+"px", 'top', nTable
.style
);
593 this._fnUpdateCache( oCache
, 'sLeft', oMes
.iTableLeft
+"px", 'left', nTable
.style
);
598 * Function: _fnScrollFixedHeader
599 * Purpose: Update the positioning of the scrolling elements
601 * Inputs: object:oCache - the cached values for this fixed element
603 _fnScrollFixedHeader: function ( oCache
)
606 s
= this.fnGetSettings(),
608 oWin
= FixedHeader
.oWin
,
609 oDoc
= FixedHeader
.oDoc
,
610 nTable
= oCache
.nWrapper
,
612 anTbodies
= s
.nTable
.getElementsByTagName('tbody');
614 for (var i
= 0; i
< anTbodies
.length
; ++i
) {
615 iTbodyHeight
+= anTbodies
[i
].offsetHeight
;
618 if ( oMes
.iTableTop
> oWin
.iScrollTop
+ s
.oOffset
.top
)
620 /* Above the table */
621 this._fnUpdateCache( oCache
, 'sPosition', "absolute", 'position', nTable
.style
);
622 this._fnUpdateCache( oCache
, 'sTop', oMes
.iTableTop
+"px", 'top', nTable
.style
);
623 this._fnUpdateCache( oCache
, 'sLeft', oMes
.iTableLeft
+"px", 'left', nTable
.style
);
625 else if ( oWin
.iScrollTop
+ s
.oOffset
.top
> oMes
.iTableTop
+iTbodyHeight
)
627 /* At the bottom of the table */
628 this._fnUpdateCache( oCache
, 'sPosition', "absolute", 'position', nTable
.style
);
629 this._fnUpdateCache( oCache
, 'sTop', (oMes
.iTableTop
+iTbodyHeight
)+"px", 'top', nTable
.style
);
630 this._fnUpdateCache( oCache
, 'sLeft', oMes
.iTableLeft
+"px", 'left', nTable
.style
);
634 /* In the middle of the table */
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
);
642 * Function: _fnUpdateCache
643 * Purpose: Check the cache and update cache and value if needed
645 * Inputs: object:oCache - local cache object
646 * string:sCache - cache property
647 * string:sSet - value to set
648 * string:sProperty - object property to set
649 * object:oObj - object to update
651 _fnUpdateCache: function ( oCache
, sCache
, sSet
, sProperty
, oObj
)
653 if ( oCache
[sCache
] != sSet
)
655 oObj
[sProperty
] = sSet
;
656 oCache
[sCache
] = sSet
;
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
666 * @param {element} source Node to copy classes from
667 * @param {element} dest Node to copy classes too
669 _fnClassUpdate: function ( source
, dest
)
673 if ( source
.nodeName
.toUpperCase() === "TR" || source
.nodeName
.toUpperCase() === "TH" ||
674 source
.nodeName
.toUpperCase() === "TD" || source
.nodeName
.toUpperCase() === "SPAN" )
676 dest
.className
= source
.className
;
679 $(source
).children().each( function (i
) {
680 that
._fnClassUpdate( $(source
).children()[i
], $(dest
).children()[i
] );
685 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
690 * Function: _fnCloneThead
691 * Purpose: Clone the thead element
693 * Inputs: object:oCache - the cached values for this fixed element
695 _fnCloneThead: function ( oCache
)
697 var s
= this.fnGetSettings();
698 var nTable
= oCache
.nNode
;
700 if ( s
.bInitComplete
&& !s
.oCloneOnDraw
.top
)
702 this._fnClassUpdate( $('thead', s
.nTable
)[0], $('thead', nTable
)[0] );
706 /* Set the wrapper width to match that of the cloned table */
707 var iDtWidth
= $(s
.nTable
).outerWidth();
708 oCache
.nWrapper
.style
.width
= iDtWidth
+"px";
709 nTable
.style
.width
= iDtWidth
+"px";
711 /* Remove any children the cloned table has */
712 while ( nTable
.childNodes
.length
> 0 )
714 $('thead th', nTable
).unbind( 'click' );
715 nTable
.removeChild( nTable
.childNodes
[0] );
718 /* Clone the DataTables header */
719 var nThead
= $('thead', s
.nTable
).clone(true)[0];
720 nTable
.appendChild( nThead
);
722 /* Copy the widths across - apparently a clone isn't good enough for this */
726 $("thead>tr th", s
.nTable
).each( function (i
) {
727 a
.push( $(this).width() );
730 $("thead>tr td", s
.nTable
).each( function (i
) {
731 b
.push( $(this).width() );
734 $("thead>tr th", s
.nTable
).each( function (i
) {
735 $("thead>tr th:eq("+i
+")", nTable
).width( a
[i
] );
736 $(this).width( a
[i
] );
739 $("thead>tr td", s
.nTable
).each( function (i
) {
740 $("thead>tr td:eq("+i
+")", nTable
).width( b
[i
] );
741 $(this).width( b
[i
] );
744 // Stop DataTables 1.9 from putting a focus ring on the headers when
746 $('th.sorting, th.sorting_desc, th.sorting_asc', nTable
).bind( 'click', function () {
752 * Function: _fnCloneTfoot
753 * Purpose: Clone the tfoot element
755 * Inputs: object:oCache - the cached values for this fixed element
757 _fnCloneTfoot: function ( oCache
)
759 var s
= this.fnGetSettings();
760 var nTable
= oCache
.nNode
;
762 /* Set the wrapper width to match that of the cloned table */
763 oCache
.nWrapper
.style
.width
= $(s
.nTable
).outerWidth()+"px";
765 /* Remove any children the cloned table has */
766 while ( nTable
.childNodes
.length
> 0 )
768 nTable
.removeChild( nTable
.childNodes
[0] );
771 /* Clone the DataTables footer */
772 var nTfoot
= $('tfoot', s
.nTable
).clone(true)[0];
773 nTable
.appendChild( nTfoot
);
775 /* Copy the widths across - apparently a clone isn't good enough for this */
776 $("tfoot:eq(0)>tr th", s
.nTable
).each( function (i
) {
777 $("tfoot:eq(0)>tr th:eq("+i
+")", nTable
).width( $(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() );
786 * Function: _fnCloneTLeft
787 * Purpose: Clone the left column(s)
789 * Inputs: object:oCache - the cached values for this fixed element
791 _fnCloneTLeft: function ( oCache
)
793 var s
= this.fnGetSettings();
794 var nTable
= oCache
.nNode
;
795 var nBody
= $('tbody', s
.nTable
)[0];
797 /* Remove any children the cloned table has */
798 while ( nTable
.childNodes
.length
> 0 )
800 nTable
.removeChild( nTable
.childNodes
[0] );
803 /* Is this the most efficient way to do this - it looks horrible... */
804 nTable
.appendChild( $("thead", s
.nTable
).clone(true)[0] );
805 nTable
.appendChild( $("tbody", s
.nTable
).clone(true)[0] );
808 nTable
.appendChild( $("tfoot", s
.nTable
).clone(true)[0] );
811 /* Remove unneeded cells */
812 var sSelector
= 'gt(' + (oCache
.iCells
- 1) + ')';
813 $('thead tr', nTable
).each( function (k
) {
814 $('th:' + sSelector
, this).remove();
817 $('tfoot tr', nTable
).each( function (k
) {
818 $('th:' + sSelector
, this).remove();
821 $('tbody tr', nTable
).each( function (k
) {
822 $('td:' + sSelector
, this).remove();
825 this.fnEqualiseHeights( 'thead', nBody
.parentNode
, nTable
);
826 this.fnEqualiseHeights( 'tbody', nBody
.parentNode
, nTable
);
827 this.fnEqualiseHeights( 'tfoot', nBody
.parentNode
, nTable
);
830 for (var i
= 0; i
< oCache
.iCells
; i
++) {
831 iWidth
+= $('thead tr th:eq(' + i
+ ')', s
.nTable
).outerWidth();
833 nTable
.style
.width
= iWidth
+"px";
834 oCache
.nWrapper
.style
.width
= iWidth
+"px";
838 * Function: _fnCloneTRight
839 * Purpose: Clone the right most column(s)
841 * Inputs: object:oCache - the cached values for this fixed element
843 _fnCloneTRight: function ( oCache
)
845 var s
= this.fnGetSettings();
846 var nBody
= $('tbody', s
.nTable
)[0];
847 var nTable
= oCache
.nNode
;
848 var iCols
= $('tbody tr:eq(0) td', s
.nTable
).length
;
850 /* Remove any children the cloned table has */
851 while ( nTable
.childNodes
.length
> 0 )
853 nTable
.removeChild( nTable
.childNodes
[0] );
856 /* Is this the most efficient way to do this - it looks horrible... */
857 nTable
.appendChild( $("thead", s
.nTable
).clone(true)[0] );
858 nTable
.appendChild( $("tbody", s
.nTable
).clone(true)[0] );
861 nTable
.appendChild( $("tfoot", s
.nTable
).clone(true)[0] );
863 $('thead tr th:lt('+(iCols
-oCache
.iCells
)+')', nTable
).remove();
864 $('tfoot tr th:lt('+(iCols
-oCache
.iCells
)+')', nTable
).remove();
866 /* Remove unneeded cells */
867 $('tbody tr', nTable
).each( function (k
) {
868 $('td:lt('+(iCols
-oCache
.iCells
)+')', this).remove();
871 this.fnEqualiseHeights( 'thead', nBody
.parentNode
, nTable
);
872 this.fnEqualiseHeights( 'tbody', nBody
.parentNode
, nTable
);
873 this.fnEqualiseHeights( 'tfoot', nBody
.parentNode
, nTable
);
876 for (var i
= 0; i
< oCache
.iCells
; i
++) {
877 iWidth
+= $('thead tr th:eq('+(iCols
-1-i
)+')', s
.nTable
).outerWidth();
879 nTable
.style
.width
= iWidth
+"px";
880 oCache
.nWrapper
.style
.width
= iWidth
+"px";
885 * Equalise the heights of the rows in a given table node in a cross browser way. Note that this
886 * is more or less lifted as is from FixedColumns
887 * @method fnEqualiseHeights
889 * @param {string} parent Node type - thead, tbody or tfoot
890 * @param {element} original Original node to take the heights from
891 * @param {element} clone Copy the heights to
894 "fnEqualiseHeights": function ( parent
, original
, clone
)
897 var originals
= $(parent
+' tr', original
);
900 $(parent
+' tr', clone
).each( function (k
) {
901 height
= originals
.eq( k
).css('height');
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;
911 $(this).css( 'height', height
);
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
);
922 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
923 * Static properties and methods
924 * We use these for speed! This information is common to all instances of FixedHeader, so no
925 * point if having them calculated and stored for each different instance.
930 * Purpose: Store information about the window positioning
944 * Purpose: Store information about the document size
953 * Variable: afnScroll
954 * Purpose: Array of functions that are to be used for the scrolling components
957 FixedHeader
.afnScroll
= [];
960 * Function: fnMeasure
961 * Purpose: Update the measurements for the window and document
965 FixedHeader
.fnMeasure = function ()
970 oWin
= FixedHeader
.oWin
,
971 oDoc
= FixedHeader
.oDoc
;
973 oDoc
.iHeight
= jqDoc
.height();
974 oDoc
.iWidth
= jqDoc
.width();
976 oWin
.iHeight
= jqWin
.height();
977 oWin
.iWidth
= jqWin
.width();
978 oWin
.iScrollTop
= jqWin
.scrollTop();
979 oWin
.iScrollLeft
= jqWin
.scrollLeft();
980 oWin
.iScrollRight
= oDoc
.iWidth
- oWin
.iScrollLeft
- oWin
.iWidth
;
981 oWin
.iScrollBottom
= oDoc
.iHeight
- oWin
.iScrollTop
- oWin
.iHeight
;
985 FixedHeader
.version
= "2.1.2";
988 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
993 * Just one 'scroll' event handler in FixedHeader, which calls the required components. This is
994 * done as an optimisation, to reduce calculation and proagation time
996 $(window
).scroll( function () {
997 FixedHeader
.fnMeasure();
999 for ( var i
=0, iLen
=FixedHeader
.afnScroll
.length
; i
<iLen
; i
++ ) {
1000 FixedHeader
.afnScroll
[i
]();
1005 $.fn
.dataTable
.FixedHeader
= FixedHeader
;
1006 $.fn
.DataTable
.FixedHeader
= FixedHeader
;
1013 // Define as an AMD module if possible
1014 if ( typeof define
=== 'function' && define
.amd
) {
1015 define( ['jquery', 'datatables'], factory
);
1017 else if ( typeof exports
=== 'object' ) {
1019 factory( require('jquery'), require('datatables') );
1021 else if ( jQuery
&& !jQuery
.fn
.dataTable
.FixedHeader
) {
1022 // Otherwise simply initialise as normal, stopping multiple evaluation
1023 factory( jQuery
, jQuery
.fn
.dataTable
);
1027 })(window
, document
);