Вход Регистрация
Файл: static/library/plugins/datatables/extensions/FixedColumns/js/dataTables.fixedColumns.js
Строк: 1588
<?php
/*! FixedColumns 3.0.4
 * ©2010-2014 SpryMedia Ltd - datatables.net/license
 */

/**
 * @summary     FixedColumns
 * @description Freeze columns in place on a scrolling DataTable
 * @version     3.0.4
 * @file        dataTables.fixedColumns.js
 * @author      SpryMedia Ltd (www.sprymedia.co.uk)
 * @contact     www.sprymedia.co.uk/contact
 * @copyright   Copyright 2010-2014 SpryMedia Ltd.
 *
 * This source file is free software, available under the following license:
 *   MIT license - http://datatables.net/license/mit
 *
 * This source file is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
 *
 * For details please refer to: http://www.datatables.net
 */


(function(windowdocumentundefined) {


var 
factory = function( $, DataTable ) {
"use strict";

/**
 * When making use of DataTables' x-axis scrolling feature, you may wish to
 * fix the left most column in place. This plug-in for DataTables provides
 * exactly this option (note for non-scrolling tables, please use the
 * FixedHeader plug-in, which can fix headers, footers and columns). Key
 * features include:
 *
 * * Freezes the left or right most columns to the side of the table
 * * Option to freeze two or more columns
 * * Full integration with DataTables' scrolling options
 * * Speed - FixedColumns is fast in its operation
 *
 *  @class
 *  @constructor
 *  @global
 *  @param {object} dt DataTables instance. With DataTables 1.10 this can also
 *    be a jQuery collection, a jQuery selector, DataTables API instance or
 *    settings object.
 *  @param {object} [init={}] Configuration object for FixedColumns. Options are
 *    defined by {@link FixedColumns.defaults}
 *
 *  @requires jQuery 1.7+
 *  @requires DataTables 1.8.0+
 *
 *  @example
 *      var table = $('#example').dataTable( {
 *        "scrollX": "100%"
 *      } );
 *      new $.fn.dataTable.fixedColumns( table );
 */
var FixedColumns = function ( dtinit ) {
    var 
that this;

    
/* Sanity check - you just know it will happen */
    
if ( ! ( this instanceof FixedColumns ) )
    {
        
alert"FixedColumns warning: FixedColumns must be initialised with the 'new' keyword." );
        return;
    }

    if ( 
typeof init == 'undefined' )
    {
        
init = {};
    }

    
// Use the DataTables Hungarian notation mapping method, if it exists to
    // provide forwards compatibility for camel case variables
    
var camelToHungarian = $.fn.dataTable.camelToHungarian;
    if ( 
camelToHungarian ) {
        
camelToHungarianFixedColumns.defaultsFixedColumns.defaultstrue );
        
camelToHungarianFixedColumns.defaultsinit );
    }

    
// v1.10 allows the settings object to be got form a number of sources
    
var dtSettings = $.fn.dataTable.Api ?
        new $.
fn.dataTable.Apidt ).settings()[0] :
        
dt.fnSettings();

    
/**
     * Settings object which contains customisable information for FixedColumns instance
     * @namespace
     * @extends FixedColumns.defaults
     * @private
     */
    
this.= {
        
/**
         * DataTables settings objects
         *  @type     object
         *  @default  Obtained from DataTables instance
         */
        
"dt"dtSettings,

        
/**
         * Number of columns in the DataTable - stored for quick access
         *  @type     int
         *  @default  Obtained from DataTables instance
         */
        
"iTableColumns"dtSettings.aoColumns.length,

        
/**
         * Original outer widths of the columns as rendered by DataTables - used to calculate
         * the FixedColumns grid bounding box
         *  @type     array.<int>
         *  @default  []
         */
        
"aiOuterWidths": [],

        
/**
         * Original inner widths of the columns as rendered by DataTables - used to apply widths
         * to the columns
         *  @type     array.<int>
         *  @default  []
         */
        
"aiInnerWidths": []
    };


    
/**
     * DOM elements used by the class instance
     * @namespace
     * @private
     *
     */
    
this.dom = {
        
/**
         * DataTables scrolling element
         *  @type     node
         *  @default  null
         */
        
"scroller"null,

        
/**
         * DataTables header table
         *  @type     node
         *  @default  null
         */
        
"header"null,

        
/**
         * DataTables body table
         *  @type     node
         *  @default  null
         */
        
"body"null,

        
/**
         * DataTables footer table
         *  @type     node
         *  @default  null
         */
        
"footer"null,

        
/**
         * Display grid elements
         * @namespace
         */
        
"grid": {
            
/**
             * Grid wrapper. This is the container element for the 3x3 grid
             *  @type     node
             *  @default  null
             */
            
"wrapper"null,

            
/**
             * DataTables scrolling element. This element is the DataTables
             * component in the display grid (making up the main table - i.e.
             * not the fixed columns).
             *  @type     node
             *  @default  null
             */
            
"dt"null,

            
/**
             * Left fixed column grid components
             * @namespace
             */
            
"left": {
                
"wrapper"null,
                
"head"null,
                
"body"null,
                
"foot"null
            
},

            
/**
             * Right fixed column grid components
             * @namespace
             */
            
"right": {
                
"wrapper"null,
                
"head"null,
                
"body"null,
                
"foot"null
            
}
        },

        
/**
         * Cloned table nodes
         * @namespace
         */
        
"clone": {
            
/**
             * Left column cloned table nodes
             * @namespace
             */
            
"left": {
                
/**
                 * Cloned header table
                 *  @type     node
                 *  @default  null
                 */
                
"header"null,

                
/**
                 * Cloned body table
                 *  @type     node
                 *  @default  null
                 */
                
"body"null,

                
/**
                 * Cloned footer table
                 *  @type     node
                 *  @default  null
                 */
                
"footer"null
            
},

            
/**
             * Right column cloned table nodes
             * @namespace
             */
            
"right": {
                
/**
                 * Cloned header table
                 *  @type     node
                 *  @default  null
                 */
                
"header"null,

                
/**
                 * Cloned body table
                 *  @type     node
                 *  @default  null
                 */
                
"body"null,

                
/**
                 * Cloned footer table
                 *  @type     node
                 *  @default  null
                 */
                
"footer"null
            
}
        }
    };

    
/* Attach the instance to the DataTables instance so it can be accessed easily */
    
dtSettings._oFixedColumns this;

    
/* Let's do it */
    
if ( ! dtSettings._bInitComplete )
    {
        
dtSettings.oApi._fnCallbackRegdtSettings'aoInitComplete', function () {
            
that._fnConstructinit );
        }, 
'FixedColumns' );
    }
    else
    {
        
this._fnConstructinit );
    }
};



FixedColumns.prototype /** @lends FixedColumns.prototype */{
    
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * Public methods
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    /**
     * Update the fixed columns - including headers and footers. Note that FixedColumns will
     * automatically update the display whenever the host DataTable redraws.
     *  @returns {void}
     *  @example
     *      var table = $('#example').dataTable( {
     *          "scrollX": "100%"
     *      } );
     *      var fc = new $.fn.dataTable.fixedColumns( table );
     *
     *      // at some later point when the table has been manipulated....
     *      fc.fnUpdate();
     */
    
"fnUpdate": function ()
    {
        
this._fnDrawtrue );
    },


    
/**
     * Recalculate the resizes of the 3x3 grid that FixedColumns uses for display of the table.
     * This is useful if you update the width of the table container. Note that FixedColumns will
     * perform this function automatically when the window.resize event is fired.
     *  @returns {void}
     *  @example
     *      var table = $('#example').dataTable( {
     *          "scrollX": "100%"
     *      } );
     *      var fc = new $.fn.dataTable.fixedColumns( table );
     *
     *      // Resize the table container and then have FixedColumns adjust its layout....
     *      $('#content').width( 1200 );
     *      fc.fnRedrawLayout();
     */
    
"fnRedrawLayout": function ()
    {
        
this._fnColCalc();
        
this._fnGridLayout();
        
this.fnUpdate();
    },


    
/**
     * Mark a row such that it's height should be recalculated when using 'semiauto' row
     * height matching. This function will have no effect when 'none' or 'auto' row height
     * matching is used.
     *  @param   {Node} nTr TR element that should have it's height recalculated
     *  @returns {void}
     *  @example
     *      var table = $('#example').dataTable( {
     *          "scrollX": "100%"
     *      } );
     *      var fc = new $.fn.dataTable.fixedColumns( table );
     *
     *      // manipulate the table - mark the row as needing an update then update the table
     *      // this allows the redraw performed by DataTables fnUpdate to recalculate the row
     *      // height
     *      fc.fnRecalculateHeight();
     *      table.fnUpdate( $('#example tbody tr:eq(0)')[0], ["insert date", 1, 2, 3 ... ]);
     */
    
"fnRecalculateHeight": function ( nTr )
    {
        
delete nTr._DTTC_iHeight;
        
nTr.style.height 'auto';
    },


    
/**
     * Set the height of a given row - provides cross browser compatibility
     *  @param   {Node} nTarget TR element that should have it's height recalculated
     *  @param   {int} iHeight Height in pixels to set
     *  @returns {void}
     *  @example
     *      var table = $('#example').dataTable( {
     *          "scrollX": "100%"
     *      } );
     *      var fc = new $.fn.dataTable.fixedColumns( table );
     *
     *      // You may want to do this after manipulating a row in the fixed column
     *      fc.fnSetRowHeight( $('#example tbody tr:eq(0)')[0], 50 );
     */
    
"fnSetRowHeight": function ( nTargetiHeight )
    {
        
nTarget.style.height iHeight+"px";
    },


    
/**
     * Get data index information about a row or cell in the table body.
     * This function is functionally identical to fnGetPosition in DataTables,
     * taking the same parameter (TH, TD or TR node) and returning exactly the
     * the same information (data index information). THe difference between
     * the two is that this method takes into account the fixed columns in the
     * table, so you can pass in nodes from the master table, or the cloned
     * tables and get the index position for the data in the main table.
     *  @param {node} node TR, TH or TD element to get the information about
     *  @returns {int} If nNode is given as a TR, then a single index is 
     *    returned, or if given as a cell, an array of [row index, column index
     *    (visible), column index (all)] is given.
     */
    
"fnGetPosition": function ( node )
    {
        var 
idx;
        var 
inst this.s.dt.oInstance;

        if ( ! $(
node).parents('.DTFC_Cloned').length )
        {
            
// Not in a cloned table
            
return inst.fnGetPositionnode );
        }
        else
        {
            
// Its in the cloned table, so need to look up position
            
if ( node.nodeName.toLowerCase() === 'tr' ) {
                
idx = $(node).index();
                return 
inst.fnGetPosition( $('tr'this.s.dt.nTBody)[ idx ] );
            }
            else
            {
                var 
colIdx = $(node).index();
                
idx = $(node.parentNode).index();
                var 
row inst.fnGetPosition( $('tr'this.s.dt.nTBody)[ idx ] );

                return [
                    
row,
                    
colIdx,
                    
inst.oApi._fnVisibleToColumnIndexthis.s.dtcolIdx )
                ];
            }
        }
    },



    
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * Private methods (they are of course public in JS, but recommended as private)
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    /**
     * Initialisation for FixedColumns
     *  @param   {Object} oInit User settings for initialisation
     *  @returns {void}
     *  @private
     */
    
"_fnConstruct": function ( oInit )
    {
        var 
iiLeniWidth,
            
that this;

        
/* Sanity checking */
        
if ( typeof this.s.dt.oInstance.fnVersionCheck != 'function' ||
             
this.s.dt.oInstance.fnVersionCheck'1.8.0' ) !== true )
        {
            
alert"FixedColumns "+FixedColumns.VERSION+" required DataTables 1.8.0 or later. "+
                
"Please upgrade your DataTables installation" );
            return;
        }

        if ( 
this.s.dt.oScroll.sX === "" )
        {
            
this.s.dt.oInstance.oApi._fnLogthis.s.dt1"FixedColumns is not needed (no "+
                
"x-scrolling in DataTables enabled), so no action will be taken. Use 'FixedHeader' for "+
                
"column fixing when scrolling is not enabled" );
            return;
        }

        
/* Apply the settings from the user / defaults */
        
this.= $.extendtruethis.sFixedColumns.defaultsoInit );

        
/* Set up the DOM as we need it and cache nodes */
        
var classes this.s.dt.oClasses;
        
this.dom.grid.dt = $(this.s.dt.nTable).parents('div.'+classes.sScrollWrapper)[0];
        
this.dom.scroller = $('div.'+classes.sScrollBodythis.dom.grid.dt )[0];

        
/* Set up the DOM that we want for the fixed column layout grid */
        
this._fnColCalc();
        
this._fnGridSetup();

        
/* Event handlers */
        
var mouseController;

        
// When the body is scrolled - scroll the left and right columns
        
$(this.dom.scroller)
            .
on'mouseover.DTFC touchstart.DTFC', function () {
                
mouseController 'main';
            } )
            .
on'scroll.DTFC', function () {
                if ( 
mouseController === 'main' ) {
                    if ( 
that.s.iLeftColumns ) {
                        
that.dom.grid.left.liner.scrollTop that.dom.scroller.scrollTop;
                    }
                    if ( 
that.s.iRightColumns ) {
                        
that.dom.grid.right.liner.scrollTop that.dom.scroller.scrollTop;
                    }
                }
            } );

        var 
wheelType 'onwheel' in document.createElement('div') ?
            
'wheel.DTFC' :
            
'mousewheel.DTFC';

        if ( 
that.s.iLeftColumns ) {
            
// When scrolling the left column, scroll the body and right column
            
$(that.dom.grid.left.liner)
                .
on'mouseover.DTFC touchstart.DTFC', function () {
                    
mouseController 'left';
                } )
                .
on'scroll.DTFC', function () {
                    if ( 
mouseController === 'left' ) {
                        
that.dom.scroller.scrollTop that.dom.grid.left.liner.scrollTop;
                        if ( 
that.s.iRightColumns ) {
                            
that.dom.grid.right.liner.scrollTop that.dom.grid.left.liner.scrollTop;
                        }
                    }
                } )
                .
onwheelType, function(e) { // xxx update the destroy as well
                    // Pass horizontal scrolling through
                    
var xDelta e.type === 'wheel' ?
                        -
e.originalEvent.deltaX :
                        
e.originalEvent.wheelDeltaX;
                    
that.dom.scroller.scrollLeft -= xDelta;
                } );
        }

        if ( 
that.s.iRightColumns ) {
            
// When scrolling the right column, scroll the body and the left column
            
$(that.dom.grid.right.liner)
                .
on'mouseover.DTFC touchstart.DTFC', function () {
                    
mouseController 'right';
                } )
                .
on'scroll.DTFC', function () {
                    if ( 
mouseController === 'right' ) {
                        
that.dom.scroller.scrollTop that.dom.grid.right.liner.scrollTop;
                        if ( 
that.s.iLeftColumns ) {
                            
that.dom.grid.left.liner.scrollTop that.dom.grid.right.liner.scrollTop;
                        }
                    }
                } )
                .
onwheelType, function(e) {
                    
// Pass horizontal scrolling through
                    
var xDelta e.type === 'wheel' ?
                        -
e.originalEvent.deltaX :
                        
e.originalEvent.wheelDeltaX;
                    
that.dom.scroller.scrollLeft -= xDelta;
                } );
        }

        $(
window).on'resize.DTFC', function () {
            
that._fnGridLayout.callthat );
        } );

        var 
bFirstDraw true;
        var 
jqTable = $(this.s.dt.nTable);

        
jqTable
            
.on'draw.dt.DTFC', function () {
                
that._fnDraw.callthatbFirstDraw );
                
bFirstDraw false;
            } )
            .
on'column-sizing.dt.DTFC', function () {
                
that._fnColCalc();
                
that._fnGridLayoutthat );
            } )
            .
on'column-visibility.dt.DTFC', function () {
                
that._fnColCalc();
                
that._fnGridLayoutthat );
                
that._fnDrawtrue );
            } )
            .
on'destroy.dt.DTFC', function () {
                
jqTable.off'column-sizing.dt.DTFC destroy.dt.DTFC draw.dt.DTFC' );

                $(
that.dom.scroller).off'scroll.DTFC mouseover.DTFC' );
                $(
window).off'resize.DTFC' );

                $(
that.dom.grid.left.liner).off'scroll.DTFC mouseover.DTFC '+wheelType );
                $(
that.dom.grid.left.wrapper).remove();

                $(
that.dom.grid.right.liner).off'scroll.DTFC mouseover.DTFC '+wheelType );
                $(
that.dom.grid.right.wrapper).remove();
            } );

        
/* Get things right to start with - note that due to adjusting the columns, there must be
         * another redraw of the main table. It doesn't need to be a full redraw however.
         */
        
this._fnGridLayout();
        
this.s.dt.oInstance.fnDraw(false);
    },


    
/**
     * Calculate the column widths for the grid layout
     *  @returns {void}
     *  @private
     */
    
"_fnColCalc": function ()
    {
        var 
that this;
        var 
iLeftWidth 0;
        var 
iRightWidth 0;

        
this.s.aiInnerWidths = [];
        
this.s.aiOuterWidths = [];

        $.
eachthis.s.dt.aoColumns, function (icol) {
            var 
th = $(col.nTh);
            var 
border;

            if ( ! 
th.filter(':visible').length ) {
                
that.s.aiInnerWidths.push);
                
that.s.aiOuterWidths.push);
            }
            else
            {
                
// Inner width is used to assign widths to cells
                // Outer width is used to calculate the container
                
var iWidth th.outerWidth();

                
// When working with the left most-cell, need to add on the
                // table's border to the outerWidth, since we need to take
                // account of it, but it isn't in any cell
                
if ( that.s.aiOuterWidths.length === ) {
                    
border = $(that.s.dt.nTable).css('border-left-width');
                    
iWidth += typeof border === 'string' parseIntborder10 );
                }

                
// Likewise with the final column on the right
                
if ( that.s.aiOuterWidths.length === that.s.dt.aoColumns.length-) {
                    
border = $(that.s.dt.nTable).css('border-right-width');
                    
iWidth += typeof border === 'string' parseIntborder10 );
                }

                
that.s.aiOuterWidths.pushiWidth );
                
that.s.aiInnerWidths.pushth.width() );

                if ( 
that.s.iLeftColumns )
                {
                    
iLeftWidth += iWidth;
                }

                if ( 
that.s.iTableColumns-that.s.iRightColumns <= )
                {
                    
iRightWidth += iWidth;
                }
            }
        } );

        
this.s.iLeftWidth iLeftWidth;
        
this.s.iRightWidth iRightWidth;
    },


    
/**
     * Set up the DOM for the fixed column. The way the layout works is to create a 1x3 grid
     * for the left column, the DataTable (for which we just reuse the scrolling element DataTable
     * puts into the DOM) and the right column. In each of he two fixed column elements there is a
     * grouping wrapper element and then a head, body and footer wrapper. In each of these we then
     * place the cloned header, body or footer tables. This effectively gives as 3x3 grid structure.
     *  @returns {void}
     *  @private
     */
    
"_fnGridSetup": function ()
    {
        var 
that this;
        var 
oOverflow this._fnDTOverflow();
        var 
block;

        
this.dom.body this.s.dt.nTable;
        
this.dom.header this.s.dt.nTHead.parentNode;
        
this.dom.header.parentNode.parentNode.style.position "relative";

        var 
nSWrapper =
            $(
'<div class="DTFC_ScrollWrapper" style="position:relative; clear:both;">'+
                
'<div class="DTFC_LeftWrapper" style="position:absolute; top:0; left:0;">'+
                    
'<div class="DTFC_LeftHeadWrapper" style="position:relative; top:0; left:0; overflow:hidden;"></div>'+
                    
'<div class="DTFC_LeftBodyWrapper" style="position:relative; top:0; left:0; overflow:hidden;">'+
                        
'<div class="DTFC_LeftBodyLiner" style="position:relative; top:0; left:0; overflow-y:scroll;"></div>'+
                    
'</div>'+
                    
'<div class="DTFC_LeftFootWrapper" style="position:relative; top:0; left:0; overflow:hidden;"></div>'+
                
'</div>'+
                
'<div class="DTFC_RightWrapper" style="position:absolute; top:0; left:0;">'+
                    
'<div class="DTFC_RightHeadWrapper" style="position:relative; top:0; left:0;">'+
                        
'<div class="DTFC_RightHeadBlocker DTFC_Blocker" style="position:absolute; top:0; bottom:0;"></div>'+
                    
'</div>'+
                    
'<div class="DTFC_RightBodyWrapper" style="position:relative; top:0; left:0; overflow:hidden;">'+
                        
'<div class="DTFC_RightBodyLiner" style="position:relative; top:0; left:0; overflow-y:scroll;"></div>'+
                    
'</div>'+
                    
'<div class="DTFC_RightFootWrapper" style="position:relative; top:0; left:0;">'+
                        
'<div class="DTFC_RightFootBlocker DTFC_Blocker" style="position:absolute; top:0; bottom:0;"></div>'+
                    
'</div>'+
                
'</div>'+
            
'</div>')[0];
        var 
nLeft nSWrapper.childNodes[0];
        var 
nRight nSWrapper.childNodes[1];

        
this.dom.grid.dt.parentNode.insertBeforenSWrapperthis.dom.grid.dt );
        
nSWrapper.appendChildthis.dom.grid.dt );

        
this.dom.grid.wrapper nSWrapper;

        if ( 
this.s.iLeftColumns )
        {
            
this.dom.grid.left.wrapper nLeft;
            
this.dom.grid.left.head nLeft.childNodes[0];
            
this.dom.grid.left.body nLeft.childNodes[1];
            
this.dom.grid.left.liner = $('div.DTFC_LeftBodyLiner'nSWrapper)[0];

            
nSWrapper.appendChildnLeft );
        }

        if ( 
this.s.iRightColumns )
        {
            
this.dom.grid.right.wrapper nRight;
            
this.dom.grid.right.head nRight.childNodes[0];
            
this.dom.grid.right.body nRight.childNodes[1];
            
this.dom.grid.right.liner = $('div.DTFC_RightBodyLiner'nSWrapper)[0];

            
block = $('div.DTFC_RightHeadBlocker'nSWrapper)[0];
            
block.style.width oOverflow.bar+"px";
            
block.style.right = -oOverflow.bar+"px";
            
this.dom.grid.right.headBlock block;

            
block = $('div.DTFC_RightFootBlocker'nSWrapper)[0];
            
block.style.width oOverflow.bar+"px";
            
block.style.right = -oOverflow.bar+"px";
            
this.dom.grid.right.footBlock block;

            
nSWrapper.appendChildnRight );
        }

        if ( 
this.s.dt.nTFoot )
        {
            
this.dom.footer this.s.dt.nTFoot.parentNode;
            if ( 
this.s.iLeftColumns )
            {
                
this.dom.grid.left.foot nLeft.childNodes[2];
            }
            if ( 
this.s.iRightColumns )
            {
                
this.dom.grid.right.foot nRight.childNodes[2];
            }
        }
    },


    
/**
     * Style and position the grid used for the FixedColumns layout
     *  @returns {void}
     *  @private
     */
    
"_fnGridLayout": function ()
    {
        var 
oGrid this.dom.grid;
        var 
iWidth = $(oGrid.wrapper).width();
        var 
iBodyHeight = $(this.s.dt.nTable.parentNode).outerHeight();
        var 
iFullHeight = $(this.s.dt.nTable.parentNode.parentNode).outerHeight();
        var 
oOverflow this._fnDTOverflow();
        var
            
iLeftWidth this.s.iLeftWidth,
            
iRightWidth this.s.iRightWidth,
            
iRight;
        var 
scrollbarAdjust = function ( nodewidth ) {
            if ( ! 
oOverflow.bar ) {
                
// If there is no scrollbar (Macs) we need to hide the auto scrollbar
                
node.style.width = (width+20)+"px";
                
node.style.paddingRight "20px";
                
node.style.boxSizing "border-box";
            }
            else {
                
// Otherwise just overflow by the scrollbar
                
node.style.width = (width+oOverflow.bar)+"px";
            }
        };

        
// When x scrolling - don't paint the fixed columns over the x scrollbar
        
if ( oOverflow.)
        {
            
iBodyHeight -= oOverflow.bar;
        }

        
oGrid.wrapper.style.height iFullHeight+"px";

        if ( 
this.s.iLeftColumns )
        {
            
oGrid.left.wrapper.style.width iLeftWidth+"px";
            
oGrid.left.wrapper.style.height "1px";
            
oGrid.left.body.style.height iBodyHeight+"px";
            if ( 
oGrid.left.foot ) {
                
oGrid.left.foot.style.top = (oOverflow.oOverflow.bar 0)+"px"// shift footer for scrollbar
            
}

            
scrollbarAdjustoGrid.left.lineriLeftWidth );
            
oGrid.left.liner.style.height iBodyHeight+"px";
        }

        if ( 
this.s.iRightColumns )
        {
            
iRight iWidth iRightWidth;
            if ( 
oOverflow.)
            {
                
iRight -= oOverflow.bar;
            }

            
oGrid.right.wrapper.style.width iRightWidth+"px";
            
oGrid.right.wrapper.style.left iRight+"px";
            
oGrid.right.wrapper.style.height "1px";
            
oGrid.right.body.style.height iBodyHeight+"px";
            if ( 
oGrid.right.foot ) {
                
oGrid.right.foot.style.top = (oOverflow.oOverflow.bar 0)+"px";
            }

            
scrollbarAdjustoGrid.right.lineriRightWidth );
            
oGrid.right.liner.style.height iBodyHeight+"px";

            
oGrid.right.headBlock.style.display oOverflow.'block' 'none';
            
oGrid.right.footBlock.style.display oOverflow.'block' 'none';
        }
    },


    
/**
     * Get information about the DataTable's scrolling state - specifically if the table is scrolling
     * on either the x or y axis, and also the scrollbar width.
     *  @returns {object} Information about the DataTables scrolling state with the properties:
     *    'x', 'y' and 'bar'
     *  @private
     */
    
"_fnDTOverflow": function ()
    {
        var 
nTable this.s.dt.nTable;
        var 
nTableScrollBody nTable.parentNode;
        var 
out = {
            
"x"false,
            
"y"false,
            
"bar"this.s.dt.oScroll.iBarWidth
        
};

        if ( 
nTable.offsetWidth nTableScrollBody.clientWidth )
        {
            
out.true;
        }

        if ( 
nTable.offsetHeight nTableScrollBody.clientHeight )
        {
            
out.true;
        }

        return 
out;
    },


    
/**
     * Clone and position the fixed columns
     *  @returns {void}
     *  @param   {Boolean} bAll Indicate if the header and footer should be updated as well (true)
     *  @private
     */
    
"_fnDraw": function ( bAll )
    {
        
this._fnGridLayout();
        
this._fnCloneLeftbAll );
        
this._fnCloneRightbAll );

        
/* Draw callback function */
        
if ( this.s.fnDrawCallback !== null )
        {
            
this.s.fnDrawCallback.callthisthis.dom.clone.leftthis.dom.clone.right );
        }

        
/* Event triggering */
        
$(this).trigger'draw.dtfc', {
            
"leftClone"this.dom.clone.left,
            
"rightClone"this.dom.clone.right
        
} );
    },


    
/**
     * Clone the right columns
     *  @returns {void}
     *  @param   {Boolean} bAll Indicate if the header and footer should be updated as well (true)
     *  @private
     */
    
"_fnCloneRight": function ( bAll )
    {
        if ( 
this.s.iRightColumns <= ) {
            return;
        }

        var 
that this,
            
ijq,
            
aiColumns = [];

        for ( 
i=this.s.iTableColumns-this.s.iRightColumns i<this.s.iTableColumns i++ ) {
            if ( 
this.s.dt.aoColumns[i].bVisible ) {
                
aiColumns.push);
            }
        }

        
this._fnClonethis.dom.clone.rightthis.dom.grid.rightaiColumnsbAll );
    },


    
/**
     * Clone the left columns
     *  @returns {void}
     *  @param   {Boolean} bAll Indicate if the header and footer should be updated as well (true)
     *  @private
     */
    
"_fnCloneLeft": function ( bAll )
    {
        if ( 
this.s.iLeftColumns <= ) {
            return;
        }

        var 
that this,
            
ijq,
            
aiColumns = [];

        for ( 
i=i<this.s.iLeftColumns i++ ) {
            if ( 
this.s.dt.aoColumns[i].bVisible ) {
                
aiColumns.push);
            }
        }

        
this._fnClonethis.dom.clone.leftthis.dom.grid.leftaiColumnsbAll );
    },


    
/**
     * Make a copy of the layout object for a header or footer element from DataTables. Note that
     * this method will clone the nodes in the layout object.
     *  @returns {Array} Copy of the layout array
     *  @param   {Object} aoOriginal Layout array from DataTables (aoHeader or aoFooter)
     *  @param   {Object} aiColumns Columns to copy
     *  @private
     */
    
"_fnCopyLayout": function ( aoOriginalaiColumns )
    {
        var 
aReturn = [];
        var 
aClones = [];
        var 
aCloned = [];

        for ( var 
i=0iLen=aoOriginal.length i<iLen i++ )
        {
            var 
aRow = [];
            
aRow.nTr = $(aoOriginal[i].nTr).clone(truetrue)[0];

            for ( var 
j=0jLen=this.s.iTableColumns j<jLen j++ )
            {
                if ( $.
inArrayjaiColumns ) === -)
                {
                    continue;
                }

                var 
iCloned = $.inArrayaoOriginal[i][j].cellaCloned );
                if ( 
iCloned === -)
                {
                    var 
nClone = $(aoOriginal[i][j].cell).clone(truetrue)[0];
                    
aClones.pushnClone );
                    
aCloned.pushaoOriginal[i][j].cell );

                    
aRow.push( {
                        
"cell"nClone,
                        
"unique"aoOriginal[i][j].unique
                    
} );
                }
                else
                {
                    
aRow.push( {
                        
"cell"aClonesiCloned ],
                        
"unique"aoOriginal[i][j].unique
                    
} );
                }
            }

            
aReturn.pushaRow );
        }

        return 
aReturn;
    },


    
/**
     * Clone the DataTable nodes and place them in the DOM (sized correctly)
     *  @returns {void}
     *  @param   {Object} oClone Object containing the header, footer and body cloned DOM elements
     *  @param   {Object} oGrid Grid object containing the display grid elements for the cloned
     *                    column (left or right)
     *  @param   {Array} aiColumns Column indexes which should be operated on from the DataTable
     *  @param   {Boolean} bAll Indicate if the header and footer should be updated as well (true)
     *  @private
     */
    
"_fnClone": function ( oCloneoGridaiColumnsbAll )
    {
        var 
that this,
            
iiLenjjLenjqnTargetiColumnnCloneiIndexaoCloneLayout,
            
jqCloneTheadaoFixedHeader,
            
dt this.s.dt;

        
/*
         * Header
         */
        
if ( bAll )
        {
            if ( 
oClone.header !== null )
            {
                
oClone.header.parentNode.removeChildoClone.header );
            }
            
oClone.header = $(this.dom.header).clone(truetrue)[0];
            
oClone.header.className += " DTFC_Cloned";
            
oClone.header.style.width "100%";
            
oGrid.head.appendChildoClone.header );

            
/* Copy the DataTables layout cache for the header for our floating column */
            
aoCloneLayout this._fnCopyLayoutdt.aoHeaderaiColumns );
            
jqCloneThead = $('>thead'oClone.header);
            
jqCloneThead.empty();

            
/* Add the created cloned TR elements to the table */
            
for ( i=0iLen=aoCloneLayout.length i<iLen i++ )
            {
                
jqCloneThead[0].appendChildaoCloneLayout[i].nTr );
            }

            
/* Use the handy _fnDrawHead function in DataTables to do the rowspan/colspan
             * calculations for us
             */
            
dt.oApi._fnDrawHeaddtaoCloneLayouttrue );
        }
        else
        {
            
/* To ensure that we copy cell classes exactly, regardless of colspan, multiple rows
             * etc, we make a copy of the header from the DataTable again, but don't insert the
             * cloned cells, just copy the classes across. To get the matching layout for the
             * fixed component, we use the DataTables _fnDetectHeader method, allowing 1:1 mapping
             */
            
aoCloneLayout this._fnCopyLayoutdt.aoHeaderaiColumns );
            
aoFixedHeader=[];

            
dt.oApi._fnDetectHeaderaoFixedHeader, $('>thead'oClone.header)[0] );

            for ( 
i=0iLen=aoCloneLayout.length i<iLen i++ )
            {
                for ( 
j=0jLen=aoCloneLayout[i].length j<jLen j++ )
                {
                    
aoFixedHeader[i][j].cell.className aoCloneLayout[i][j].cell.className;

                    
// If jQuery UI theming is used we need to copy those elements as well
                    
$('span.DataTables_sort_icon'aoFixedHeader[i][j].cell).each( function () {
                        
this.className = $('span.DataTables_sort_icon'aoCloneLayout[i][j].cell)[0].className;
                    } );
                }
            }
        }
        
this._fnEqualiseHeights'thead'this.dom.headeroClone.header );

        
/*
         * Body
         */
        
if ( this.s.sHeightMatch == 'auto' )
        {
            
/* Remove any heights which have been applied already and let the browser figure it out */
            
$('>tbody>tr'that.dom.body).css('height''auto');
        }

        if ( 
oClone.body !== null )
        {
            
oClone.body.parentNode.removeChildoClone.body );
            
oClone.body null;
        }

        
oClone.body = $(this.dom.body).clone(true)[0];
        
oClone.body.className += " DTFC_Cloned";
        
oClone.body.style.paddingBottom dt.oScroll.iBarWidth+"px";
        
oClone.body.style.marginBottom = (dt.oScroll.iBarWidth*2)+"px"/* For IE */
        
if ( oClone.body.getAttribute('id') !== null )
        {
            
oClone.body.removeAttribute('id');
        }

        $(
'>thead>tr'oClone.body).empty();
        $(
'>tfoot'oClone.body).remove();

        var 
nBody = $('tbody'oClone.body)[0];
        $(
nBody).empty();
        if ( 
dt.aiDisplay.length )
        {
            
/* Copy the DataTables' header elements to force the column width in exactly the
             * same way that DataTables does it - have the header element, apply the width and
             * colapse it down
             */
            
var nInnerThead = $('>thead>tr'oClone.body)[0];
            for ( 
iIndex=iIndex<aiColumns.length iIndex++ )
            {
                
iColumn aiColumns[iIndex];

                
nClone = $(dt.aoColumns[iColumn].nTh).clone(true)[0];
                
nClone.innerHTML "";

                var 
oStyle nClone.style;
                
oStyle.paddingTop "0";
                
oStyle.paddingBottom "0";
                
oStyle.borderTopWidth "0";
                
oStyle.borderBottomWidth "0";
                
oStyle.height 0;
                
oStyle.width that.s.aiInnerWidths[iColumn]+"px";

                
nInnerThead.appendChildnClone );
            }

            
/* Add in the tbody elements, cloning form the master table */
            
$('>tbody>tr'that.dom.body).each( function (z) {
                var 
this.cloneNode(false);
                
n.removeAttribute('id');
                var 
that.s.dt.oFeatures.bServerSide===false ?
                    
that.s.dt.aiDisplaythat.s.dt._iDisplayStart+] : z;
                var 
aTds that.s.dt.aoData].anCells || $(this).children('td, th');

                for ( 
iIndex=iIndex<aiColumns.length iIndex++ )
                {
                    
iColumn aiColumns[iIndex];

                    if ( 
aTds.length )
                    {
                        
nClone = $( aTds[iColumn] ).clone(truetrue)[0];
                        
n.appendChildnClone );
                    }
                }
                
nBody.appendChild);
            } );
        }
        else
        {
            $(
'>tbody>tr'that.dom.body).each( function (z) {
                
nClone this.cloneNode(true);
                
nClone.className += ' DTFC_NoData';
                $(
'td'nClone).html('');
                
nBody.appendChildnClone );
            } );
        }

        
oClone.body.style.width "100%";
        
oClone.body.style.margin "0";
        
oClone.body.style.padding "0";

        
// Interop with Scroller - need to use a height forcing element in the
        // scrolling area in the same way that Scroller does in the body scroll.
        
if ( dt.oScroller !== undefined )
        {
            var 
scrollerForcer dt.oScroller.dom.force;

            if ( ! 
oGrid.forcer ) {
                
oGrid.forcer scrollerForcer.cloneNodetrue );
                
oGrid.liner.appendChildoGrid.forcer );
            }
            else {
                
oGrid.forcer.style.height scrollerForcer.style.height;
            }
        }

        
oGrid.liner.appendChildoClone.body );

        
this._fnEqualiseHeights'tbody'that.dom.bodyoClone.body );

        
/*
         * Footer
         */
        
if ( dt.nTFoot !== null )
        {
            if ( 
bAll )
            {
                if ( 
oClone.footer !== null )
                {
                    
oClone.footer.parentNode.removeChildoClone.footer );
                }
                
oClone.footer = $(this.dom.footer).clone(truetrue)[0];
                
oClone.footer.className += " DTFC_Cloned";
                
oClone.footer.style.width "100%";
                
oGrid.foot.appendChildoClone.footer );

                
/* Copy the footer just like we do for the header */
                
aoCloneLayout this._fnCopyLayoutdt.aoFooteraiColumns );
                var 
jqCloneTfoot = $('>tfoot'oClone.footer);
                
jqCloneTfoot.empty();

                for ( 
i=0iLen=aoCloneLayout.length i<iLen i++ )
                {
                    
jqCloneTfoot[0].appendChildaoCloneLayout[i].nTr );
                }
                
dt.oApi._fnDrawHeaddtaoCloneLayouttrue );
            }
            else
            {
                
aoCloneLayout this._fnCopyLayoutdt.aoFooteraiColumns );
                var 
aoCurrFooter=[];

                
dt.oApi._fnDetectHeaderaoCurrFooter, $('>tfoot'oClone.footer)[0] );

                for ( 
i=0iLen=aoCloneLayout.length i<iLen i++ )
                {
                    for ( 
j=0jLen=aoCloneLayout[i].length j<jLen j++ )
                    {
                        
aoCurrFooter[i][j].cell.className aoCloneLayout[i][j].cell.className;
                    }
                }
            }
            
this._fnEqualiseHeights'tfoot'this.dom.footeroClone.footer );
        }

        
/* Equalise the column widths between the header footer and body - body get's priority */
        
var anUnique dt.oApi._fnGetUniqueThsdt, $('>thead'oClone.header)[0] );
        $(
anUnique).each( function (i) {
            
iColumn aiColumns[i];
            
this.style.width that.s.aiInnerWidths[iColumn]+"px";
        } );

        if ( 
that.s.dt.nTFoot !== null )
        {
            
anUnique dt.oApi._fnGetUniqueThsdt, $('>tfoot'oClone.footer)[0] );
            $(
anUnique).each( function (i) {
                
iColumn aiColumns[i];
                
this.style.width that.s.aiInnerWidths[iColumn]+"px";
            } );
        }
    },


    
/**
     * From a given table node (THEAD etc), get a list of TR direct child elements
     *  @param   {Node} nIn Table element to search for TR elements (THEAD, TBODY or TFOOT element)
     *  @returns {Array} List of TR elements found
     *  @private
     */
    
"_fnGetTrNodes": function ( nIn )
    {
        var 
aOut = [];
        for ( var 
i=0iLen=nIn.childNodes.length i<iLen i++ )
        {
            if ( 
nIn.childNodes[i].nodeName.toUpperCase() == "TR" )
            {
                
aOut.pushnIn.childNodes[i] );
            }
        }
        return 
aOut;
    },


    
/**
     * Equalise the heights of the rows in a given table node in a cross browser way
     *  @returns {void}
     *  @param   {String} nodeName Node type - thead, tbody or tfoot
     *  @param   {Node} original Original node to take the heights from
     *  @param   {Node} clone Copy the heights to
     *  @private
     */
    
"_fnEqualiseHeights": function ( nodeNameoriginal, clone )
    {
        if ( 
this.s.sHeightMatch == 'none' && nodeName !== 'thead' && nodeName !== 'tfoot' )
        {
            return;
        }

        var 
that this,
            
iiLeniHeightiHeight2iHeightOriginaliHeightClone,
            
rootOriginal original.getElementsByTagName(nodeName)[0],
            
rootClone    = clone.getElementsByTagName(nodeName)[0],
            
jqBoxHack    = $('>'+nodeName+'>tr:eq(0)'original).children(':first'),
            
iBoxHack     jqBoxHack.outerHeight() - jqBoxHack.height(),
            
anOriginal   this._fnGetTrNodesrootOriginal ),
            
anClone      this._fnGetTrNodesrootClone ),
            
heights      = [];

        for ( 
i=0iLen=anClone.length i<iLen i++ )
        {
            
iHeightOriginal anOriginal[i].offsetHeight;
            
iHeightClone anClone[i].offsetHeight;
            
iHeight iHeightClone iHeightOriginal iHeightClone iHeightOriginal;

            if ( 
this.s.sHeightMatch == 'semiauto' )
            {
                
anOriginal[i]._DTTC_iHeight iHeight;
            }

            
heights.pushiHeight );
        }

        for ( 
i=0iLen=anClone.length i<iLen i++ )
        {
            
anClone[i].style.height heights[i]+"px";
            
anOriginal[i].style.height heights[i]+"px";
        }
    }
};



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Statics
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/**
 * FixedColumns default settings for initialisation
 *  @name FixedColumns.defaults
 *  @namespace
 *  @static
 */
FixedColumns.defaults /** @lends FixedColumns.defaults */{
    
/**
     * Number of left hand columns to fix in position
     *  @type     int
     *  @default  1
     *  @static
     *  @example
     *      var  = $('#example').dataTable( {
     *          "scrollX": "100%"
     *      } );
     *      new $.fn.dataTable.fixedColumns( table, {
     *          "leftColumns": 2
     *      } );
     */
    
"iLeftColumns"1,

    
/**
     * Number of right hand columns to fix in position
     *  @type     int
     *  @default  0
     *  @static
     *  @example
     *      var table = $('#example').dataTable( {
     *          "scrollX": "100%"
     *      } );
     *      new $.fn.dataTable.fixedColumns( table, {
     *          "rightColumns": 1
     *      } );
     */
    
"iRightColumns"0,

    
/**
     * Draw callback function which is called when FixedColumns has redrawn the fixed assets
     *  @type     function(object, object):void
     *  @default  null
     *  @static
     *  @example
     *      var table = $('#example').dataTable( {
     *          "scrollX": "100%"
     *      } );
     *      new $.fn.dataTable.fixedColumns( table, {
     *          "drawCallback": function () {
     *                alert( "FixedColumns redraw" );
     *            }
     *      } );
     */
    
"fnDrawCallback"null,

    
/**
     * Height matching algorthim to use. This can be "none" which will result in no height
     * matching being applied by FixedColumns (height matching could be forced by CSS in this
     * case), "semiauto" whereby the height calculation will be performed once, and the result
     * cached to be used again (fnRecalculateHeight can be used to force recalculation), or
     * "auto" when height matching is performed on every draw (slowest but must accurate)
     *  @type     string
     *  @default  semiauto
     *  @static
     *  @example
     *      var table = $('#example').dataTable( {
     *          "scrollX": "100%"
     *      } );
     *      new $.fn.dataTable.fixedColumns( table, {
     *          "heightMatch": "auto"
     *      } );
     */
    
"sHeightMatch""semiauto"
};




/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Constants
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/**
 * FixedColumns version
 *  @name      FixedColumns.version
 *  @type      String
 *  @default   See code
 *  @static
 */
FixedColumns.version "3.0.4";



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Fired events (for documentation)
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


/**
 * 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.
 * @name FixedColumns#draw.dtfc
 * @event
 * @param {event} e jQuery event object
 * @param {object} o Event parameters from FixedColumns
 * @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
 * @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
 */


// Make FixedColumns accessible from the DataTables instance
$.fn.dataTable.FixedColumns FixedColumns;
$.
fn.DataTable.FixedColumns FixedColumns;


return 
FixedColumns;
}; 
// /factory


// Define as an AMD module if possible
if ( typeof define === 'function' && define.amd ) {
    
define( ['jquery''datatables'], factory );
}
else if ( 
typeof exports === 'object' ) {
    
// Node/CommonJS
    
factory( require('jquery'), require('datatables') );
}
else if ( 
jQuery && !jQuery.fn.dataTable.FixedColumns ) {
    
// Otherwise simply initialise as normal, stopping multiple evaluation
    
factoryjQueryjQuery.fn.dataTable );
}


})(
windowdocument);
?>
Онлайн: 0
Реклама