aboutsummaryrefslogtreecommitdiff
path: root/wqflask
diff options
context:
space:
mode:
authorzsloan2015-07-23 16:20:55 +0000
committerzsloan2015-07-23 16:20:55 +0000
commitc053ff453e6c8354e61b227d028378712ab240d6 (patch)
tree1b754cb3c1e6670c9078c799b0990313169b54d1 /wqflask
parent1e190b22c35c5a7d71eafa8c7136fd9b8cbd0688 (diff)
downloadgenenetwork2-c053ff453e6c8354e61b227d028378712ab240d6.tar.gz
Committing most recent changes to tables so Lei can pull; still have a few more issues to resolve, like setting initial column width
Diffstat (limited to 'wqflask')
-rw-r--r--wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.colReorder.js1372
-rw-r--r--wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.colResize.js1669
-rw-r--r--wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.fixedHeader.css4
-rw-r--r--wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.fixedHeader.js1027
-rwxr-xr-xwqflask/wqflask/templates/correlation_page.html27
-rwxr-xr-xwqflask/wqflask/templates/search_result_page.html55
-rwxr-xr-xwqflask/wqflask/templates/show_trait.html131
-rwxr-xr-xwqflask/wqflask/templates/show_trait_edit_data.html25
8 files changed, 3417 insertions, 893 deletions
diff --git a/wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.colReorder.js b/wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.colReorder.js
new file mode 100644
index 00000000..58e7656e
--- /dev/null
+++ b/wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.colReorder.js
@@ -0,0 +1,1372 @@
+/*! ColReorder 1.1.3
+ * ©2010-2014 SpryMedia Ltd - datatables.net/license
+ */
+
+/**
+ * @summary ColReorder
+ * @description Provide the ability to reorder columns in a DataTable
+ * @version 1.1.3
+ * @file dataTables.colReorder.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(window, document, undefined) {
+
+
+/**
+ * Switch the key value pairing of an index array to be value key (i.e. the old value is now the
+ * key). For example consider [ 2, 0, 1 ] this would be returned as [ 1, 2, 0 ].
+ * @method fnInvertKeyValues
+ * @param array aIn Array to switch around
+ * @returns array
+ */
+function fnInvertKeyValues( aIn )
+{
+ var aRet=[];
+ for ( var i=0, iLen=aIn.length ; i<iLen ; i++ )
+ {
+ aRet[ aIn[i] ] = i;
+ }
+ return aRet;
+}
+
+
+/**
+ * Modify an array by switching the position of two elements
+ * @method fnArraySwitch
+ * @param array aArray Array to consider, will be modified by reference (i.e. no return)
+ * @param int iFrom From point
+ * @param int iTo Insert point
+ * @returns void
+ */
+function fnArraySwitch( aArray, iFrom, iTo )
+{
+ var mStore = aArray.splice( iFrom, 1 )[0];
+ aArray.splice( iTo, 0, mStore );
+}
+
+
+/**
+ * Switch the positions of nodes in a parent node (note this is specifically designed for
+ * table rows). Note this function considers all element nodes under the parent!
+ * @method fnDomSwitch
+ * @param string sTag Tag to consider
+ * @param int iFrom Element to move
+ * @param int Point to element the element to (before this point), can be null for append
+ * @returns void
+ */
+function fnDomSwitch( nParent, iFrom, iTo )
+{
+ var anTags = [];
+ for ( var i=0, iLen=nParent.childNodes.length ; i<iLen ; i++ )
+ {
+ if ( nParent.childNodes[i].nodeType == 1 )
+ {
+ anTags.push( nParent.childNodes[i] );
+ }
+ }
+ var nStore = anTags[ iFrom ];
+
+ if ( iTo !== null )
+ {
+ nParent.insertBefore( nStore, anTags[iTo] );
+ }
+ else
+ {
+ nParent.appendChild( nStore );
+ }
+}
+
+
+
+var factory = function( $, DataTable ) {
+"use strict";
+
+/**
+ * Plug-in for DataTables which will reorder the internal column structure by taking the column
+ * from one position (iFrom) and insert it into a given point (iTo).
+ * @method $.fn.dataTableExt.oApi.fnColReorder
+ * @param object oSettings DataTables settings object - automatically added by DataTables!
+ * @param int iFrom Take the column to be repositioned from this point
+ * @param int iTo and insert it into this point
+ * @returns void
+ */
+$.fn.dataTableExt.oApi.fnColReorder = function ( oSettings, iFrom, iTo )
+{
+ var v110 = $.fn.dataTable.Api ? true : false;
+ var i, iLen, j, jLen, iCols=oSettings.aoColumns.length, nTrs, oCol;
+ var attrMap = function ( obj, prop, mapping ) {
+ if ( ! obj[ prop ] ) {
+ return;
+ }
+
+ var a = obj[ prop ].split('.');
+ var num = a.shift();
+
+ if ( isNaN( num*1 ) ) {
+ return;
+ }
+
+ obj[ prop ] = mapping[ num*1 ]+'.'+a.join('.');
+ };
+
+ /* Sanity check in the input */
+ if ( iFrom == iTo )
+ {
+ /* Pointless reorder */
+ return;
+ }
+
+ if ( iFrom < 0 || iFrom >= iCols )
+ {
+ this.oApi._fnLog( oSettings, 1, "ColReorder 'from' index is out of bounds: "+iFrom );
+ return;
+ }
+
+ if ( iTo < 0 || iTo >= iCols )
+ {
+ this.oApi._fnLog( oSettings, 1, "ColReorder 'to' index is out of bounds: "+iTo );
+ return;
+ }
+
+ /*
+ * Calculate the new column array index, so we have a mapping between the old and new
+ */
+ var aiMapping = [];
+ for ( i=0, iLen=iCols ; i<iLen ; i++ )
+ {
+ aiMapping[i] = i;
+ }
+ fnArraySwitch( aiMapping, iFrom, iTo );
+ var aiInvertMapping = fnInvertKeyValues( aiMapping );
+
+
+ /*
+ * Convert all internal indexing to the new column order indexes
+ */
+ /* Sorting */
+ for ( i=0, iLen=oSettings.aaSorting.length ; i<iLen ; i++ )
+ {
+ oSettings.aaSorting[i][0] = aiInvertMapping[ oSettings.aaSorting[i][0] ];
+ }
+
+ /* Fixed sorting */
+ if ( oSettings.aaSortingFixed !== null )
+ {
+ for ( i=0, iLen=oSettings.aaSortingFixed.length ; i<iLen ; i++ )
+ {
+ oSettings.aaSortingFixed[i][0] = aiInvertMapping[ oSettings.aaSortingFixed[i][0] ];
+ }
+ }
+
+ /* Data column sorting (the column which the sort for a given column should take place on) */
+ for ( i=0, iLen=iCols ; i<iLen ; i++ )
+ {
+ oCol = oSettings.aoColumns[i];
+ for ( j=0, jLen=oCol.aDataSort.length ; j<jLen ; j++ )
+ {
+ oCol.aDataSort[j] = aiInvertMapping[ oCol.aDataSort[j] ];
+ }
+
+ // Update the column indexes
+ if ( v110 ) {
+ oCol.idx = aiInvertMapping[ oCol.idx ];
+ }
+ }
+
+ if ( v110 ) {
+ // Update 1.10 optimised sort class removal variable
+ $.each( oSettings.aLastSort, function (i, val) {
+ oSettings.aLastSort[i].src = aiInvertMapping[ val.src ];
+ } );
+ }
+
+ /* Update the Get and Set functions for each column */
+ for ( i=0, iLen=iCols ; i<iLen ; i++ )
+ {
+ oCol = oSettings.aoColumns[i];
+
+ if ( typeof oCol.mData == 'number' ) {
+ oCol.mData = aiInvertMapping[ oCol.mData ];
+
+ // regenerate the get / set functions
+ oSettings.oApi._fnColumnOptions( oSettings, i, {} );
+ }
+ else if ( $.isPlainObject( oCol.mData ) ) {
+ // HTML5 data sourced
+ attrMap( oCol.mData, '_', aiInvertMapping );
+ attrMap( oCol.mData, 'filter', aiInvertMapping );
+ attrMap( oCol.mData, 'sort', aiInvertMapping );
+ attrMap( oCol.mData, 'type', aiInvertMapping );
+
+ // regenerate the get / set functions
+ oSettings.oApi._fnColumnOptions( oSettings, i, {} );
+ }
+ }
+
+
+ /*
+ * Move the DOM elements
+ */
+ if ( oSettings.aoColumns[iFrom].bVisible )
+ {
+ /* Calculate the current visible index and the point to insert the node before. The insert
+ * before needs to take into account that there might not be an element to insert before,
+ * in which case it will be null, and an appendChild should be used
+ */
+ var iVisibleIndex = this.oApi._fnColumnIndexToVisible( oSettings, iFrom );
+ var iInsertBeforeIndex = null;
+
+ i = iTo < iFrom ? iTo : iTo + 1;
+ while ( iInsertBeforeIndex === null && i < iCols )
+ {
+ iInsertBeforeIndex = this.oApi._fnColumnIndexToVisible( oSettings, i );
+ i++;
+ }
+
+ /* Header */
+ nTrs = oSettings.nTHead.getElementsByTagName('tr');
+ for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
+ {
+ fnDomSwitch( nTrs[i], iVisibleIndex, iInsertBeforeIndex );
+ }
+
+ /* Footer */
+ if ( oSettings.nTFoot !== null )
+ {
+ nTrs = oSettings.nTFoot.getElementsByTagName('tr');
+ for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
+ {
+ fnDomSwitch( nTrs[i], iVisibleIndex, iInsertBeforeIndex );
+ }
+ }
+
+ /* Body */
+ for ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )
+ {
+ if ( oSettings.aoData[i].nTr !== null )
+ {
+ fnDomSwitch( oSettings.aoData[i].nTr, iVisibleIndex, iInsertBeforeIndex );
+ }
+ }
+ }
+
+ /*
+ * Move the internal array elements
+ */
+ /* Columns */
+ fnArraySwitch( oSettings.aoColumns, iFrom, iTo );
+
+ /* Search columns */
+ fnArraySwitch( oSettings.aoPreSearchCols, iFrom, iTo );
+
+ /* Array array - internal data anodes cache */
+ for ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )
+ {
+ var data = oSettings.aoData[i];
+
+ if ( v110 ) {
+ // DataTables 1.10+
+ if ( data.anCells ) {
+ fnArraySwitch( data.anCells, iFrom, iTo );
+ }
+
+ // For DOM sourced data, the invalidate will reread the cell into
+ // the data array, but for data sources as an array, they need to
+ // be flipped
+ if ( data.src !== 'dom' && $.isArray( data._aData ) ) {
+ fnArraySwitch( data._aData, iFrom, iTo );
+ }
+ }
+ else {
+ // DataTables 1.9-
+ if ( $.isArray( data._aData ) ) {
+ fnArraySwitch( data._aData, iFrom, iTo );
+ }
+ fnArraySwitch( data._anHidden, iFrom, iTo );
+ }
+ }
+
+ /* Reposition the header elements in the header layout array */
+ for ( i=0, iLen=oSettings.aoHeader.length ; i<iLen ; i++ )
+ {
+ fnArraySwitch( oSettings.aoHeader[i], iFrom, iTo );
+ }
+
+ if ( oSettings.aoFooter !== null )
+ {
+ for ( i=0, iLen=oSettings.aoFooter.length ; i<iLen ; i++ )
+ {
+ fnArraySwitch( oSettings.aoFooter[i], iFrom, iTo );
+ }
+ }
+
+ // In 1.10 we need to invalidate row cached data for sorting, filtering etc
+ if ( v110 ) {
+ var api = new $.fn.dataTable.Api( oSettings );
+ api.rows().invalidate();
+ }
+
+ /*
+ * Update DataTables' event handlers
+ */
+
+ /* Sort listener */
+ for ( i=0, iLen=iCols ; i<iLen ; i++ )
+ {
+ $(oSettings.aoColumns[i].nTh).off('click.DT');
+ this.oApi._fnSortAttachListener( oSettings, oSettings.aoColumns[i].nTh, i );
+ }
+
+
+ /* Fire an event so other plug-ins can update */
+ $(oSettings.oInstance).trigger( 'column-reorder', [ oSettings, {
+ "iFrom": iFrom,
+ "iTo": iTo,
+ "aiInvertMapping": aiInvertMapping
+ } ] );
+};
+
+
+/**
+ * ColReorder provides column visibility control for DataTables
+ * @class ColReorder
+ * @constructor
+ * @param {object} dt DataTables settings object
+ * @param {object} opts ColReorder options
+ */
+var ColReorder = function( dt, opts )
+{
+ var oDTSettings;
+
+ if ( $.fn.dataTable.Api ) {
+ oDTSettings = new $.fn.dataTable.Api( dt ).settings()[0];
+ }
+ // 1.9 compatibility
+ else if ( dt.fnSettings ) {
+ // DataTables object, convert to the settings object
+ oDTSettings = dt.fnSettings();
+ }
+ else if ( typeof dt === 'string' ) {
+ // jQuery selector
+ if ( $.fn.dataTable.fnIsDataTable( $(dt)[0] ) ) {
+ oDTSettings = $(dt).eq(0).dataTable().fnSettings();
+ }
+ }
+ else if ( dt.nodeName && dt.nodeName.toLowerCase() === 'table' ) {
+ // Table node
+ if ( $.fn.dataTable.fnIsDataTable( dt.nodeName ) ) {
+ oDTSettings = $(dt.nodeName).dataTable().fnSettings();
+ }
+ }
+ else if ( dt instanceof jQuery ) {
+ // jQuery object
+ if ( $.fn.dataTable.fnIsDataTable( dt[0] ) ) {
+ oDTSettings = dt.eq(0).dataTable().fnSettings();
+ }
+ }
+ else {
+ // DataTables settings object
+ oDTSettings = dt;
+ }
+
+ // Ensure that we can't initialise on the same table twice
+ if ( oDTSettings._colReorder ) {
+ throw "ColReorder already initialised on table #"+oDTSettings.nTable.id;
+ }
+
+ // Convert from camelCase to Hungarian, just as DataTables does
+ var camelToHungarian = $.fn.dataTable.camelToHungarian;
+ if ( camelToHungarian ) {
+ camelToHungarian( ColReorder.defaults, ColReorder.defaults, true );
+ camelToHungarian( ColReorder.defaults, opts || {} );
+ }
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Public class variables
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /**
+ * @namespace Settings object which contains customisable information for ColReorder instance
+ */
+ this.s = {
+ /**
+ * DataTables settings object
+ * @property dt
+ * @type Object
+ * @default null
+ */
+ "dt": null,
+
+ /**
+ * Initialisation object used for this instance
+ * @property init
+ * @type object
+ * @default {}
+ */
+ "init": $.extend( true, {}, ColReorder.defaults, opts ),
+
+ /**
+ * Number of columns to fix (not allow to be reordered)
+ * @property fixed
+ * @type int
+ * @default 0
+ */
+ "fixed": 0,
+
+ /**
+ * Number of columns to fix counting from right (not allow to be reordered)
+ * @property fixedRight
+ * @type int
+ * @default 0
+ */
+ "fixedRight": 0,
+
+ /**
+ * Callback function for once the reorder has been done
+ * @property reorderCallback
+ * @type function
+ * @default null
+ */
+ "reorderCallback": null,
+
+ /**
+ * @namespace Information used for the mouse drag
+ */
+ "mouse": {
+ "startX": -1,
+ "startY": -1,
+ "offsetX": -1,
+ "offsetY": -1,
+ "target": -1,
+ "targetIndex": -1,
+ "fromIndex": -1
+ },
+
+ /**
+ * Information which is used for positioning the insert cusor and knowing where to do the
+ * insert. Array of objects with the properties:
+ * x: x-axis position
+ * to: insert point
+ * @property aoTargets
+ * @type array
+ * @default []
+ */
+ "aoTargets": []
+ };
+
+
+ /**
+ * @namespace Common and useful DOM elements for the class instance
+ */
+ this.dom = {
+ /**
+ * Dragging element (the one the mouse is moving)
+ * @property drag
+ * @type element
+ * @default null
+ */
+ "drag": null,
+
+ /**
+ * The insert cursor
+ * @property pointer
+ * @type element
+ * @default null
+ */
+ "pointer": null
+ };
+
+
+ /* Constructor logic */
+ this.s.dt = oDTSettings;
+ this.s.dt._colReorder = this;
+ this._fnConstruct();
+
+ /* Add destroy callback */
+ oDTSettings.oApi._fnCallbackReg(oDTSettings, 'aoDestroyCallback', $.proxy(this._fnDestroy, this), 'ColReorder');
+
+ return this;
+};
+
+
+
+ColReorder.prototype = {
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Public methods
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /**
+ * Reset the column ordering to the original ordering that was detected on
+ * start up.
+ * @return {this} Returns `this` for chaining.
+ *
+ * @example
+ * // DataTables initialisation with ColReorder
+ * var table = $('#example').dataTable( {
+ * "sDom": 'Rlfrtip'
+ * } );
+ *
+ * // Add click event to a button to reset the ordering
+ * $('#resetOrdering').click( function (e) {
+ * e.preventDefault();
+ * $.fn.dataTable.ColReorder( table ).fnReset();
+ * } );
+ */
+ "fnReset": function ()
+ {
+ var a = [];
+ for ( var i=0, iLen=this.s.dt.aoColumns.length ; i<iLen ; i++ )
+ {
+ a.push( this.s.dt.aoColumns[i]._ColReorder_iOrigCol );
+ }
+
+ this._fnOrderColumns( a );
+
+ return this;
+ },
+
+ /**
+ * `Deprecated` - Get the current order of the columns, as an array.
+ * @return {array} Array of column identifiers
+ * @deprecated `fnOrder` should be used in preference to this method.
+ * `fnOrder` acts as a getter/setter.
+ */
+ "fnGetCurrentOrder": function ()
+ {
+ return this.fnOrder();
+ },
+
+ /**
+ * Get the current order of the columns, as an array. Note that the values
+ * given in the array are unique identifiers for each column. Currently
+ * these are the original ordering of the columns that was detected on
+ * start up, but this could potentially change in future.
+ * @return {array} Array of column identifiers
+ *
+ * @example
+ * // Get column ordering for the table
+ * var order = $.fn.dataTable.ColReorder( dataTable ).fnOrder();
+ *//**
+ * Set the order of the columns, from the positions identified in the
+ * ordering array given. Note that ColReorder takes a brute force approach
+ * to reordering, so it is possible multiple reordering events will occur
+ * before the final order is settled upon.
+ * @param {array} [set] Array of column identifiers in the new order. Note
+ * that every column must be included, uniquely, in this array.
+ * @return {this} Returns `this` for chaining.
+ *
+ * @example
+ * // Swap the first and second columns
+ * $.fn.dataTable.ColReorder( dataTable ).fnOrder( [1, 0, 2, 3, 4] );
+ *
+ * @example
+ * // Move the first column to the end for the table `#example`
+ * var curr = $.fn.dataTable.ColReorder( '#example' ).fnOrder();
+ * var first = curr.shift();
+ * curr.push( first );
+ * $.fn.dataTable.ColReorder( '#example' ).fnOrder( curr );
+ *
+ * @example
+ * // Reverse the table's order
+ * $.fn.dataTable.ColReorder( '#example' ).fnOrder(
+ * $.fn.dataTable.ColReorder( '#example' ).fnOrder().reverse()
+ * );
+ */
+ "fnOrder": function ( set )
+ {
+ if ( set === undefined )
+ {
+ var a = [];
+ for ( var i=0, iLen=this.s.dt.aoColumns.length ; i<iLen ; i++ )
+ {
+ a.push( this.s.dt.aoColumns[i]._ColReorder_iOrigCol );
+ }
+ return a;
+ }
+
+ this._fnOrderColumns( fnInvertKeyValues( set ) );
+
+ return this;
+ },
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Private methods (they are of course public in JS, but recommended as private)
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /**
+ * Constructor logic
+ * @method _fnConstruct
+ * @returns void
+ * @private
+ */
+ "_fnConstruct": function ()
+ {
+ var that = this;
+ var iLen = this.s.dt.aoColumns.length;
+ var i;
+
+ /* Columns discounted from reordering - counting left to right */
+ if ( this.s.init.iFixedColumns )
+ {
+ this.s.fixed = this.s.init.iFixedColumns;
+ }
+
+ /* Columns discounted from reordering - counting right to left */
+ this.s.fixedRight = this.s.init.iFixedColumnsRight ?
+ this.s.init.iFixedColumnsRight :
+ 0;
+
+ /* Drop callback initialisation option */
+ if ( this.s.init.fnReorderCallback )
+ {
+ this.s.reorderCallback = this.s.init.fnReorderCallback;
+ }
+
+ /* Add event handlers for the drag and drop, and also mark the original column order */
+ for ( i = 0; i < iLen; i++ )
+ {
+ if ( i > this.s.fixed-1 && i < iLen - this.s.fixedRight )
+ {
+ this._fnMouseListener( i, this.s.dt.aoColumns[i].nTh );
+ }
+
+ /* Mark the original column order for later reference */
+ this.s.dt.aoColumns[i]._ColReorder_iOrigCol = i;
+ }
+
+ /* State saving */
+ this.s.dt.oApi._fnCallbackReg( this.s.dt, 'aoStateSaveParams', function (oS, oData) {
+ that._fnStateSave.call( that, oData );
+ }, "ColReorder_State" );
+
+ /* An initial column order has been specified */
+ var aiOrder = null;
+ if ( this.s.init.aiOrder )
+ {
+ aiOrder = this.s.init.aiOrder.slice();
+ }
+
+ /* State loading, overrides the column order given */
+ if ( this.s.dt.oLoadedState && typeof this.s.dt.oLoadedState.ColReorder != 'undefined' &&
+ this.s.dt.oLoadedState.ColReorder.length == this.s.dt.aoColumns.length )
+ {
+ aiOrder = this.s.dt.oLoadedState.ColReorder;
+ }
+
+ /* If we have an order to apply - do so */
+ if ( aiOrder )
+ {
+ /* We might be called during or after the DataTables initialisation. If before, then we need
+ * to wait until the draw is done, if after, then do what we need to do right away
+ */
+ if ( !that.s.dt._bInitComplete )
+ {
+ var bDone = false;
+ this.s.dt.aoDrawCallback.push( {
+ "fn": function () {
+ if ( !that.s.dt._bInitComplete && !bDone )
+ {
+ bDone = true;
+ var resort = fnInvertKeyValues( aiOrder );
+ that._fnOrderColumns.call( that, resort );
+ }
+ },
+ "sName": "ColReorder_Pre"
+ } );
+ }
+ else
+ {
+ var resort = fnInvertKeyValues( aiOrder );
+ that._fnOrderColumns.call( that, resort );
+ }
+ }
+ else {
+ this._fnSetColumnIndexes();
+ }
+ },
+
+
+ /**
+ * Set the column order from an array
+ * @method _fnOrderColumns
+ * @param array a An array of integers which dictate the column order that should be applied
+ * @returns void
+ * @private
+ */
+ "_fnOrderColumns": function ( a )
+ {
+ if ( a.length != this.s.dt.aoColumns.length )
+ {
+ this.s.dt.oInstance.oApi._fnLog( this.s.dt, 1, "ColReorder - array reorder does not "+
+ "match known number of columns. Skipping." );
+ return;
+ }
+
+ for ( var i=0, iLen=a.length ; i<iLen ; i++ )
+ {
+ var currIndex = $.inArray( i, a );
+ if ( i != currIndex )
+ {
+ /* Reorder our switching array */
+ fnArraySwitch( a, currIndex, i );
+
+ /* Do the column reorder in the table */
+ this.s.dt.oInstance.fnColReorder( currIndex, i );
+ }
+ }
+
+ /* When scrolling we need to recalculate the column sizes to allow for the shift */
+ if ( this.s.dt.oScroll.sX !== "" || this.s.dt.oScroll.sY !== "" )
+ {
+ this.s.dt.oInstance.fnAdjustColumnSizing( false );
+ }
+
+ /* Save the state */
+ this.s.dt.oInstance.oApi._fnSaveState( this.s.dt );
+
+ this._fnSetColumnIndexes();
+
+ if ( this.s.reorderCallback !== null )
+ {
+ this.s.reorderCallback.call( this );
+ }
+ },
+
+
+ /**
+ * Because we change the indexes of columns in the table, relative to their starting point
+ * we need to reorder the state columns to what they are at the starting point so we can
+ * then rearrange them again on state load!
+ * @method _fnStateSave
+ * @param object oState DataTables state
+ * @returns string JSON encoded cookie string for DataTables
+ * @private
+ */
+ "_fnStateSave": function ( oState )
+ {
+ var i, iLen, aCopy, iOrigColumn;
+ var oSettings = this.s.dt;
+ var columns = oSettings.aoColumns;
+
+ oState.ColReorder = [];
+
+ /* Sorting */
+ if ( oState.aaSorting ) {
+ // 1.10.0-
+ for ( i=0 ; i<oState.aaSorting.length ; i++ ) {
+ oState.aaSorting[i][0] = columns[ oState.aaSorting[i][0] ]._ColReorder_iOrigCol;
+ }
+
+ var aSearchCopy = $.extend( true, [], oState.aoSearchCols );
+
+ for ( i=0, iLen=columns.length ; i<iLen ; i++ )
+ {
+ iOrigColumn = columns[i]._ColReorder_iOrigCol;
+
+ /* Column filter */
+ oState.aoSearchCols[ iOrigColumn ] = aSearchCopy[i];
+
+ /* Visibility */
+ oState.abVisCols[ iOrigColumn ] = columns[i].bVisible;
+
+ /* Column reordering */
+ oState.ColReorder.push( iOrigColumn );
+ }
+ }
+ else if ( oState.order ) {
+ // 1.10.1+
+ for ( i=0 ; i<oState.order.length ; i++ ) {
+ oState.order[i][0] = columns[ oState.order[i][0] ]._ColReorder_iOrigCol;
+ }
+
+ var stateColumnsCopy = $.extend( true, [], oState.columns );
+
+ for ( i=0, iLen=columns.length ; i<iLen ; i++ )
+ {
+ iOrigColumn = columns[i]._ColReorder_iOrigCol;
+
+ /* Columns */
+ oState.columns[ iOrigColumn ] = stateColumnsCopy[i];
+
+ /* Column reordering */
+ oState.ColReorder.push( iOrigColumn );
+ }
+ }
+ },
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mouse drop and drag
+ */
+
+ /**
+ * Add a mouse down listener to a particluar TH element
+ * @method _fnMouseListener
+ * @param int i Column index
+ * @param element nTh TH element clicked on
+ * @returns void
+ * @private
+ */
+ "_fnMouseListener": function ( i, nTh )
+ {
+ var that = this;
+ $(nTh).on( 'mousedown.ColReorder', function (e) {
+ e.preventDefault();
+ that._fnMouseDown.call( that, e, nTh );
+ } );
+ },
+
+
+ /**
+ * Mouse down on a TH element in the table header
+ * @method _fnMouseDown
+ * @param event e Mouse event
+ * @param element nTh TH element to be dragged
+ * @returns void
+ * @private
+ */
+ "_fnMouseDown": function ( e, nTh )
+ {
+ var that = this;
+
+ /* Store information about the mouse position */
+ var target = $(e.target).closest('th, td');
+ var offset = target.offset();
+ var idx = parseInt( $(nTh).attr('data-column-index'), 10 );
+
+ if ( idx === undefined ) {
+ return;
+ }
+
+ this.s.mouse.startX = e.pageX;
+ this.s.mouse.startY = e.pageY;
+ this.s.mouse.offsetX = e.pageX - offset.left;
+ this.s.mouse.offsetY = e.pageY - offset.top;
+ this.s.mouse.target = this.s.dt.aoColumns[ idx ].nTh;//target[0];
+ this.s.mouse.targetIndex = idx;
+ this.s.mouse.fromIndex = idx;
+
+ this._fnRegions();
+
+ /* Add event handlers to the document */
+ $(document)
+ .on( 'mousemove.ColReorder', function (e) {
+ that._fnMouseMove.call( that, e );
+ } )
+ .on( 'mouseup.ColReorder', function (e) {
+ that._fnMouseUp.call( that, e );
+ } );
+ },
+
+
+ /**
+ * Deal with a mouse move event while dragging a node
+ * @method _fnMouseMove
+ * @param event e Mouse event
+ * @returns void
+ * @private
+ */
+ "_fnMouseMove": function ( e )
+ {
+ var that = this;
+
+ if ( this.dom.drag === null )
+ {
+ /* Only create the drag element if the mouse has moved a specific distance from the start
+ * point - this allows the user to make small mouse movements when sorting and not have a
+ * possibly confusing drag element showing up
+ */
+ if ( Math.pow(
+ Math.pow(e.pageX - this.s.mouse.startX, 2) +
+ Math.pow(e.pageY - this.s.mouse.startY, 2), 0.5 ) < 5 )
+ {
+ return;
+ }
+ this._fnCreateDragNode();
+ }
+
+ /* Position the element - we respect where in the element the click occured */
+ this.dom.drag.css( {
+ left: e.pageX - this.s.mouse.offsetX,
+ top: e.pageY - this.s.mouse.offsetY
+ } );
+
+ /* Based on the current mouse position, calculate where the insert should go */
+ var bSet = false;
+ var lastToIndex = this.s.mouse.toIndex;
+
+ for ( var i=1, iLen=this.s.aoTargets.length ; i<iLen ; i++ )
+ {
+ if ( e.pageX < this.s.aoTargets[i-1].x + ((this.s.aoTargets[i].x-this.s.aoTargets[i-1].x)/2) )
+ {
+ this.dom.pointer.css( 'left', this.s.aoTargets[i-1].x );
+ this.s.mouse.toIndex = this.s.aoTargets[i-1].to;
+ bSet = true;
+ break;
+ }
+ }
+
+ // The insert element wasn't positioned in the array (less than
+ // operator), so we put it at the end
+ if ( !bSet )
+ {
+ this.dom.pointer.css( 'left', this.s.aoTargets[this.s.aoTargets.length-1].x );
+ this.s.mouse.toIndex = this.s.aoTargets[this.s.aoTargets.length-1].to;
+ }
+
+ // Perform reordering if realtime updating is on and the column has moved
+ if ( this.s.init.bRealtime && lastToIndex !== this.s.mouse.toIndex ) {
+ this.s.dt.oInstance.fnColReorder( this.s.mouse.fromIndex, this.s.mouse.toIndex );
+ this.s.mouse.fromIndex = this.s.mouse.toIndex;
+ this._fnRegions();
+ }
+ },
+
+
+ /**
+ * Finish off the mouse drag and insert the column where needed
+ * @method _fnMouseUp
+ * @param event e Mouse event
+ * @returns void
+ * @private
+ */
+ "_fnMouseUp": function ( e )
+ {
+ var that = this;
+
+ $(document).off( 'mousemove.ColReorder mouseup.ColReorder' );
+
+ if ( this.dom.drag !== null )
+ {
+ /* Remove the guide elements */
+ this.dom.drag.remove();
+ this.dom.pointer.remove();
+ this.dom.drag = null;
+ this.dom.pointer = null;
+
+ /* Actually do the reorder */
+ this.s.dt.oInstance.fnColReorder( this.s.mouse.fromIndex, this.s.mouse.toIndex );
+ this._fnSetColumnIndexes();
+
+ /* When scrolling we need to recalculate the column sizes to allow for the shift */
+ if ( this.s.dt.oScroll.sX !== "" || this.s.dt.oScroll.sY !== "" )
+ {
+ this.s.dt.oInstance.fnAdjustColumnSizing( false );
+ }
+
+ /* Save the state */
+ this.s.dt.oInstance.oApi._fnSaveState( this.s.dt );
+
+ if ( this.s.reorderCallback !== null )
+ {
+ this.s.reorderCallback.call( this );
+ }
+ }
+ },
+
+
+ /**
+ * Calculate a cached array with the points of the column inserts, and the
+ * 'to' points
+ * @method _fnRegions
+ * @returns void
+ * @private
+ */
+ "_fnRegions": function ()
+ {
+ var aoColumns = this.s.dt.aoColumns;
+
+ this.s.aoTargets.splice( 0, this.s.aoTargets.length );
+
+ this.s.aoTargets.push( {
+ "x": $(this.s.dt.nTable).offset().left,
+ "to": 0
+ } );
+
+ var iToPoint = 0;
+ for ( var i=0, iLen=aoColumns.length ; i<iLen ; i++ )
+ {
+ /* For the column / header in question, we want it's position to remain the same if the
+ * position is just to it's immediate left or right, so we only incremement the counter for
+ * other columns
+ */
+ if ( i != this.s.mouse.fromIndex )
+ {
+ iToPoint++;
+ }
+
+ if ( aoColumns[i].bVisible )
+ {
+ this.s.aoTargets.push( {
+ "x": $(aoColumns[i].nTh).offset().left + $(aoColumns[i].nTh).outerWidth(),
+ "to": iToPoint
+ } );
+ }
+ }
+
+ /* Disallow columns for being reordered by drag and drop, counting right to left */
+ if ( this.s.fixedRight !== 0 )
+ {
+ this.s.aoTargets.splice( this.s.aoTargets.length - this.s.fixedRight );
+ }
+
+ /* Disallow columns for being reordered by drag and drop, counting left to right */
+ if ( this.s.fixed !== 0 )
+ {
+ this.s.aoTargets.splice( 0, this.s.fixed );
+ }
+ },
+
+
+ /**
+ * Copy the TH element that is being drags so the user has the idea that they are actually
+ * moving it around the page.
+ * @method _fnCreateDragNode
+ * @returns void
+ * @private
+ */
+ "_fnCreateDragNode": function ()
+ {
+ var scrolling = this.s.dt.oScroll.sX !== "" || this.s.dt.oScroll.sY !== "";
+
+ var origCell = this.s.dt.aoColumns[ this.s.mouse.targetIndex ].nTh;
+ var origTr = origCell.parentNode;
+ var origThead = origTr.parentNode;
+ var origTable = origThead.parentNode;
+ var cloneCell = $(origCell).clone();
+
+ // This is a slightly odd combination of jQuery and DOM, but it is the
+ // fastest and least resource intensive way I could think of cloning
+ // the table with just a single header cell in it.
+ this.dom.drag = $(origTable.cloneNode(false))
+ .addClass( 'DTCR_clonedTable' )
+ .append(
+ $(origThead.cloneNode(false)).append(
+ $(origTr.cloneNode(false)).append(
+ cloneCell[0]
+ )
+ )
+ )
+ .css( {
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ width: $(origCell).outerWidth(),
+ height: $(origCell).outerHeight()
+ } )
+ .appendTo( 'body' );
+
+ this.dom.pointer = $('<div></div>')
+ .addClass( 'DTCR_pointer' )
+ .css( {
+ position: 'absolute',
+ top: scrolling ?
+ $('div.dataTables_scroll', this.s.dt.nTableWrapper).offset().top :
+ $(this.s.dt.nTable).offset().top,
+ height : scrolling ?
+ $('div.dataTables_scroll', this.s.dt.nTableWrapper).height() :
+ $(this.s.dt.nTable).height()
+ } )
+ .appendTo( 'body' );
+ },
+
+ /**
+ * Clean up ColReorder memory references and event handlers
+ * @method _fnDestroy
+ * @returns void
+ * @private
+ */
+ "_fnDestroy": function ()
+ {
+ var i, iLen;
+
+ for ( i=0, iLen=this.s.dt.aoDrawCallback.length ; i<iLen ; i++ )
+ {
+ if ( this.s.dt.aoDrawCallback[i].sName === 'ColReorder_Pre' )
+ {
+ this.s.dt.aoDrawCallback.splice( i, 1 );
+ break;
+ }
+ }
+
+ $(this.s.dt.nTHead).find( '*' ).off( '.ColReorder' );
+
+ $.each( this.s.dt.aoColumns, function (i, column) {
+ $(column.nTh).removeAttr('data-column-index');
+ } );
+
+ this.s.dt._colReorder = null;
+ this.s = null;
+ },
+
+
+ /**
+ * Add a data attribute to the column headers, so we know the index of
+ * the row to be reordered. This allows fast detection of the index, and
+ * for this plug-in to work with FixedHeader which clones the nodes.
+ * @private
+ */
+ "_fnSetColumnIndexes": function ()
+ {
+ $.each( this.s.dt.aoColumns, function (i, column) {
+ $(column.nTh).attr('data-column-index', i);
+ } );
+ }
+};
+
+
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Static parameters
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+/**
+ * ColReorder default settings for initialisation
+ * @namespace
+ * @static
+ */
+ColReorder.defaults = {
+ /**
+ * Predefined ordering for the columns that will be applied automatically
+ * on initialisation. If not specified then the order that the columns are
+ * found to be in the HTML is the order used.
+ * @type array
+ * @default null
+ * @static
+ * @example
+ * // Using the `oColReorder` option in the DataTables options object
+ * $('#example').dataTable( {
+ * "sDom": 'Rlfrtip',
+ * "oColReorder": {
+ * "aiOrder": [ 4, 3, 2, 1, 0 ]
+ * }
+ * } );
+ *
+ * @example
+ * // Using `new` constructor
+ * $('#example').dataTable()
+ *
+ * new $.fn.dataTable.ColReorder( '#example', {
+ * "aiOrder": [ 4, 3, 2, 1, 0 ]
+ * } );
+ */
+ aiOrder: null,
+
+ /**
+ * Redraw the table's column ordering as the end user draws the column
+ * (`true`) or wait until the mouse is released (`false` - default). Note
+ * that this will perform a redraw on each reordering, which involves an
+ * Ajax request each time if you are using server-side processing in
+ * DataTables.
+ * @type boolean
+ * @default false
+ * @static
+ * @example
+ * // Using the `oColReorder` option in the DataTables options object
+ * $('#example').dataTable( {
+ * "sDom": 'Rlfrtip',
+ * "oColReorder": {
+ * "bRealtime": true
+ * }
+ * } );
+ *
+ * @example
+ * // Using `new` constructor
+ * $('#example').dataTable()
+ *
+ * new $.fn.dataTable.ColReorder( '#example', {
+ * "bRealtime": true
+ * } );
+ */
+ bRealtime: false,
+
+ /**
+ * Indicate how many columns should be fixed in position (counting from the
+ * left). This will typically be 1 if used, but can be as high as you like.
+ * @type int
+ * @default 0
+ * @static
+ * @example
+ * // Using the `oColReorder` option in the DataTables options object
+ * $('#example').dataTable( {
+ * "sDom": 'Rlfrtip',
+ * "oColReorder": {
+ * "iFixedColumns": 1
+ * }
+ * } );
+ *
+ * @example
+ * // Using `new` constructor
+ * $('#example').dataTable()
+ *
+ * new $.fn.dataTable.ColReorder( '#example', {
+ * "iFixedColumns": 1
+ * } );
+ */
+ iFixedColumns: 0,
+
+ /**
+ * As `iFixedColumnsRight` but counting from the right.
+ * @type int
+ * @default 0
+ * @static
+ * @example
+ * // Using the `oColReorder` option in the DataTables options object
+ * $('#example').dataTable( {
+ * "sDom": 'Rlfrtip',
+ * "oColReorder": {
+ * "iFixedColumnsRight": 1
+ * }
+ * } );
+ *
+ * @example
+ * // Using `new` constructor
+ * $('#example').dataTable()
+ *
+ * new $.fn.dataTable.ColReorder( '#example', {
+ * "iFixedColumnsRight": 1
+ * } );
+ */
+ iFixedColumnsRight: 0,
+
+ /**
+ * Callback function that is fired when columns are reordered
+ * @type function():void
+ * @default null
+ * @static
+ * @example
+ * // Using the `oColReorder` option in the DataTables options object
+ * $('#example').dataTable( {
+ * "sDom": 'Rlfrtip',
+ * "oColReorder": {
+ * "fnReorderCallback": function () {
+ * alert( 'Columns reordered' );
+ * }
+ * }
+ * } );
+ *
+ * @example
+ * // Using `new` constructor
+ * $('#example').dataTable()
+ *
+ * new $.fn.dataTable.ColReorder( '#example', {
+ * "fnReorderCallback": function () {
+ * alert( 'Columns reordered' );
+ * }
+ * } );
+ */
+ fnReorderCallback: null
+};
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Constants
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/**
+ * ColReorder version
+ * @constant version
+ * @type String
+ * @default As code
+ */
+ColReorder.version = "1.1.3";
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * DataTables interfaces
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+// Expose
+$.fn.dataTable.ColReorder = ColReorder;
+$.fn.DataTable.ColReorder = ColReorder;
+
+
+// Register a new feature with DataTables
+if ( typeof $.fn.dataTable == "function" &&
+ typeof $.fn.dataTableExt.fnVersionCheck == "function" &&
+ $.fn.dataTableExt.fnVersionCheck('1.9.3') )
+{
+ $.fn.dataTableExt.aoFeatures.push( {
+ "fnInit": function( settings ) {
+ var table = settings.oInstance;
+
+ if ( ! settings._colReorder ) {
+ var dtInit = settings.oInit;
+ var opts = dtInit.colReorder || dtInit.oColReorder || {};
+
+ new ColReorder( settings, opts );
+ }
+ else {
+ table.oApi._fnLog( settings, 1, "ColReorder attempted to initialise twice. Ignoring second" );
+ }
+
+ return null; /* No node for DataTables to insert */
+ },
+ "cFeature": "R",
+ "sFeature": "ColReorder"
+ } );
+}
+else {
+ alert( "Warning: ColReorder requires DataTables 1.9.3 or greater - www.datatables.net/download");
+}
+
+
+// API augmentation
+if ( $.fn.dataTable.Api ) {
+ $.fn.dataTable.Api.register( 'colReorder.reset()', function () {
+ return this.iterator( 'table', function ( ctx ) {
+ ctx._colReorder.fnReset();
+ } );
+ } );
+
+ $.fn.dataTable.Api.register( 'colReorder.order()', function ( set ) {
+ if ( set ) {
+ return this.iterator( 'table', function ( ctx ) {
+ ctx._colReorder.fnOrder( set );
+ } );
+ }
+
+ return this.context.length ?
+ this.context[0]._colReorder.fnOrder() :
+ null;
+ } );
+}
+
+return ColReorder;
+}; // /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.ColReorder ) {
+ // Otherwise simply initialise as normal, stopping multiple evaluation
+ factory( jQuery, jQuery.fn.dataTable );
+}
+
+
+})(window, document); \ No newline at end of file
diff --git a/wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.colResize.js b/wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.colResize.js
index 2712750a..6ef9907a 100644
--- a/wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.colResize.js
+++ b/wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.colResize.js
@@ -1,846 +1,943 @@
-/*! ColResize 0.0.10
- */
-
-/**
- * @summary ColResize
- * @description Provide the ability to resize columns in a DataTable
- * @version 0.0.10
- * @file dataTables.colResize.js
- * @author Silvacom Ltd.
- *
- * For details please refer to: http://www.datatables.net
- *
- * Special thank to everyone who has contributed to this plug in
- * - dykstrad
- * - tdillan (for 0.0.3 and 0.0.5 bug fixes)
- * - kylealonius (for 0.0.8 bug fix)
- * - the86freak (for 0.0.9 bug fix)
- */
-
-(function (window, document, undefined) {
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DataTables plug-in API functions test
- *
- * This are required by ColResize in order to perform the tasks required, and also keep this
- * code portable, to be used for other column resize projects with DataTables, if needed.
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- var factory = function ($, DataTable) {
- "use strict";
-
- /**
- * Plug-in for DataTables which will resize the columns depending on the handle clicked
- * @method $.fn.dataTableExt.oApi.fnColResize
- * @param object oSettings DataTables settings object - automatically added by DataTables!
- * @param int iCol Take the column to be resized
- * @returns void
- */
- $.fn.dataTableExt.oApi.fnColResize = function (oSettings, iCol) {
- var v110 = $.fn.dataTable.Api ? true : false;
-
- /*
- * Update DataTables' event handlers
- */
-
- /* Fire an event so other plug-ins can update */
- $(oSettings.oInstance).trigger('column-resize', [ oSettings, {
- "iCol": iCol
- } ]);
- };
-
- /**
- * ColResize provides column resize control for DataTables
- * @class ColResize
- * @constructor
- * @param {object} dt DataTables settings object
- * @param {object} opts ColResize options
- */
- var ColResize = function (dt, opts) {
- var oDTSettings;
-
- if ($.fn.dataTable.Api) {
- oDTSettings = new $.fn.dataTable.Api(dt).settings()[0];
- }
- // 1.9 compatibility
- else if (dt.fnSettings) {
- // DataTables object, convert to the settings object
- oDTSettings = dt.fnSettings();
- }
- else if (typeof dt === 'string') {
- // jQuery selector
- if ($.fn.dataTable.fnIsDataTable($(dt)[0])) {
- oDTSettings = $(dt).eq(0).dataTable().fnSettings();
- }
+var dt;
+(function (dt) {
+ var ColResize = (function () {
+ function ColResize($, api, settings) {
+ this.$ = $;
+ this.tableSize = -1;
+ this.initialized = false;
+ this.dt = {};
+ this.dom = {
+ fixedLayout: false,
+ fixedHeader: null,
+ winResizeTimer: null,
+ mouse: {
+ startX: -1,
+ startWidth: null
+ },
+ table: {
+ prevWidth: null
+ },
+ origState: true,
+ resize: false,
+ scrollHead: null,
+ scrollHeadTable: null,
+ scrollFoot: null,
+ scrollFootTable: null,
+ scrollFootInner: null,
+ scrollBody: null,
+ scrollBodyTable: null,
+ scrollX: false,
+ scrollY: false
+ };
+ this.settings = this.$.extend(true, {}, dt.ColResize.defaultSettings, settings);
+ this.dt.settings = api.settings()[0];
+ this.dt.api = api;
+ this.dt.settings.colResize = this;
+ this.registerCallbacks();
+ }
+ ColResize.prototype.initialize = function () {
+ var _this = this;
+ this.$.each(this.dt.settings.aoColumns, function (i, col) {
+ return _this.setupColumn(col);
+ });
+
+ //Initialize fixedHeader if specified
+ if (this.settings.fixedHeader)
+ this.setupFixedHeader();
+
+ //Save scroll head and body if found
+ this.dom.scrollHead = this.$('div.' + this.dt.settings.oClasses.sScrollHead, this.dt.settings.nTableWrapper);
+ this.dom.scrollHeadInner = this.$('div.' + this.dt.settings.oClasses.sScrollHeadInner, this.dom.scrollHead);
+ this.dom.scrollHeadTable = this.$('div.' + this.dt.settings.oClasses.sScrollHeadInner + ' > table', this.dom.scrollHead);
+
+ this.dom.scrollFoot = this.$('div.' + this.dt.settings.oClasses.sScrollFoot, this.dt.settings.nTableWrapper);
+ this.dom.scrollFootInner = this.$('div.' + this.dt.settings.oClasses.sScrollFootInner, this.dom.scrollFoot);
+ this.dom.scrollFootTable = this.$('div.' + this.dt.settings.oClasses.sScrollFootInner + ' > table', this.dom.scrollFoot);
+
+ this.dom.scrollBody = this.$('div.' + this.dt.settings.oClasses.sScrollBody, this.dt.settings.nTableWrapper);
+ this.dom.scrollBodyTable = this.$('> table', this.dom.scrollBody);
+ this.dt.api.on('draw.dt', this.onDraw.bind(this));
+ if (this.dom.scrollFootTable) {
+ this.dt.api.on('colPinFcDraw.dt', function (e, colPin, data) {
+ if (data.leftClone.header)
+ _this.$('tfoot', data.leftClone.header).remove();
+ if (data.leftClone.footer)
+ _this.$('thead', data.leftClone.footer).remove();
+ if (data.rightClone.header)
+ _this.$('tfoot', data.rightClone.header).remove();
+ if (data.rightClone.footer)
+ _this.$('thead', data.rightClone.footer).remove();
+ });
}
- else if (dt.nodeName && dt.nodeName.toLowerCase() === 'table') {
- // Table node
- if ($.fn.dataTable.fnIsDataTable(dt.nodeName)) {
- oDTSettings = $(dt.nodeName).dataTable().fnSettings();
- }
+
+ this.dom.scrollX = this.dt.settings.oInit.sScrollX === undefined ? false : true;
+ this.dom.scrollY = this.dt.settings.oInit.sScrollY === undefined ? false : true;
+
+ //SaveTableWidth
+ this.dt.settings.sTableWidthOrig = this.$(this.dt.settings.nTable).width();
+ this.updateTableSize();
+
+ this.dt.settings.oFeatures.bAutoWidthOrig = this.dt.settings.oFeatures.bAutoWidth;
+ this.dt.settings.oFeatures.bAutoWidth = false;
+
+ if (this.dt.settings.oInit.bStateSave && this.dt.settings.oLoadedState) {
+ this.loadState(this.dt.settings.oLoadedState);
}
- else if (dt instanceof jQuery) {
- // jQuery object
- if ($.fn.dataTable.fnIsDataTable(dt[0])) {
- oDTSettings = dt.eq(0).dataTable().fnSettings();
- }
+
+ this.onDraw();
+ this.dom.table.preWidth = parseFloat(this.dom.scrollBodyTable.css('width'));
+
+ if (!this.dom.scrollX && this.dom.scrollY && this.settings.fixedLayout && this.dt.settings._reszEvt) {
+ //We have to manually resize columns on window resize
+ var eventName = 'resize.DT-' + this.dt.settings.sInstance;
+ this.$(window).off(eventName);
+ this.$(window).on(eventName, function () {
+ _this.proportionallyColumnSizing();
+ //api._fnAdjustColumnSizing(this.dt.settings);
+ });
}
- else {
- // DataTables settings object
- oDTSettings = dt;
- }
-
- // Convert from camelCase to Hungarian, just as DataTables does
- if ($.fn.dataTable.camelToHungarian) {
- $.fn.dataTable.camelToHungarian(ColResize.defaults, opts || {});
- }
-
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Public class variables
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /**
- * @namespace Settings object which contains customizable information for ColResize instance
- */
- this.s = {
- /**
- * DataTables settings object
- * @property dt
- * @type Object
- * @default null
- */
- "dt": null,
-
- /**
- * Initialisation object used for this instance
- * @property init
- * @type object
- * @default {}
- */
- "init": $.extend(true, {}, ColResize.defaults, opts),
-
- /**
- * @namespace Information used for the mouse drag
- */
- "mouse": {
- "startX": -1,
- "startY": -1,
- "targetIndex": -1,
- "targetColumn": -1,
- "neighbourIndex": -1,
- "neighbourColumn": -1
- },
- /**
- * Status variable keeping track of mouse down status
- * @property isMousedown
- * @type boolean
- * @default false
- */
- "isMousedown": false
- };
+ if (this.dom.scrollX || this.dom.scrollY) {
+ this.dt.api.on('column-sizing.dt', this.fixFootAndHeadTables.bind(this));
+ this.dt.api.on('column-visibility.dt', this.fixFootAndHeadTables.bind(this));
+ }
+ this.initialized = true;
+ this.dt.settings.oApi._fnCallbackFire(this.dt.settings, 'colResizeInitCompleted', 'colResizeInitCompleted', [this]);
+ };
- /**
- * @namespace Common and useful DOM elements for the class instance
- */
- this.dom = {
- /**
- * Resizing element (the one the mouse is resizing)
- * @property resize
- * @type element
- * @default null
- */
- "resizeCol": null,
-
- /**
- * Resizing element neighbour (the column next to the one the mouse is resizing)
- * This is for fixed table resizing.
- * @property resize
- * @type element
- * @default null
- */
- "resizeColNeighbour": null,
-
- /**
- * Array of events to be restored, used for overriding existing events from other plugins for a time.
- * @property restoreEvents
- * @type array
- * @default []
- */
- "restoreEvents": []
+ ColResize.prototype.setupColumn = function (col) {
+ var _this = this;
+ var $th = this.$(col.nTh);
+ if (col.resizable === false)
+ return;
+
+ // listen to mousemove event for resize
+ $th.on('mousemove.ColResize', function (e) {
+ if (_this.dom.resize || col.resizable === false)
+ return;
+
+ /* Store information about the mouse position */
+ var $thTarget = e.target.nodeName.toUpperCase() == 'TH' ? _this.$(e.target) : _this.$(e.target).closest('TH');
+ var offset = $thTarget.offset();
+ var nLength = $thTarget.innerWidth();
+
+ /* are we on the col border (if so, resize col) */
+ if (Math.abs(e.pageX - Math.round(offset.left + nLength)) <= 5) {
+ $thTarget.css({ 'cursor': 'col-resize' });
+ } else
+ $thTarget.css({ 'cursor': 'pointer' });
+ });
+
+ //Save the original width
+ col._ColResize_sWidthOrig = col.sWidthOrig;
+ col.initWidth = $th.width();
+ col.minWidthOrig = col.minWidth;
+
+ $th.on('dblclick.ColResize', function (e) {
+ _this.onDblClick(e, $th, col);
+ });
+
+ $th.off('mousedown.ColReorder');
+
+ // listen to mousedown event
+ $th.on('mousedown.ColResize', function (e) {
+ return _this.onMouseDown(e, col);
+ });
+ };
+
+ ColResize.prototype.setupFixedHeader = function () {
+ var fhSettings = this.settings.fixedHeader === true ? undefined : this.settings.fixedHeader;
+
+ //If left or right option was set to true disable resizing for the first or last column
+ if (this.$.isPlainObject(fhSettings)) {
+ var columns = this.dt.settings.aoColumns;
+ if (fhSettings.left === true)
+ columns[0].resizable = false;
+ if (fhSettings.right === true)
+ columns[columns.length - 1].resizable = false;
+ }
+
+ this.dom.fixedHeader = new this.$.fn.dataTable.FixedHeader(this.dt.api, fhSettings);
+ var origUpdateClones = this.dom.fixedHeader._fnUpdateClones;
+ var that = this;
+
+ //FixeHeader doesn't have any callback after updating the clones so we have to wrap the orig function
+ this.dom.fixedHeader._fnUpdateClones = function () {
+ origUpdateClones.apply(this, arguments);
+ that.memorizeFixedHeaderNodes();
};
+ //As we missed the first call of _fnUpdateClones we have to call memorizeFixedHeaderNodes function manually
+ this.memorizeFixedHeaderNodes();
+ };
- /* Constructor logic */
- this.s.dt = oDTSettings.oInstance.fnSettings();
- this.s.dt._colResize = this;
- this._fnConstruct();
-
- /* Add destroy callback */
- oDTSettings.oApi._fnCallbackReg(oDTSettings, 'aoDestroyCallback', $.proxy(this._fnDestroy, this), 'ColResize');
-
- return this;
- };
-
-
- ColResize.prototype = {
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Public methods
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /**
- * Reset the column widths to the original widths that was detected on
- * start up.
- * @return {this} Returns `this` for chaining.
- *
- * @example
- * // DataTables initialisation with ColResize
- * var table = $('#example').dataTable( {
- * "sDom": 'Zlfrtip'
- * } );
- *
- * // Add click event to a button to reset the ordering
- * $('#resetOrdering').click( function (e) {
- * e.preventDefault();
- * $.fn.dataTable.ColResize( table ).fnReset();
- * } );
- */
- "fnReset": function () {
- var a = [];
- for (var i = 0, iLen = this.s.dt.aoColumns.length; i < iLen; i++) {
- this.s.dt.aoColumns[i].width = this.s.dt.aoColumns[i]._ColResize_iOrigWidth;
+ ColResize.prototype.memorizeFixedHeaderNodes = function () {
+ var _this = this;
+ var fhSettings = this.dom.fixedHeader.fnGetSettings();
+ var fhCache = fhSettings.aoCache;
+ var i, col;
+ for (i = 0; i < fhCache.length; i++) {
+ var type = fhCache[i].sType;
+ var propName;
+ var selector;
+ switch (type) {
+ case 'fixedHeader':
+ propName = 'fhTh';
+ selector = 'thead>tr>th';
+ this.dt.settings.fhTHead = fhCache[i].nNode;
+ break;
+ case 'fixedFooter':
+ propName = 'fhTf';
+ selector = 'thead>tr>th';
+
+ //prepend a cloned thead to the floating footer table so that resizing will work correctly
+ var tfoot = this.$(fhCache[i].nNode);
+ var thead = this.$(this.dt.settings.nTHead).clone().css({ height: 0, visibility: 'hidden' });
+ this.$('tr', thead).css('height', 0);
+ this.$('tr>th', thead).css({
+ 'height': 0,
+ 'padding-bottom': 0,
+ 'padding-top': 0,
+ 'border-bottom-width': 0,
+ 'border-top-width': 0,
+ 'line-height': 0
+ });
+ tfoot.prepend(thead);
+ this.$('tfoot>tr>th', tfoot).css('width', '');
+ this.dt.settings.fhTFoot = fhCache[i].nNode;
+ break;
+ default:
+ continue;
}
- this.s.dt.adjust().draw();
+ this.$(selector, fhCache[i].nNode).each(function (j, th) {
+ col = _this.getVisibleColumn(j);
+ col[propName] = th;
+ });
+ }
+ };
- return this;
- },
+ //zero based index
+ ColResize.prototype.getVisibleColumn = function (idx) {
+ var columns = this.dt.settings.aoColumns;
+ var currVisColIdx = -1;
+ for (var i = 0; i < columns.length; i++) {
+ if (!columns[i].bVisible)
+ continue;
+ currVisColIdx++;
+ if (currVisColIdx == idx)
+ return columns[i];
+ }
+ return null;
+ };
+ ColResize.prototype.updateTableSize = function () {
+ if (this.dom.scrollX && this.dom.scrollHeadTable.length)
+ this.tableSize = this.dom.scrollHeadTable.width();
+ else
+ this.tableSize = -1;
+ };
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Private methods (they are of course public in JS, but recommended as private)
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+ ColResize.prototype.proportionallyColumnSizing = function () {
+ var _this = this;
+ var prevWidths = [], newWidths = [], prevWidth, newWidth, newTableWidth, prevTableWidth, moveLength, multiplier, cWidth, i, j, delay = 500, prevTotalColWidths = 0, currTotalColWidths, columnRestWidths = [], columns = this.dt.settings.aoColumns, bodyTableColumns = this.$('thead th', this.dom.scrollBodyTable), headTableColumns = this.$('thead th', this.dom.scrollHeadTable), footTableColumns = this.dom.scrollFootTable.length ? this.$('thead th', this.dom.scrollFootTable) : [], visColumns = [];
- /**
- * Constructor logic
- * @method _fnConstruct
- * @returns void
- * @private
- */
- "_fnConstruct": function () {
- var that = this;
- var iLen = that.s.dt.aoColumns.length;
- var i;
+ for (i = 0; i < columns.length; i++) {
+ if (!columns[i].bVisible)
+ continue;
+ visColumns.push(columns[i]);
+ columnRestWidths.push(0); //set default value
+ }
- that._fnSetupMouseListeners();
+ for (i = 0; i < bodyTableColumns.length; i++) {
+ cWidth = parseFloat(bodyTableColumns[i].style.width);
+ prevTotalColWidths += cWidth;
+ prevWidths.push(cWidth);
+ }
- /* Add event handlers for the resize handles */
- for (i = 0; i < iLen; i++) {
- /* Mark the original column width for later reference */
- this.s.dt.aoColumns[i]._ColResize_iOrigWidth = this.s.dt.aoColumns[i].width;
+ for (i = 0; i < bodyTableColumns.length; i++) {
+ bodyTableColumns[i].style.width = '';
+ }
+
+ //Get the new table width calculated by the browser
+ newTableWidth = parseFloat(this.dom.scrollBodyTable.css('width'));
+
+ //Get the old table width
+ prevTableWidth = this.dom.table.preWidth;
+ moveLength = newTableWidth - prevTableWidth;
+ if (moveLength == 0) {
+ for (i = 0; i < bodyTableColumns.length; i++) {
+ bodyTableColumns[i].style.width = prevWidths[i] + 'px';
}
+ return;
+ }
- this._fnSetColumnIndexes();
-
- /* State saving */
- this.s.dt.oApi._fnCallbackReg( this.s.dt, 'aoStateSaveParams', function (oS, oData) {
- that._fnStateSave.call(that, oData);
- }, "ColResize_State" );
-
- // State loading
- this._fnStateLoad();
- },
-
- /**
- * @method _fnStateSave
- * @param object oState DataTables state
- * @private
- */
- "_fnStateSave": function (oState) {
- this.s.dt.aoColumns.forEach(function(col, index) {
- oState.columns[index].width = col.sWidthOrig;
- });
- },
-
- /**
- * If state has been loaded, apply the saved widths to the columns
- * @method _fnStateLoad
- * @private
- */
- "_fnStateLoad": function() {
- var that = this,
- loadedState = this.s.dt.oLoadedState;
- if (loadedState && loadedState.columns) {
- var colStates = loadedState.columns,
- currCols = this.s.dt.aoColumns;
- // Only apply the saved widths if the number of columns is the same.
- // Otherwise, we don't know if we're applying the width to the correct column.
- if (colStates.length > 0 && colStates.length === currCols.length) {
- colStates.forEach(function(state, index) {
- var col = that.s.dt.aoColumns[index];
- if (state.width) {
- col.sWidthOrig = col.sWidth = state.width;
- }
- });
+ //var tot = 0;
+ currTotalColWidths = prevTotalColWidths;
+ for (i = 0; i < visColumns.length; i++) {
+ //For each column calculate the new width
+ prevWidth = prevWidths[i];
+ multiplier = (+(prevWidth / prevTotalColWidths).toFixed(2));
+
+ //tot += multiplier;
+ newWidth = prevWidth + (moveLength * multiplier) + columnRestWidths[i];
+ currTotalColWidths -= prevWidth;
+
+ //Check whether the column can be resized to the new calculated value
+ //if not, set it to the min or max width depends on the moveLength value
+ if (!this.canResizeColumn(visColumns[i], newWidth)) {
+ cWidth = moveLength > 0 ? this.getColumnMaxWidth(visColumns[i]) : this.getColumnMinWidth(visColumns[i]);
+ var rest = newWidth - cWidth;
+ newWidth = cWidth;
+
+ for (j = (i + 1); j < visColumns.length; j++) {
+ columnRestWidths[j] += rest * (+(visColumns[j] / currTotalColWidths).toFixed(2));
}
}
- },
-
- /**
- * Remove events of type from obj add it to restoreEvents array to be restored at a later time
- * @param until string flag when to restore the event
- * @param obj Object to remove events from
- * @param type type of event to remove
- * @param namespace namespace of the event being removed
- */
- "_fnDelayEvents": function (until, obj, type, namespace) {
- var that = this;
- //Get the events for the object
- var events = $._data($(obj).get(0), 'events');
- $.each(events, function (i, o) {
- //If the event type matches
- if (i == type) {
- //Loop through the possible many events with that type
- $.each(o, function (k, v) {
- //Somehow it is possible for the event to be undefined make sure it is defined first
- if (v) {
- if (namespace) {
- //Add the event to the array of events to be restored later
- that.dom.restoreEvents.push({"until": until, "obj": obj, "type": v.type, "namespace": v.namespace, "handler": v.handler});
- //If the namespace matches
- if (v.namespace == namespace) {
- //Turn off/unbind the event
- $(obj).off(type + "." + namespace);
- }
- } else {
- //Add the event to the array of events to be restored later
- that.dom.restoreEvents.push({"until": until, "obj": obj, "type": v.type, "namespace": null, "handler": v.handler});
- //Turn off/unbind the event
- $(obj).off(type);
- }
- }
- });
- }
- });
- },
-
- /**
- * Loop through restoreEvents array and restore the events on the elements provided
- */
- "_fnRestoreEvents": function (until) {
- var that = this;
- //Loop through the events to be restored
- var i;
- for (i = that.dom.restoreEvents.length; i--;) {
- if (that.dom.restoreEvents[i].until == undefined || that.dom.restoreEvents[i].until == null || that.dom.restoreEvents[i].until == until) {
- if (that.dom.restoreEvents[i].namespace) {
- //Turn on the event for the object provided
- $(that.dom.restoreEvents[i].obj).off(that.dom.restoreEvents[i].type + "." + that.dom.restoreEvents[i].namespace).on(that.dom.restoreEvents[i].type + "." + that.dom.restoreEvents[i].namespace, that.dom.restoreEvents[i].handler);
- that.dom.restoreEvents.splice(i, 1);
- } else {
- //Turn on the event for the object provided
- $(that.dom.restoreEvents[i].obj).off(that.dom.restoreEvents[i].type).on(that.dom.restoreEvents[i].type, that.dom.restoreEvents[i].handler);
- that.dom.restoreEvents.splice(i, 1);
- }
- }
+ newWidths.push(newWidth);
+ }
+
+ //Apply the calculated column widths to the headers cells
+ var tablesWidth = this.dom.scrollBodyTable.outerWidth() + 'px';
+ for (i = 0; i < headTableColumns.length; i++) {
+ headTableColumns[i].style.width = newWidths[i] + 'px';
+ }
+ this.dom.scrollHeadTable.css('width', tablesWidth);
+ this.dom.scrollHeadInner.css('width', tablesWidth);
+
+ for (i = 0; i < bodyTableColumns.length; i++) {
+ bodyTableColumns[i].style.width = newWidths[i] + 'px';
+ }
+
+ if (this.dom.scrollFootTable.length) {
+ for (i = 0; i < footTableColumns.length; i++) {
+ footTableColumns[i].style.width = newWidths[i] + 'px';
}
- },
+ this.dom.scrollFootTable[0].style.width = tablesWidth;
+ this.dom.scrollFootInner[0].style.width = tablesWidth;
+ }
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Mouse drop and drag
- */
+ //console.log('moveLength: ' + moveLength + ' multiplier: ' + tot);
+ //console.log(newWidths);
+ this.dom.table.preWidth = newTableWidth;
+
+ //Call afterResizing function after the window stops resizing
+ if (this.dom.winResizeTimer)
+ clearTimeout(this.dom.winResizeTimer);
+ this.dom.winResizeTimer = setTimeout(function () {
+ _this.afterResizing();
+ _this.dom.winResizeTimer = null;
+ }, delay);
+ };
- "_fnSetupMouseListeners":function() {
- var that = this;
- $(that.s.dt.nTableWrapper).off("mouseenter.ColResize").on("mouseenter.ColResize","th",function(e) {
- e.preventDefault();
- that._fnMouseEnter.call(that, e, this);
- });
- $(that.s.dt.nTableWrapper).off("mouseleave.ColResize").on("mouseleave.ColResize","th",function(e) {
- e.preventDefault();
- that._fnMouseLeave.call(that, e, this);
- });
- },
-
- /**
- * Add mouse listeners to the resize handle on TH element
- * @method _fnMouseListener
- * @param i Column index
- * @param nTh TH resize handle element clicked on
- * @returns void
- * @private
- */
- "_fnMouseListener": function (i, nTh) {
- var that = this;
- $(nTh).off('mouseenter.ColResize').on('mouseenter.ColResize', function (e) {
- e.preventDefault();
- that._fnMouseEnter.call(that, e, nTh);
- });
- $(nTh).off('mouseleave.ColResize').on('mouseleave.ColResize', function (e) {
- e.preventDefault();
- that._fnMouseLeave.call(that, e, nTh);
- });
- },
-
- /**
- *
- * @param e Mouse event
- * @param nTh TH element that the mouse is over
- */
- "_fnMouseEnter": function (e, nTh) {
- var that = this;
- if(!that.s.isMousedown) {
- //Once the mouse has entered the cell add mouse move event to see if the mouse is over resize handle
- $(nTh).off('mousemove.ColResizeHandle').on('mousemove.ColResizeHandle', function (e) {
- e.preventDefault();
- that._fnResizeHandleCheck.call(that, e, nTh);
- });
+ ColResize.prototype.getColumnIndex = function (col) {
+ //Get the current column position
+ var colIdx = -1;
+ for (var i = 0; i < this.dt.settings.aoColumns.length; i++) {
+ if (this.dt.settings.aoColumns[i] === col) {
+ colIdx = i;
+ break;
}
- },
-
- /**
- * Clear mouse events when the mouse has left the th
- * @param e Mouse event
- * @param nTh TH element that the mouse has just left
- */
- "_fnMouseLeave": function (e, nTh) {
- //Once the mouse has left the TH make suure to remove the mouse move listener
- $(nTh).off('mousemove.ColResizeHandle');
- },
-
- /**
- * Mouse down on a TH element in the table header
- * @method _fnMouseDown
- * @param event e Mouse event
- * @param element nTh TH element to be resized
- * @returns void
- * @private
- */
- "_fnMouseDown": function (e, nTh) {
- var that = this;
-
- that.s.isMousedown = true;
+ }
+ return colIdx;
+ };
- /* Store information about the mouse position */
- var target = $(e.target).closest('th, td');
- var offset = target.offset();
-
- /* Store information about the mouse position for resize calculations in mouse move function */
- this.s.mouse.startX = e.pageX;
- this.s.mouse.startY = e.pageY;
-
- //Store the indexes of the columns the mouse is down on
- var idx = that.dom.resizeCol[0].cellIndex;
-
- // the last column has no 'right-side' neighbour
- // with fixed this can make the table smaller
- if (that.dom.resizeColNeighbour[0] === undefined){
- var idxNeighbour = 0;
+ ColResize.prototype.getColumnEvent = function (th, type, ns) {
+ var event;
+ var thEvents = this.$._data(th, "events");
+ this.$.each(thEvents[type] || [], function (idx, handler) {
+ if (handler.namespace === ns)
+ event = handler;
+ });
+ return event;
+ };
+
+ ColResize.prototype.loadState = function (data) {
+ var _this = this;
+ var i, col;
+
+ var onInit = function () {
+ if (_this.settings.fixedLayout) {
+ _this.setTablesLayout('fixed');
} else {
- var idxNeighbour = that.dom.resizeColNeighbour[0].cellIndex;
+ _this.setTablesLayout('auto');
}
-
-
+ if (!data.colResize) {
+ if (_this.dt.settings.oFeatures.bAutoWidthOrig)
+ _this.dt.settings.oFeatures.bAutoWidth = true;
+ else if (_this.dt.settings.sTableWidthOrig)
+ _this.$(_this.dt.settings.nTable).width(_this.dt.settings.sTableWidthOrig);
+
+ for (i = 0; i < _this.dt.settings.aoColumns.length; i++) {
+ col = _this.dt.settings.aoColumns[i];
+ if (col._ColResize_sWidthOrig) {
+ col.sWidthOrig = col._ColResize_sWidthOrig;
+ }
+ }
+ _this.dom.origState = true;
+ } else {
+ var columns = data.colResize.columns || [];
+ var wMap = {};
- if (idx === undefined) {
- return;
- }
+ if (_this.dt.settings.oFeatures.bAutoWidth) {
+ _this.dt.settings.oFeatures.bAutoWidth = false;
+ }
- this.s.mouse.targetIndex = idx;
- this.s.mouse.targetColumn = this.s.dt.aoColumns[ idx ];
-
- this.s.mouse.neighbourIndex = idxNeighbour;
- this.s.mouse.neighbourColumn = this.s.dt.aoColumns[ idxNeighbour ];
-
- /* Add event handlers to the document */
- $(document)
- .off('mousemove.ColResize').on('mousemove.ColResize', function (e) {
- that._fnMouseMove.call(that, e);
- })
- .off('mouseup.ColResize').on('mouseup.ColResize', function (e) {
- that._fnMouseUp.call(that, e);
- });
- },
-
- /**
- * Deal with a mouse move event while dragging to resize a column
- * @method _fnMouseMove
- * @param e Mouse event
- * @returns void
- * @private
- */
- "_fnMouseMove": function (e) {
- var that = this;
-
- var offset = $(that.s.mouse.targetColumn.nTh).offset();
- var relativeX = (e.pageX - offset.left);
- var distFromLeft = relativeX;
- var distFromRight = $(that.s.mouse.targetColumn.nTh).outerWidth() - relativeX - 1;
-
- //Change in mouse x position
- var dx = e.pageX - that.s.mouse.startX;
- //Get the minimum width of the column (default minimum 10px)
- var minColumnWidth = Math.max(parseInt($(that.s.mouse.targetColumn.nTh).css('min-width')), 10);
- //Store the previous width of the column
- var prevWidth = $(that.s.mouse.targetColumn.nTh).width();
- //As long as the cursor is past the handle, resize the columns
- if ((dx > 0 && distFromRight <= 0) || (dx < 0 && distFromRight >= 0)) {
- if (!that.s.init.tableWidthFixed) {
- //As long as the width is larger than the minimum
- var newColWidth = Math.max(minColumnWidth, prevWidth + dx);
- //Get the width difference (take into account the columns minimum width)
- var widthDiff = newColWidth - prevWidth;
- var colResizeIdx = parseInt(that.dom.resizeCol.attr("data-column-index"));
- //Set datatable column widths
- that.s.mouse.targetColumn.sWidthOrig = that.s.mouse.targetColumn.sWidth = that.s.mouse.targetColumn.width = newColWidth + "px";
- var domCols = $(that.s.dt.nTableWrapper).find("th[data-column-index='"+colResizeIdx+"']");
- //For each table expand the width by the same amount as the column
- //This accounts for other datatable plugins like FixedColumns
- domCols.parents("table").each(function() {
- if(!$(this).parent().hasClass("DTFC_LeftBodyLiner")) {
- var newWidth = $(this).width() + widthDiff;
- $(this).width(newWidth);
- } else {
- var newWidth =$(that.s.dt.nTableWrapper).find(".DTFC_LeftHeadWrapper").children("table").width();
- $(this).parents(".DTFC_LeftWrapper").width(newWidth);
- $(this).parent().width(newWidth+15);
- $(this).width(newWidth);
- }
- });
- //Apply the new width to the columns after the table has been resized
- domCols.width(that.s.mouse.targetColumn.width);
- } else {
- //A neighbour column must exist in order to resize a column in a table with a fixed width
- if (that.s.mouse.neighbourColumn) {
- //Get the minimum width of the neighbor column (default minimum 10px)
- var minColumnNeighbourWidth = Math.max(parseInt($(that.s.mouse.neighbourColumn.nTh).css('min-width')), 10);
- //Store the previous width of the neighbour column
- var prevNeighbourWidth = $(that.s.mouse.neighbourColumn.nTh).width();
- //As long as the width is larger than the minimum
- var newColWidth = Math.max(minColumnWidth, prevWidth + dx);
- var newColNeighbourWidth = Math.max(minColumnNeighbourWidth, prevNeighbourWidth - dx);
- //Get the width difference (take into account the columns minimum width)
- var widthDiff = newColWidth - prevWidth;
- var widthDiffNeighbour = newColNeighbourWidth - prevNeighbourWidth;
- //Get the column index for the column being changed
- var colResizeIdx = parseInt(that.dom.resizeCol.attr("data-column-index"));
- var neighbourColResizeIdx = parseInt(that.dom.resizeColNeighbour.attr("data-column-index"));
- //Set datatable column widths
- that.s.mouse.neighbourColumn.sWidthOrig = that.s.mouse.neighbourColumn.sWidth = that.s.mouse.neighbourColumn.width = newColNeighbourWidth + "px";
- that.s.mouse.targetColumn.sWidthOrig = that.s.mouse.targetColumn.sWidth = that.s.mouse.targetColumn.width = newColWidth + "px";
- //Get list of columns based on column index in all affected tables tables. This accounts for other plugins like FixedColumns
- var domNeighbourCols = $(that.s.dt.nTableWrapper).find("th[data-column-index='" + neighbourColResizeIdx + "']");
- var domCols = $(that.s.dt.nTableWrapper).find("th[data-column-index='" + colResizeIdx + "']");
- //If dx if positive (the width is getting larger) shrink the neighbour columns first
- if(dx>0) {
- domNeighbourCols.width(that.s.mouse.neighbourColumn.width);
- domCols.width(that.s.mouse.targetColumn.width);
- } else {
- //Apply the new width to the columns then to the neighbour columns
- domCols.width(that.s.mouse.targetColumn.width);
- domNeighbourCols.width(that.s.mouse.neighbourColumn.width);
- }
- }
+ if (_this.dom.scrollX && data.colResize.tableSize > 0) {
+ _this.dom.scrollHeadTable.width(data.colResize.tableSize);
+ _this.dom.scrollHeadInner.width(data.colResize.tableSize);
+ _this.dom.scrollBodyTable.width(data.colResize.tableSize);
+ _this.dom.scrollFootTable.width(data.colResize.tableSize);
}
- }
- that.s.mouse.startX = e.pageX;
- },
-
- /**
- * Check to see if the mouse is over the resize handle area
- * @param e
- * @param nTh
- */
- "_fnResizeHandleCheck": function (e, nTh) {
- var that = this;
-
- var offset = $(nTh).offset();
- var relativeX = (e.pageX - offset.left);
- var relativeY = (e.pageY - offset.top);
- var distFromLeft = relativeX;
- var distFromRight = $(nTh).outerWidth() - relativeX - 1;
-
- var handleBuffer = this.s.init.handleWidth / 2;
- var leftHandleOn = distFromLeft < handleBuffer;
- var rightHandleOn = distFromRight < handleBuffer;
-
- //If this is the first table cell
- if ($(nTh).prev("th").length == 0) {
- if(this.s.init.rtl)
- rightHandleOn = false;
- else
- leftHandleOn = false;
- }
- //If this is the last cell and the table is fixed width don't let them expand the last cell directly
- if ($(nTh).next("th").length == 0 && this.s.init.tableWidthFixed) {
- if(this.s.init.rtl)
- leftHandleOn = false;
- else
- rightHandleOn = false;
- }
- var resizeAvailable = leftHandleOn||rightHandleOn;
-
- //If table is in right to left mode flip which TH is being resized
- if (that.s.init.rtl) {
- //Handle is to the left
- if (leftHandleOn) {
- that.dom.resizeCol = $(nTh);
- that.dom.resizeColNeighbour = $(nTh).next();
- } else if (rightHandleOn) {
- that.dom.resizeCol = $(nTh).prev();
- that.dom.resizeColNeighbour = $(nTh);
+ for (i = 0; i < columns.length; i++) {
+ wMap[i] = columns[i];
}
- } else {
- //Handle is to the right
- if (rightHandleOn) {
- that.dom.resizeCol = $(nTh);
- that.dom.resizeColNeighbour = $(nTh).next();
- } else if (leftHandleOn) {
- that.dom.resizeCol = $(nTh).prev();
- that.dom.resizeColNeighbour = $(nTh);
+ for (i = 0; i < _this.dt.settings.aoColumns.length; i++) {
+ col = _this.dt.settings.aoColumns[i];
+ var idx = col._ColReorder_iOrigCol != null ? col._ColReorder_iOrigCol : i;
+ col.sWidth = wMap[idx];
+ col.sWidthOrig = wMap[idx];
+ col.nTh.style.width = columns[i];
+
+ //Check for FixedHeader
+ if (col.fhTh)
+ col.fhTh.style.width = columns[i];
+ if (col.fhTf)
+ col.fhTf.style.width = columns[i];
}
+ _this.dom.origState = false;
}
- //If table width is fixed make sure both columns are resizable else just check the one.
- if(this.s.init.tableWidthFixed)
- resizeAvailable &= this.s.init.exclude.indexOf(parseInt($(that.dom.resizeCol).attr("data-column-index"))) == -1 && this.s.init.exclude.indexOf(parseInt($(that.dom.resizeColNeighbour).attr("data-column-index"))) == -1;
- else
- resizeAvailable &= this.s.init.exclude.indexOf(parseInt($(that.dom.resizeCol).attr("data-column-index"))) == -1;
-
- $(nTh).off('mousedown.ColResize');
- if (resizeAvailable) {
- $(nTh).css("cursor", "ew-resize");
-
- //Delay other mousedown events from the Reorder plugin
- that._fnDelayEvents(null, nTh, "mousedown", "ColReorder");
- that._fnDelayEvents("click", nTh, "click", "DT");
-
- $(nTh).off('mousedown.ColResize').on('mousedown.ColResize', function (e) {
- e.preventDefault();
- that._fnMouseDown.call(that, e, nTh);
- })
- .off('click.ColResize').on('click.ColResize', function (e) {
- that._fnClick.call(that, e);
- });
- } else {
- $(nTh).css("cursor", "pointer");
- $(nTh).off('mousedown.ColResize click.ColResize');
- //Restore any events that were removed
- that._fnRestoreEvents();
- //This is to restore column sorting on click functionality
- if (!that.s.isMousedown)
- //Restore click event if mouse is not down
- this._fnRestoreEvents("click");
+ _this.dt.api.columns.adjust();
+ if (_this.dom.scrollX || _this.dom.scrollY)
+ _this.dt.api.draw(false);
+ };
+
+ if (this.initialized) {
+ onInit();
+ return;
+ }
+ this.dt.settings.oApi._fnCallbackReg(this.dt.settings, 'colResizeInitCompleted', function () {
+ onInit();
+ }, "ColResize_Init");
+ };
+
+ ColResize.prototype.saveState = function (data) {
+ if (!this.dt.settings._bInitComplete) {
+ var oData = this.dt.settings.fnStateLoadCallback.call(this.dt.settings.oInstance, this.dt.settings);
+ if (oData && oData.colResize)
+ data.colResize = oData.colResize;
+ return;
+ }
+ this.updateTableSize();
+ data.colResize = {
+ columns: [],
+ tableSize: this.tableSize
+ };
+
+ data.colResize.columns.length = this.dt.settings.aoColumns.length;
+ for (var i = 0; i < this.dt.settings.aoColumns.length; i++) {
+ var col = this.dt.settings.aoColumns[i];
+ var idx = col._ColReorder_iOrigCol != null ? col._ColReorder_iOrigCol : i;
+ data.colResize.columns[idx] = col.sWidth;
+ }
+ };
+
+ ColResize.prototype.registerCallbacks = function () {
+ var _this = this;
+ /* State saving */
+ this.dt.settings.oApi._fnCallbackReg(this.dt.settings, 'aoStateSaveParams', function (oS, oData) {
+ _this.saveState(oData);
+ }, "ColResize_StateSave");
+
+ /* State loading */
+ this.dt.settings.oApi._fnCallbackReg(this.dt.settings, 'aoStateLoaded', function (oS, oData) {
+ _this.loadState(oData);
+ }, "ColResize_StateLoad");
+
+ if (this.$.fn.DataTable.models.oSettings.remoteStateInitCompleted !== undefined) {
+ //Integrate with remote state
+ this.dt.settings.oApi._fnCallbackReg(this.dt.settings, 'remoteStateLoadedParams', function (s, data) {
+ _this.loadState(data);
+ }, "ColResize_StateLoad");
+ this.dt.settings.oApi._fnCallbackReg(this.dt.settings, 'remoteStateSaveParams', function (s, data) {
+ _this.saveState(data);
+ }, "ColResize_StateSave");
+ }
+ };
+
+ ColResize.prototype.setTablesLayout = function (value) {
+ if (this.dom.scrollX || this.dom.scrollY) {
+ this.dom.scrollHeadTable.css('table-layout', value);
+ this.dom.scrollBodyTable.css('table-layout', value);
+ this.dom.scrollFootTable.css('table-layout', value);
+ } else {
+ this.$(this.dt.settings.nTable).css('table-layout', value);
+ }
+ this.dom.fixedLayout = value == 'fixed';
+ };
+
+ //only when scrollX or scrollY are enabled
+ ColResize.prototype.fixFootAndHeadTables = function (e) {
+ var _this = this;
+ if (e != null && e.target !== this.dt.settings.nTable)
+ return;
+
+ if (this.dom.scrollFootTable.length) {
+ this.$('thead', this.dom.scrollFootTable).remove();
+ this.dom.scrollFootTable.prepend(this.$('thead', this.dom.scrollBodyTable).clone());
+ }
+ this.$('tfoot', this.dom.scrollHeadTable).remove();
+ this.dom.scrollHeadTable.append(this.$('tfoot', this.dom.scrollBodyTable).clone());
+ var removeFooterWidth = function (table) {
+ _this.$('tfoot>tr>th', table).each(function (i, th) {
+ _this.$(th).css('width', '');
+ });
+ };
+
+ //Remove all tfoot headers widths
+ removeFooterWidth(this.dom.scrollFootTable);
+ removeFooterWidth(this.dom.scrollBodyTable);
+ removeFooterWidth(this.dom.scrollHeadTable);
+ };
+
+ ColResize.prototype.onDraw = function (e) {
+ if (e != null && e.target !== this.dt.settings.nTable)
+ return;
+ if (this.dom.scrollX || this.dom.scrollY) {
+ this.fixFootAndHeadTables();
+
+ //Fix the header table padding
+ if (this.dt.settings._bInitComplete) {
+ var borderWidth = this.dom.scrollHeadTable.outerWidth() - this.dom.scrollHeadTable.innerWidth();
+ var paddingType = this.dt.settings.oBrowser.bScrollbarLeft ? 'padding-left' : 'padding-right';
+ var paddingVal = parseFloat(this.dom.scrollHeadInner.css(paddingType));
+ this.dom.scrollHeadInner.css(paddingType, (paddingVal + borderWidth) + 'px');
}
- },
-
- "_fnClick": function (e) {
- var that = this;
- that.s.isMousedown = false;
- e.stopImmediatePropagation();
- },
-
- /**
- * Finish off the mouse drag
- * @method _fnMouseUp
- * @param e Mouse event
- * @returns void
- * @private
- */
- "_fnMouseUp": function (e) {
- var that = this;
- that.s.isMousedown = false;
-
- //Fix width of column to be the size the dom is limited to (for when user sets min-width on a column)
- that.s.mouse.targetColumn.width = that.dom.resizeCol.width();
-
- $(document).off('mousemove.ColResize mouseup.ColResize');
- this.s.dt.oInstance.fnAdjustColumnSizing();
- //Table width fix, prevents extra gaps between tables
- var LeftWrapper = $(that.s.dt.nTableWrapper).find(".DTFC_LeftWrapper");
- var DTFC_LeftWidth = LeftWrapper.width();
- LeftWrapper.children(".DTFC_LeftHeadWrapper").children("table").width(DTFC_LeftWidth);
-
- if (that.s.init.resizeCallback) {
- that.s.init.resizeCallback.call(that, that.s.mouse.targetColumn);
+ }
+
+ var autoWidthTypes = [];
+ if (this.settings.dblClick == 'autoMinFit' || !this.settings.fixedLayout)
+ autoWidthTypes.push('autoMinWidth');
+ if (this.settings.dblClick == 'autoFit')
+ autoWidthTypes.push('autoWidth');
+
+ //Call this only once so that the table will be cloned only one time
+ if (autoWidthTypes.length)
+ this.updateColumnsAutoWidth(autoWidthTypes);
+
+ if (!this.settings.fixedLayout) {
+ var columns = this.dt.settings.aoColumns;
+ var i;
+ for (i = 0; i < columns.length; i++) {
+ if (!columns[i].bVisible)
+ continue;
+ columns[i].minWidth = Math.max((columns[i].minWidthOrig || 0), columns[i].autoMinWidth);
+
+ //We have to resize if the current column width if is less that the column minWidth
+ if (this.$(columns[i].nTh).width() < columns[i].minWidth)
+ this.resize(columns[i], columns[i].minWidth);
+ }
+ } else {
+ if (!this.dom.fixedLayout) {
+ this.setTablesLayout('fixed');
+ this.afterResizing();
}
- },
-
- /**
- * Clean up ColResize memory references and event handlers
- * @method _fnDestroy
- * @returns void
- * @private
- */
- "_fnDestroy": function () {
- var i, iLen;
-
- for (i = 0, iLen = this.s.dt.aoDrawCallback.length; i < iLen; i++) {
- if (this.s.dt.aoDrawCallback[i].sName === 'ColResize_Pre') {
- this.s.dt.aoDrawCallback.splice(i, 1);
+ }
+ };
+
+ ColResize.prototype.getTableAutoColWidths = function (table, types) {
+ var widths = {}, i, colIdx;
+ var $table = this.$(table);
+ for (i = 0; i < types.length; i++) {
+ widths[types[i]] = [];
+ }
+ if (!types.length || !$table.length)
+ return widths;
+
+ var clnTable = $table.clone().removeAttr('id').css('table-layout', 'auto');
+
+ // Remove any assigned widths from the footer (from scrolling)
+ clnTable.find('thead th, tfoot th, tfoot td').css('width', '');
+ var container = this.$('<div />').css({
+ 'position': 'absolute',
+ 'width': '9999px',
+ 'height': '9999px'
+ });
+ container.append(clnTable);
+ this.$(this.dt.settings.nTableWrapper).append(container);
+
+ var headerCols = this.$('thead>tr>th', clnTable);
+
+ for (i = 0; i < types.length; i++) {
+ var type = types[i];
+ var fn = '';
+ switch (type) {
+ case 'autoMinWidth':
+ clnTable.css('width', '1px');
+ fn = 'width';
break;
+ case 'autoWidth':
+ clnTable.css('width', 'auto');
+ fn = 'outerWidth';
+ break;
+ default:
+ throw 'Invalid widthType ' + type;
+ }
+ for (colIdx = 0; colIdx < headerCols.length; colIdx++) {
+ widths[type].push(this.$(headerCols[colIdx])[fn]());
+ }
+ }
+
+ container.remove();
+ return widths;
+ };
+
+ ColResize.prototype.updateColumnsAutoWidth = function (types) {
+ var columns = this.dt.settings.aoColumns;
+ var i, j, colLen, type, visColIdx = 0;
+ var widths = {};
+ if (this.dom.scrollX || this.dom.scrollY) {
+ var headWidths = this.getTableAutoColWidths(this.dom.scrollHeadTable, types);
+ var bodyWidths = this.getTableAutoColWidths(this.dom.scrollBodyTable, types);
+ var footWidths = this.getTableAutoColWidths(this.dom.scrollFootTable, types);
+
+ for (i = 0; i < types.length; i++) {
+ type = types[i];
+ widths[type] = [];
+ footWidths[type].length = headWidths[type].length;
+ colLen = headWidths[type].length;
+ for (j = 0; j < colLen; j++) {
+ widths[type].push(Math.max(headWidths[type][j], bodyWidths[type][j], (footWidths[type][j] || 0)));
}
}
+ } else {
+ widths = this.getTableAutoColWidths(this.dt.settings.nTable, types);
+ }
+
+ for (i = 0; i < columns.length; i++) {
+ if (!columns[i].bVisible)
+ continue;
+ for (j = 0; j < types.length; j++) {
+ type = types[j];
+ columns[i][type] = widths[type][visColIdx];
+ }
+ visColIdx++;
+ }
+ };
- $(this.s.dt.nTHead).find('*').off('.ColResize');
+ ColResize.prototype.overrideClickHander = function (col, $th) {
+ var dtClickEvent = this.getColumnEvent($th.get(0), 'click', 'DT');
- $.each(this.s.dt.aoColumns, function (i, column) {
- $(column.nTh).removeAttr('data-column-index');
+ //Remove the DataTables event so that ordering will not occur
+ if (dtClickEvent) {
+ $th.off('click.DT');
+ this.$(document).one('click.ColResize', function (e) {
+ $th.on('click.DT', dtClickEvent.handler);
});
+ }
+ };
- this.s.dt._colResize = null;
- this.s = null;
- },
+ ColResize.prototype.onDblClick = function (e, $th, col) {
+ if (e.target !== $th.get(0))
+ return;
+ if ($th.css('cursor') != 'col-resize')
+ return;
+
+ var width;
+ switch (this.settings.dblClick) {
+ case 'autoMinFit':
+ width = col.autoMinWidth;
+ break;
+ case 'autoFit':
+ width = col.autoWidth;
+ break;
+ default:
+ width = col.initWidth;
+ }
+ this.resize(col, width);
+ };
+ ColResize.prototype.onMouseDown = function (e, col) {
+ var _this = this;
+ if (e.target !== col.nTh && e.target !== col.fhTh)
+ return true;
- /**
- * Add a data attribute to the column headers, so we know the index of
- * the row to be reordered. This allows fast detection of the index, and
- * for this plug-in to work with FixedHeader which clones the nodes.
- * @private
- */
- "_fnSetColumnIndexes": function () {
- $.each(this.s.dt.aoColumns, function (i, column) {
- $(column.nTh).attr('data-column-index', i);
- });
+ var $th = e.target === col.nTh ? this.$(col.nTh) : this.$(col.fhTh);
+
+ if ($th.css('cursor') != 'col-resize' || col.resizable === false) {
+ var colReorder = this.dt.settings._colReorder;
+ if (colReorder) {
+ colReorder._fnMouseDown.call(colReorder, e, e.target); //Here we fix the e.preventDefault() in ColReorder so that we can have working inputs in header
+ }
+ return true;
+ }
+ this.dom.mouse.startX = e.pageX;
+ this.dom.mouse.prevX = e.pageX;
+ this.dom.mouse.startWidth = $th.width();
+ this.dom.resize = true;
+
+ this.beforeResizing(col);
+
+ /* Add event handlers to the document */
+ this.$(document).on('mousemove.ColResize', function (event) {
+ _this.onMouseMove(event, col);
+ });
+ this.overrideClickHander(col, $th);
+ this.$(document).one('mouseup.ColResize', function (event) {
+ _this.onMouseUp(event, col);
+ });
+
+ return false;
+ };
+
+ ColResize.prototype.resize = function (col, width) {
+ var colWidth = this.$(col.nTh).width();
+ var moveLength = width - this.$(col.nTh).width();
+ this.beforeResizing(col);
+ var resized = this.resizeColumn(col, colWidth, moveLength, moveLength);
+ this.afterResizing();
+ return resized;
+ };
+
+ ColResize.prototype.beforeResizing = function (col) {
+ //if (this.settings.fixedLayout && !this.dom.fixedLayout)
+ // this.setTablesLayout('fixed');
+ };
+
+ ColResize.prototype.afterResizing = function () {
+ var i;
+ var columns = this.dt.settings.aoColumns;
+ for (i = 0; i < columns.length; i++) {
+ if (!columns[i].bVisible)
+ continue;
+ columns[i].sWidth = this.$(columns[i].nTh).css('width');
}
+
+ //Update the internal storage of the table's width (in case we changed it because the user resized some column and scrollX was enabled
+ this.updateTableSize();
+
+ //Save the state
+ this.dt.settings.oInstance.oApi._fnSaveState(this.dt.settings);
+ this.dom.origState = false;
};
+ ColResize.prototype.onMouseUp = function (e, col) {
+ this.$(document).off('mousemove.ColResize');
+ if (!this.dom.resize)
+ return;
+ this.dom.resize = false;
+ this.afterResizing();
+ };
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Static parameters
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-
- /**
- * ColResize default settings for initialisation
- * @namespace
- * @static
- */
- ColResize.defaults = {
- /**
- * Callback function that is fired when columns are resized
- * @type function():void
- * @default null
- * @static
- */
- "resizeCallback": null,
-
- /**
- * Exclude array for columns that are not resizable
- * @property exclude
- * @type array of indexes that are excluded from resizing
- * @default []
- */
- "exclude": [],
-
- /**
- * Check to see if user is using a fixed table width or dynamic
- * if true:
- * -Columns will resize themselves and their neighbour
- * -If neighbour is excluded resize will not occur
- * if false:
- * -Columns will resize themselves and increase or decrease the width of the table accordingly
- */
- "tableWidthFixed": true,
-
- /**
- * Width of the resize handle in pixels
- * @property handleWidth
- * @type int (pixels)
- * @default 10
- */
- "handleWidth": 10,
-
- /**
- * Right to left support, when true flips which column they are resizing on mouse down
- * @property rtl
- * @type bool
- * @default false
- */
- "rtl": false
- };
-
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Constants
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /**
- * ColResize version
- * @constant version
- * @type String
- * @default As code
- */
- ColResize.version = "0.0.10";
-
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DataTables interfaces
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- // Expose
- $.fn.dataTable.ColResize = ColResize;
- $.fn.DataTable.ColResize = ColResize;
-
-
- // Register a new feature with DataTables
- if (typeof $.fn.dataTable == "function" &&
- typeof $.fn.dataTableExt.fnVersionCheck == "function" &&
- $.fn.dataTableExt.fnVersionCheck('1.9.3')) {
- $.fn.dataTableExt.aoFeatures.push({
- "fnInit": function (settings) {
- var table = settings.oInstance;
-
- if (!settings._colResize) {
- var dtInit = settings.oInit;
- var opts = dtInit.colResize || dtInit.oColResize || {};
-
- new ColResize(settings, opts);
- }
- else {
- table.oApi._fnLog(settings, 1, "ColResize attempted to initialise twice. Ignoring second");
+ ColResize.prototype.canResizeColumn = function (col, newWidth) {
+ return (col.resizable === undefined || col.resizable) && this.settings.minWidth <= newWidth && (!col.minWidth || col.minWidth <= newWidth) && (!this.settings.maxWidth || this.settings.maxWidth >= newWidth) && (!col.maxWidth || col.maxWidth >= newWidth);
+ };
+
+ ColResize.prototype.getColumnMaxWidth = function (col) {
+ return col.maxWidth ? col.maxWidth : this.settings.maxWidth;
+ };
+
+ ColResize.prototype.getColumnMinWidth = function (col) {
+ return col.minWidth ? col.minWidth : this.settings.minWidth;
+ };
+
+ ColResize.prototype.getPrevResizableColumnIdx = function (col, moveLength) {
+ var columns = this.dt.settings.aoColumns;
+ var colIdx = ColResizeHelper.indexOf(columns, col);
+ for (var i = colIdx; i >= 0; i--) {
+ if (!columns[i].bVisible)
+ continue;
+ var newWidth = this.$(columns[i].nTh).width() + moveLength;
+ if (this.canResizeColumn(columns[i], newWidth))
+ return i;
+ }
+ return -1;
+ };
+
+ ColResize.prototype.getNextResizableColumnIdx = function (col, moveLength) {
+ var columns = this.dt.settings.aoColumns;
+ var colIdx = ColResizeHelper.indexOf(columns, col);
+ for (var i = (colIdx + 1); i < columns.length; i++) {
+ if (!columns[i].bVisible)
+ continue;
+ var newWidth = this.$(columns[i].nTh).width() - moveLength;
+ if (this.canResizeColumn(columns[i], newWidth))
+ return i;
+ }
+ return -1;
+ };
+
+ ColResize.prototype.resizeColumn = function (col, startWidth, moveLength, lastMoveLength) {
+ if (moveLength == 0 || lastMoveLength == 0 || col.resizable === false)
+ return false;
+ var i;
+ var columns = this.dt.settings.aoColumns;
+ var headCol = this.$(col.nTh);
+ var headColNext = headCol.next();
+ var colIdx = this.getColumnIndex(col);
+ var thWidth = startWidth + moveLength;
+ var thNextWidth;
+ var nextColIdx;
+
+ if (!this.dom.scrollX) {
+ if (lastMoveLength < 0) {
+ thWidth = headColNext.width() - lastMoveLength;
+ nextColIdx = this.getPrevResizableColumnIdx(col, lastMoveLength);
+ if (nextColIdx < 0)
+ return false;
+ headCol = headColNext;
+ colIdx = colIdx + 1;
+ headColNext = this.$(columns[nextColIdx].nTh);
+ thNextWidth = headColNext.width() + lastMoveLength;
+ } else {
+ thWidth = headCol.width() + lastMoveLength;
+ nextColIdx = this.getNextResizableColumnIdx(col, lastMoveLength);
+
+ //If there is no columns that can be shrinked dont resize anymore
+ if (nextColIdx < 0)
+ return false;
+ headColNext = this.$(columns[nextColIdx].nTh);
+ thNextWidth = headColNext.width() - lastMoveLength;
+
+ if ((this.settings.maxWidth && this.settings.maxWidth < thWidth) || col.maxWidth && col.maxWidth < thWidth)
+ return false;
+ }
+ if (!this.canResizeColumn(columns[nextColIdx], thNextWidth) || !this.canResizeColumn(columns[colIdx], thWidth))
+ return false;
+ headColNext.width(thNextWidth);
+
+ //If fixed header is present we have to resize the cloned column too
+ if (this.dom.fixedHeader) {
+ this.$(columns[nextColIdx].fhTh).width(thNextWidth);
+ this.$(columns[colIdx].fhTh).width(thWidth);
+
+ //If fixedfooter was enabled resize that too
+ if (columns[nextColIdx].fhTf) {
+ this.$(columns[nextColIdx].fhTf).width(thNextWidth);
+ this.$(columns[colIdx].fhTf).width(thWidth);
}
+ }
+ } else {
+ if (!this.canResizeColumn(col, thWidth))
+ return false;
+ var tSize = this.tableSize + moveLength + 'px';
+ this.dom.scrollHeadInner.css('width', tSize);
+ this.dom.scrollHeadTable.css('width', tSize);
+ this.dom.scrollBodyTable.css('width', tSize);
+ this.dom.scrollFootTable.css('width', tSize);
+ }
+ headCol.width(thWidth);
+
+ //scrollX or scrollY enabled
+ if (this.dom.scrollBody.length) {
+ var colDomIdx = 0;
+ for (i = 0; i < this.dt.settings.aoColumns.length && i != colIdx; i++) {
+ if (this.dt.settings.aoColumns[i].bVisible)
+ colDomIdx++;
+ }
- return null;
- /* No node for DataTables to insert */
- },
- "cFeature": "Z",
- "sFeature": "ColResize"
- });
- } else {
- alert("Warning: ColResize requires DataTables 1.9.3 or greater - www.datatables.net/download");
- }
+ //Get the table
+ var bodyCol = this.$('thead>tr>th:nth(' + colDomIdx + ')', this.dom.scrollBodyTable);
+ var footCol = this.$('thead>tr>th:nth(' + colDomIdx + ')', this.dom.scrollFootTable);
+ //This will happen only when scrollY is used without scrollX
+ if (!this.dom.scrollX) {
+ var nextColDomIdx = 0;
+ for (i = 0; i < this.dt.settings.aoColumns.length && i != nextColIdx; i++) {
+ if (this.dt.settings.aoColumns[i].bVisible)
+ nextColDomIdx++;
+ }
+ var bodyColNext = this.$('thead>tr>th:nth(' + nextColDomIdx + ')', this.dom.scrollBodyTable);
+ var footColNext = this.$('thead>tr>th:nth(' + nextColDomIdx + ')', this.dom.scrollFootTable);
-// API augmentation
- if ($.fn.dataTable.Api) {
- $.fn.dataTable.Api.register('colResize.reset()', function () {
- return this.iterator('table', function (ctx) {
- ctx._colResize.fnReset();
- });
- });
- }
+ bodyColNext.width(thNextWidth);
+ if (thWidth > 0)
+ bodyCol.width(thWidth);
- return ColResize;
- }; // /factory
+ footColNext.width(thNextWidth);
+ if (thWidth > 0)
+ footCol.width(thWidth);
+ }
+ //Resize the table and the column
+ if (this.dom.scrollX && thWidth > 0) {
+ bodyCol.width(thWidth);
+ footCol.width(thWidth);
+ }
+ }
+ return true;
+ };
-// 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.ColResize) {
- // Otherwise simply initialise as normal, stopping multiple evaluation
- factory(jQuery, jQuery.fn.dataTable);
-}
+ ColResize.prototype.onMouseMove = function (e, col) {
+ var moveLength = e.pageX - this.dom.mouse.startX;
+ var lastMoveLength = e.pageX - this.dom.mouse.prevX;
+ this.resizeColumn(col, this.dom.mouse.startWidth, moveLength, lastMoveLength);
+ this.dom.mouse.prevX = e.pageX;
+ };
+ ColResize.prototype.destroy = function () {
+ };
+ ColResize.defaultSettings = {
+ minWidth: 1,
+ maxWidth: null,
+ fixedLayout: true,
+ fixedHeader: null,
+ dblClick: 'initWidth'
+ };
+ return ColResize;
+ })();
+ dt.ColResize = ColResize;
-})(window, document); \ No newline at end of file
+ var ColResizeHelper = (function () {
+ function ColResizeHelper() {
+ }
+ ColResizeHelper.indexOf = function (arr, item, equalFun) {
+ if (typeof equalFun === "undefined") { equalFun = null; }
+ for (var i = 0; i < arr.length; i++) {
+ if (equalFun) {
+ if (equalFun(arr[i], item))
+ return i;
+ } else if (arr[i] === item)
+ return i;
+ }
+ return -1;
+ };
+ return ColResizeHelper;
+ })();
+ dt.ColResizeHelper = ColResizeHelper;
+})(dt || (dt = {}));
+
+(function ($, window, document, undefined) {
+ //Register events
+ $.fn.DataTable.models.oSettings.colResizeInitCompleted = [];
+
+ //Register api function
+ $.fn.DataTable.Api.register('colResize.init()', function (settings) {
+ var colResize = new dt.ColResize($, this, settings);
+ if (this.settings()[0]._bInitComplete)
+ colResize.initialize();
+ else
+ this.one('init.dt', function () {
+ colResize.initialize();
+ });
+ return null;
+ });
+
+ $.fn.DataTable.Api.register('column().resize()', function (width) {
+ var oSettings = this.settings()[0];
+ var colResize = oSettings.colResize;
+ return colResize.resize(oSettings.aoColumns[this[0][0]], width);
+ });
+
+ //Add as feature
+ $.fn.dataTable.ext.feature.push({
+ "fnInit": function (oSettings) {
+ return oSettings.oInstance.api().colResize.init(oSettings.oInit.colResize);
+ },
+ "cFeature": "J",
+ "sFeature": "ColResize"
+ });
+}(jQuery, window, document, undefined)); \ No newline at end of file
diff --git a/wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.fixedHeader.css b/wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.fixedHeader.css
new file mode 100644
index 00000000..4001ab12
--- /dev/null
+++ b/wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.fixedHeader.css
@@ -0,0 +1,4 @@
+div.FixedHeader_Cloned th,
+div.FixedHeader_Cloned td {
+ background-color: white !important;
+}
diff --git a/wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.fixedHeader.js b/wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.fixedHeader.js
new file mode 100644
index 00000000..c1f962c4
--- /dev/null
+++ b/wqflask/wqflask/static/new/packages/DataTables/extensions/dataTables.fixedHeader.js
@@ -0,0 +1,1027 @@
+/*! FixedHeader 2.1.2
+ * ©2010-2014 SpryMedia Ltd - datatables.net/license
+ */
+
+/**
+ * @summary FixedHeader
+ * @description Fix a table's header or footer, so it is always visible while
+ * Scrolling
+ * @version 2.1.2
+ * @file dataTables.fixedHeader.js
+ * @author SpryMedia Ltd (www.sprymedia.co.uk)
+ * @contact www.sprymedia.co.uk/contact
+ * @copyright Copyright 2009-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
+ */
+
+/* Global scope for FixedColumns for backwards compatibility - will be removed
+ * in future. Not documented in 1.1.x.
+ */
+
+/* Global scope for FixedColumns */
+var FixedHeader;
+
+(function(window, document, undefined) {
+
+
+var factory = function( $, DataTable ) {
+"use strict";
+
+/*
+ * Function: FixedHeader
+ * Purpose: Provide 'fixed' header, footer and columns for a DataTable
+ * Returns: object:FixedHeader - must be called with 'new'
+ * Inputs: mixed:mTable - target table
+ * @param {object} dt DataTables instance or HTML table node. With DataTables
+ * 1.10 this can also be a jQuery collection (with just a single table in its
+ * result set), a jQuery selector, DataTables API instance or settings
+ * object.
+ * @param {object} [oInit] initialisation settings, with the following
+ * properties (each optional)
+ * * bool:top - fix the header (default true)
+ * * bool:bottom - fix the footer (default false)
+ * * int:left - fix the left column(s) (default 0)
+ * * int:right - fix the right column(s) (default 0)
+ * * int:zTop - fixed header zIndex
+ * * int:zBottom - fixed footer zIndex
+ * * int:zLeft - fixed left zIndex
+ * * int:zRight - fixed right zIndex
+ */
+FixedHeader = function ( mTable, oInit ) {
+ /* Sanity check - you just know it will happen */
+ if ( ! this instanceof FixedHeader )
+ {
+ alert( "FixedHeader warning: FixedHeader must be initialised with the 'new' keyword." );
+ return;
+ }
+
+ var that = this;
+ var oSettings = {
+ "aoCache": [],
+ "oSides": {
+ "top": true,
+ "bottom": false,
+ "left": 0,
+ "right": 0
+ },
+ "oZIndexes": {
+ "top": 104,
+ "bottom": 103,
+ "left": 102,
+ "right": 101
+ },
+ "oCloneOnDraw": {
+ "top": false,
+ "bottom": false,
+ "left": true,
+ "right": true
+ },
+ "oMes": {
+ "iTableWidth": 0,
+ "iTableHeight": 0,
+ "iTableLeft": 0,
+ "iTableRight": 0, /* note this is left+width, not actually "right" */
+ "iTableTop": 0,
+ "iTableBottom": 0 /* note this is top+height, not actually "bottom" */
+ },
+ "oOffset": {
+ "top": 0
+ },
+ "nTable": null,
+ "bFooter": false,
+ "bInitComplete": false
+ };
+
+ /*
+ * Function: fnGetSettings
+ * Purpose: Get the settings for this object
+ * Returns: object: - settings object
+ * Inputs: -
+ */
+ this.fnGetSettings = function () {
+ return oSettings;
+ };
+
+ /*
+ * Function: fnUpdate
+ * Purpose: Update the positioning and copies of the fixed elements
+ * Returns: -
+ * Inputs: -
+ */
+ this.fnUpdate = function () {
+ this._fnUpdateClones();
+ this._fnUpdatePositions();
+ };
+
+ /*
+ * Function: fnPosition
+ * Purpose: Update the positioning of the fixed elements
+ * Returns: -
+ * Inputs: -
+ */
+ this.fnPosition = function () {
+ this._fnUpdatePositions();
+ };
+
+
+ var dt = $.fn.dataTable.Api ?
+ new $.fn.dataTable.Api( mTable ).settings()[0] :
+ mTable.fnSettings();
+
+ dt._oPluginFixedHeader = this;
+
+ /* Let's do it */
+ this.fnInit( dt, oInit );
+
+};
+
+
+/*
+ * Variable: FixedHeader
+ * Purpose: Prototype for FixedHeader
+ * Scope: global
+ */
+FixedHeader.prototype = {
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Initialisation
+ */
+
+ /*
+ * Function: fnInit
+ * Purpose: The "constructor"
+ * Returns: -
+ * Inputs: {as FixedHeader function}
+ */
+ fnInit: function ( oDtSettings, oInit )
+ {
+ var s = this.fnGetSettings();
+ var that = this;
+
+ /* Record the user definable settings */
+ this.fnInitSettings( s, oInit );
+
+ if ( oDtSettings.oScroll.sX !== "" || oDtSettings.oScroll.sY !== "" )
+ {
+ alert( "FixedHeader 2 is not supported with DataTables' scrolling mode at this time" );
+ return;
+ }
+
+ s.nTable = oDtSettings.nTable;
+ oDtSettings.aoDrawCallback.unshift( {
+ "fn": function () {
+ FixedHeader.fnMeasure();
+ that._fnUpdateClones.call(that);
+ that._fnUpdatePositions.call(that);
+ },
+ "sName": "FixedHeader"
+ } );
+
+ s.bFooter = ($('>tfoot', s.nTable).length > 0) ? true : false;
+
+ /* Add the 'sides' that are fixed */
+ if ( s.oSides.top )
+ {
+ s.aoCache.push( that._fnCloneTable( "fixedHeader", "FixedHeader_Header", that._fnCloneThead ) );
+ }
+ if ( s.oSides.bottom )
+ {
+ s.aoCache.push( that._fnCloneTable( "fixedFooter", "FixedHeader_Footer", that._fnCloneTfoot ) );
+ }
+ if ( s.oSides.left )
+ {
+ s.aoCache.push( that._fnCloneTable( "fixedLeft", "FixedHeader_Left", that._fnCloneTLeft, s.oSides.left ) );
+ }
+ if ( s.oSides.right )
+ {
+ s.aoCache.push( that._fnCloneTable( "fixedRight", "FixedHeader_Right", that._fnCloneTRight, s.oSides.right ) );
+ }
+
+ /* Event listeners for window movement */
+ FixedHeader.afnScroll.push( function () {
+ that._fnUpdatePositions.call(that);
+ } );
+
+ $(window).resize( function () {
+ FixedHeader.fnMeasure();
+ that._fnUpdateClones.call(that);
+ that._fnUpdatePositions.call(that);
+ } );
+
+ $(s.nTable)
+ .on('column-reorder.dt', function () {
+ FixedHeader.fnMeasure();
+ that._fnUpdateClones( true );
+ that._fnUpdatePositions();
+ } )
+ .on('column-visibility.dt', function () {
+ FixedHeader.fnMeasure();
+ that._fnUpdateClones( true );
+ that._fnUpdatePositions();
+ } );
+
+ /* Get things right to start with */
+ FixedHeader.fnMeasure();
+ that._fnUpdateClones();
+ that._fnUpdatePositions();
+
+ s.bInitComplete = true;
+ },
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Support functions
+ */
+
+ /*
+ * Function: fnInitSettings
+ * Purpose: Take the user's settings and copy them to our local store
+ * Returns: -
+ * Inputs: object:s - the local settings object
+ * object:oInit - the user's settings object
+ */
+ fnInitSettings: function ( s, oInit )
+ {
+ if ( oInit !== undefined )
+ {
+ if ( oInit.top !== undefined ) {
+ s.oSides.top = oInit.top;
+ }
+ if ( oInit.bottom !== undefined ) {
+ s.oSides.bottom = oInit.bottom;
+ }
+ if ( typeof oInit.left == 'boolean' ) {
+ s.oSides.left = oInit.left ? 1 : 0;
+ }
+ else if ( oInit.left !== undefined ) {
+ s.oSides.left = oInit.left;
+ }
+ if ( typeof oInit.right == 'boolean' ) {
+ s.oSides.right = oInit.right ? 1 : 0;
+ }
+ else if ( oInit.right !== undefined ) {
+ s.oSides.right = oInit.right;
+ }
+
+ if ( oInit.zTop !== undefined ) {
+ s.oZIndexes.top = oInit.zTop;
+ }
+ if ( oInit.zBottom !== undefined ) {
+ s.oZIndexes.bottom = oInit.zBottom;
+ }
+ if ( oInit.zLeft !== undefined ) {
+ s.oZIndexes.left = oInit.zLeft;
+ }
+ if ( oInit.zRight !== undefined ) {
+ s.oZIndexes.right = oInit.zRight;
+ }
+
+ if ( oInit.offsetTop !== undefined ) {
+ s.oOffset.top = oInit.offsetTop;
+ }
+ if ( oInit.alwaysCloneTop !== undefined ) {
+ s.oCloneOnDraw.top = oInit.alwaysCloneTop;
+ }
+ if ( oInit.alwaysCloneBottom !== undefined ) {
+ s.oCloneOnDraw.bottom = oInit.alwaysCloneBottom;
+ }
+ if ( oInit.alwaysCloneLeft !== undefined ) {
+ s.oCloneOnDraw.left = oInit.alwaysCloneLeft;
+ }
+ if ( oInit.alwaysCloneRight !== undefined ) {
+ s.oCloneOnDraw.right = oInit.alwaysCloneRight;
+ }
+ }
+ },
+
+ /*
+ * Function: _fnCloneTable
+ * Purpose: Clone the table node and do basic initialisation
+ * Returns: -
+ * Inputs: -
+ */
+ _fnCloneTable: function ( sType, sClass, fnClone, iCells )
+ {
+ var s = this.fnGetSettings();
+ var nCTable;
+
+ /* We know that the table _MUST_ has a DIV wrapped around it, because this is simply how
+ * DataTables works. Therefore, we can set this to be relatively position (if it is not
+ * alreadu absolute, and use this as the base point for the cloned header
+ */
+ if ( $(s.nTable.parentNode).css('position') != "absolute" )
+ {
+ s.nTable.parentNode.style.position = "relative";
+ }
+
+ /* Just a shallow clone will do - we only want the table node */
+ nCTable = s.nTable.cloneNode( false );
+ nCTable.removeAttribute( 'id' );
+
+ var nDiv = document.createElement( 'div' );
+ nDiv.style.position = "absolute";
+ nDiv.style.top = "0px";
+ nDiv.style.left = "0px";
+ nDiv.className += " FixedHeader_Cloned "+sType+" "+sClass;
+
+ /* Set the zIndexes */
+ if ( sType == "fixedHeader" )
+ {
+ nDiv.style.zIndex = s.oZIndexes.top;
+ }
+ if ( sType == "fixedFooter" )
+ {
+ nDiv.style.zIndex = s.oZIndexes.bottom;
+ }
+ if ( sType == "fixedLeft" )
+ {
+ nDiv.style.zIndex = s.oZIndexes.left;
+ }
+ else if ( sType == "fixedRight" )
+ {
+ nDiv.style.zIndex = s.oZIndexes.right;
+ }
+
+ /* remove margins since we are going to position it absolutely */
+ nCTable.style.margin = "0";
+
+ /* Insert the newly cloned table into the DOM, on top of the "real" header */
+ nDiv.appendChild( nCTable );
+ document.body.appendChild( nDiv );
+
+ return {
+ "nNode": nCTable,
+ "nWrapper": nDiv,
+ "sType": sType,
+ "sPosition": "",
+ "sTop": "",
+ "sLeft": "",
+ "fnClone": fnClone,
+ "iCells": iCells
+ };
+ },
+
+ /*
+ * Function: _fnMeasure
+ * Purpose: Get the current positioning of the table in the DOM
+ * Returns: -
+ * Inputs: -
+ */
+ _fnMeasure: function ()
+ {
+ var
+ s = this.fnGetSettings(),
+ m = s.oMes,
+ jqTable = $(s.nTable),
+ oOffset = jqTable.offset(),
+ iParentScrollTop = this._fnSumScroll( s.nTable.parentNode, 'scrollTop' ),
+ iParentScrollLeft = this._fnSumScroll( s.nTable.parentNode, 'scrollLeft' );
+
+ m.iTableWidth = jqTable.outerWidth();
+ m.iTableHeight = jqTable.outerHeight();
+ m.iTableLeft = oOffset.left + s.nTable.parentNode.scrollLeft;
+ m.iTableTop = oOffset.top + iParentScrollTop;
+ m.iTableRight = m.iTableLeft + m.iTableWidth;
+ m.iTableRight = FixedHeader.oDoc.iWidth - m.iTableLeft - m.iTableWidth;
+ m.iTableBottom = FixedHeader.oDoc.iHeight - m.iTableTop - m.iTableHeight;
+ },
+
+ /*
+ * Function: _fnSumScroll
+ * Purpose: Sum node parameters all the way to the top
+ * Returns: int: sum
+ * Inputs: node:n - node to consider
+ * string:side - scrollTop or scrollLeft
+ */
+ _fnSumScroll: function ( n, side )
+ {
+ var i = n[side];
+ while ( n = n.parentNode )
+ {
+ if ( n.nodeName == 'HTML' || n.nodeName == 'BODY' )
+ {
+ break;
+ }
+ i = n[side];
+ }
+ return i;
+ },
+
+ /*
+ * Function: _fnUpdatePositions
+ * Purpose: Loop over the fixed elements for this table and update their positions
+ * Returns: -
+ * Inputs: -
+ */
+ _fnUpdatePositions: function ()
+ {
+ var s = this.fnGetSettings();
+ this._fnMeasure();
+
+ for ( var i=0, iLen=s.aoCache.length ; i<iLen ; i++ )
+ {
+ if ( s.aoCache[i].sType == "fixedHeader" )
+ {
+ this._fnScrollFixedHeader( s.aoCache[i] );
+ }
+ else if ( s.aoCache[i].sType == "fixedFooter" )
+ {
+ this._fnScrollFixedFooter( s.aoCache[i] );
+ }
+ else if ( s.aoCache[i].sType == "fixedLeft" )
+ {
+ this._fnScrollHorizontalLeft( s.aoCache[i] );
+ }
+ else
+ {
+ this._fnScrollHorizontalRight( s.aoCache[i] );
+ }
+ }
+ },
+
+ /*
+ * Function: _fnUpdateClones
+ * Purpose: Loop over the fixed elements for this table and call their cloning functions
+ * Returns: -
+ * Inputs: -
+ */
+ _fnUpdateClones: function ( full )
+ {
+ var s = this.fnGetSettings();
+
+ if ( full ) {
+ // This is a little bit of a hack to force a full clone draw. When
+ // `full` is set to true, we want to reclone the source elements,
+ // regardless of the clone-on-draw settings
+ s.bInitComplete = false;
+ }
+
+ for ( var i=0, iLen=s.aoCache.length ; i<iLen ; i++ )
+ {
+ s.aoCache[i].fnClone.call( this, s.aoCache[i] );
+ }
+
+ if ( full ) {
+ s.bInitComplete = true;
+ }
+ },
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Scrolling functions
+ */
+
+ /*
+ * Function: _fnScrollHorizontalLeft
+ * Purpose: Update the positioning of the scrolling elements
+ * Returns: -
+ * Inputs: object:oCache - the cached values for this fixed element
+ */
+ _fnScrollHorizontalRight: function ( oCache )
+ {
+ var
+ s = this.fnGetSettings(),
+ oMes = s.oMes,
+ oWin = FixedHeader.oWin,
+ oDoc = FixedHeader.oDoc,
+ nTable = oCache.nWrapper,
+ iFixedWidth = $(nTable).outerWidth();
+
+ if ( oWin.iScrollRight < oMes.iTableRight )
+ {
+ /* Fully right aligned */
+ this._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );
+ this._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+"px", 'top', nTable.style );
+ this._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft+oMes.iTableWidth-iFixedWidth)+"px", 'left', nTable.style );
+ }
+ else if ( oMes.iTableLeft < oDoc.iWidth-oWin.iScrollRight-iFixedWidth )
+ {
+ /* Middle */
+ this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );
+ this._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop-oWin.iScrollTop)+"px", 'top', nTable.style );
+ this._fnUpdateCache( oCache, 'sLeft', (oWin.iWidth-iFixedWidth)+"px", 'left', nTable.style );
+ }
+ else
+ {
+ /* Fully left aligned */
+ this._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );
+ this._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+"px", 'top', nTable.style );
+ this._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+"px", 'left', nTable.style );
+ }
+ },
+
+ /*
+ * Function: _fnScrollHorizontalLeft
+ * Purpose: Update the positioning of the scrolling elements
+ * Returns: -
+ * Inputs: object:oCache - the cached values for this fixed element
+ */
+ _fnScrollHorizontalLeft: function ( oCache )
+ {
+ var
+ s = this.fnGetSettings(),
+ oMes = s.oMes,
+ oWin = FixedHeader.oWin,
+ oDoc = FixedHeader.oDoc,
+ nTable = oCache.nWrapper,
+ iCellWidth = $(nTable).outerWidth();
+
+ if ( oWin.iScrollLeft < oMes.iTableLeft )
+ {
+ /* Fully left align */
+ this._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );
+ this._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+"px", 'top', nTable.style );
+ this._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+"px", 'left', nTable.style );
+ }
+ else if ( oWin.iScrollLeft < oMes.iTableLeft+oMes.iTableWidth-iCellWidth )
+ {
+ this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );
+ this._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop-oWin.iScrollTop)+"px", 'top', nTable.style );
+ this._fnUpdateCache( oCache, 'sLeft', "0px", 'left', nTable.style );
+ }
+ else
+ {
+ /* Fully right align */
+ this._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );
+ this._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+"px", 'top', nTable.style );
+ this._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft+oMes.iTableWidth-iCellWidth)+"px", 'left', nTable.style );
+ }
+ },
+
+ /*
+ * Function: _fnScrollFixedFooter
+ * Purpose: Update the positioning of the scrolling elements
+ * Returns: -
+ * Inputs: object:oCache - the cached values for this fixed element
+ */
+ _fnScrollFixedFooter: function ( oCache )
+ {
+ var
+ s = this.fnGetSettings(),
+ oMes = s.oMes,
+ oWin = FixedHeader.oWin,
+ oDoc = FixedHeader.oDoc,
+ nTable = oCache.nWrapper,
+ iTheadHeight = $("thead", s.nTable).outerHeight(),
+ iCellHeight = $(nTable).outerHeight();
+
+ if ( oWin.iScrollBottom < oMes.iTableBottom )
+ {
+ /* Below */
+ this._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );
+ this._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop+oMes.iTableHeight-iCellHeight)+"px", 'top', nTable.style );
+ this._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+"px", 'left', nTable.style );
+ }
+ else if ( oWin.iScrollBottom < oMes.iTableBottom+oMes.iTableHeight-iCellHeight-iTheadHeight )
+ {
+ this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );
+ this._fnUpdateCache( oCache, 'sTop', (oWin.iHeight-iCellHeight)+"px", 'top', nTable.style );
+ this._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft-oWin.iScrollLeft)+"px", 'left', nTable.style );
+ }
+ else
+ {
+ /* Above */
+ this._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );
+ this._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop+iCellHeight)+"px", 'top', nTable.style );
+ this._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+"px", 'left', nTable.style );
+ }
+ },
+
+ /*
+ * Function: _fnScrollFixedHeader
+ * Purpose: Update the positioning of the scrolling elements
+ * Returns: -
+ * Inputs: object:oCache - the cached values for this fixed element
+ */
+ _fnScrollFixedHeader: function ( oCache )
+ {
+ var
+ s = this.fnGetSettings(),
+ oMes = s.oMes,
+ oWin = FixedHeader.oWin,
+ oDoc = FixedHeader.oDoc,
+ nTable = oCache.nWrapper,
+ iTbodyHeight = 0,
+ anTbodies = s.nTable.getElementsByTagName('tbody');
+
+ for (var i = 0; i < anTbodies.length; ++i) {
+ iTbodyHeight += anTbodies[i].offsetHeight;
+ }
+
+ if ( oMes.iTableTop > oWin.iScrollTop + s.oOffset.top )
+ {
+ /* Above the table */
+ this._fnUpdateCache( oCache, 'sPosition', "absolute", 'position', nTable.style );
+ this._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+"px", 'top', nTable.style );
+ this._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+"px", 'left', nTable.style );
+ }
+ else if ( oWin.iScrollTop + s.oOffset.top > oMes.iTableTop+iTbodyHeight )
+ {
+ /* At the bottom of the table */
+ this._fnUpdateCache( oCache, 'sPosition', "absolute", 'position', nTable.style );
+ this._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop+iTbodyHeight)+"px", 'top', nTable.style );
+ this._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+"px", 'left', nTable.style );
+ }
+ else
+ {
+ /* In the middle of the table */
+ this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );
+ this._fnUpdateCache( oCache, 'sTop', s.oOffset.top+"px", 'top', nTable.style );
+ this._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft-oWin.iScrollLeft)+"px", 'left', nTable.style );
+ }
+ },
+
+ /*
+ * Function: _fnUpdateCache
+ * Purpose: Check the cache and update cache and value if needed
+ * Returns: -
+ * Inputs: object:oCache - local cache object
+ * string:sCache - cache property
+ * string:sSet - value to set
+ * string:sProperty - object property to set
+ * object:oObj - object to update
+ */
+ _fnUpdateCache: function ( oCache, sCache, sSet, sProperty, oObj )
+ {
+ if ( oCache[sCache] != sSet )
+ {
+ oObj[sProperty] = sSet;
+ oCache[sCache] = sSet;
+ }
+ },
+
+
+
+ /**
+ * Copy the classes of all child nodes from one element to another. This implies
+ * that the two have identical structure - no error checking is performed to that
+ * fact.
+ * @param {element} source Node to copy classes from
+ * @param {element} dest Node to copy classes too
+ */
+ _fnClassUpdate: function ( source, dest )
+ {
+ var that = this;
+
+ if ( source.nodeName.toUpperCase() === "TR" || source.nodeName.toUpperCase() === "TH" ||
+ source.nodeName.toUpperCase() === "TD" || source.nodeName.toUpperCase() === "SPAN" )
+ {
+ dest.className = source.className;
+ }
+
+ $(source).children().each( function (i) {
+ that._fnClassUpdate( $(source).children()[i], $(dest).children()[i] );
+ } );
+ },
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Cloning functions
+ */
+
+ /*
+ * Function: _fnCloneThead
+ * Purpose: Clone the thead element
+ * Returns: -
+ * Inputs: object:oCache - the cached values for this fixed element
+ */
+ _fnCloneThead: function ( oCache )
+ {
+ var s = this.fnGetSettings();
+ var nTable = oCache.nNode;
+
+ if ( s.bInitComplete && !s.oCloneOnDraw.top )
+ {
+ this._fnClassUpdate( $('thead', s.nTable)[0], $('thead', nTable)[0] );
+ return;
+ }
+
+ /* Set the wrapper width to match that of the cloned table */
+ var iDtWidth = $(s.nTable).outerWidth();
+ oCache.nWrapper.style.width = iDtWidth+"px";
+ nTable.style.width = iDtWidth+"px";
+
+ /* Remove any children the cloned table has */
+ while ( nTable.childNodes.length > 0 )
+ {
+ $('thead th', nTable).unbind( 'click' );
+ nTable.removeChild( nTable.childNodes[0] );
+ }
+
+ /* Clone the DataTables header */
+ var nThead = $('thead', s.nTable).clone(true)[0];
+ nTable.appendChild( nThead );
+
+ /* Copy the widths across - apparently a clone isn't good enough for this */
+ var a = [];
+ var b = [];
+
+ $("thead>tr th", s.nTable).each( function (i) {
+ a.push( $(this).width() );
+ } );
+
+ $("thead>tr td", s.nTable).each( function (i) {
+ b.push( $(this).width() );
+ } );
+
+ $("thead>tr th", s.nTable).each( function (i) {
+ $("thead>tr th:eq("+i+")", nTable).width( a[i] );
+ $(this).width( a[i] );
+ } );
+
+ $("thead>tr td", s.nTable).each( function (i) {
+ $("thead>tr td:eq("+i+")", nTable).width( b[i] );
+ $(this).width( b[i] );
+ } );
+
+ // Stop DataTables 1.9 from putting a focus ring on the headers when
+ // clicked to sort
+ $('th.sorting, th.sorting_desc, th.sorting_asc', nTable).bind( 'click', function () {
+ this.blur();
+ } );
+ },
+
+ /*
+ * Function: _fnCloneTfoot
+ * Purpose: Clone the tfoot element
+ * Returns: -
+ * Inputs: object:oCache - the cached values for this fixed element
+ */
+ _fnCloneTfoot: function ( oCache )
+ {
+ var s = this.fnGetSettings();
+ var nTable = oCache.nNode;
+
+ /* Set the wrapper width to match that of the cloned table */
+ oCache.nWrapper.style.width = $(s.nTable).outerWidth()+"px";
+
+ /* Remove any children the cloned table has */
+ while ( nTable.childNodes.length > 0 )
+ {
+ nTable.removeChild( nTable.childNodes[0] );
+ }
+
+ /* Clone the DataTables footer */
+ var nTfoot = $('tfoot', s.nTable).clone(true)[0];
+ nTable.appendChild( nTfoot );
+
+ /* Copy the widths across - apparently a clone isn't good enough for this */
+ $("tfoot:eq(0)>tr th", s.nTable).each( function (i) {
+ $("tfoot:eq(0)>tr th:eq("+i+")", nTable).width( $(this).width() );
+ } );
+
+ $("tfoot:eq(0)>tr td", s.nTable).each( function (i) {
+ $("tfoot:eq(0)>tr td:eq("+i+")", nTable).width( $(this).width() );
+ } );
+ },
+
+ /*
+ * Function: _fnCloneTLeft
+ * Purpose: Clone the left column(s)
+ * Returns: -
+ * Inputs: object:oCache - the cached values for this fixed element
+ */
+ _fnCloneTLeft: function ( oCache )
+ {
+ var s = this.fnGetSettings();
+ var nTable = oCache.nNode;
+ var nBody = $('tbody', s.nTable)[0];
+
+ /* Remove any children the cloned table has */
+ while ( nTable.childNodes.length > 0 )
+ {
+ nTable.removeChild( nTable.childNodes[0] );
+ }
+
+ /* Is this the most efficient way to do this - it looks horrible... */
+ nTable.appendChild( $("thead", s.nTable).clone(true)[0] );
+ nTable.appendChild( $("tbody", s.nTable).clone(true)[0] );
+ if ( s.bFooter )
+ {
+ nTable.appendChild( $("tfoot", s.nTable).clone(true)[0] );
+ }
+
+ /* Remove unneeded cells */
+ var sSelector = 'gt(' + (oCache.iCells - 1) + ')';
+ $('thead tr', nTable).each( function (k) {
+ $('th:' + sSelector, this).remove();
+ } );
+
+ $('tfoot tr', nTable).each( function (k) {
+ $('th:' + sSelector, this).remove();
+ } );
+
+ $('tbody tr', nTable).each( function (k) {
+ $('td:' + sSelector, this).remove();
+ } );
+
+ this.fnEqualiseHeights( 'thead', nBody.parentNode, nTable );
+ this.fnEqualiseHeights( 'tbody', nBody.parentNode, nTable );
+ this.fnEqualiseHeights( 'tfoot', nBody.parentNode, nTable );
+
+ var iWidth = 0;
+ for (var i = 0; i < oCache.iCells; i++) {
+ iWidth += $('thead tr th:eq(' + i + ')', s.nTable).outerWidth();
+ }
+ nTable.style.width = iWidth+"px";
+ oCache.nWrapper.style.width = iWidth+"px";
+ },
+
+ /*
+ * Function: _fnCloneTRight
+ * Purpose: Clone the right most column(s)
+ * Returns: -
+ * Inputs: object:oCache - the cached values for this fixed element
+ */
+ _fnCloneTRight: function ( oCache )
+ {
+ var s = this.fnGetSettings();
+ var nBody = $('tbody', s.nTable)[0];
+ var nTable = oCache.nNode;
+ var iCols = $('tbody tr:eq(0) td', s.nTable).length;
+
+ /* Remove any children the cloned table has */
+ while ( nTable.childNodes.length > 0 )
+ {
+ nTable.removeChild( nTable.childNodes[0] );
+ }
+
+ /* Is this the most efficient way to do this - it looks horrible... */
+ nTable.appendChild( $("thead", s.nTable).clone(true)[0] );
+ nTable.appendChild( $("tbody", s.nTable).clone(true)[0] );
+ if ( s.bFooter )
+ {
+ nTable.appendChild( $("tfoot", s.nTable).clone(true)[0] );
+ }
+ $('thead tr th:lt('+(iCols-oCache.iCells)+')', nTable).remove();
+ $('tfoot tr th:lt('+(iCols-oCache.iCells)+')', nTable).remove();
+
+ /* Remove unneeded cells */
+ $('tbody tr', nTable).each( function (k) {
+ $('td:lt('+(iCols-oCache.iCells)+')', this).remove();
+ } );
+
+ this.fnEqualiseHeights( 'thead', nBody.parentNode, nTable );
+ this.fnEqualiseHeights( 'tbody', nBody.parentNode, nTable );
+ this.fnEqualiseHeights( 'tfoot', nBody.parentNode, nTable );
+
+ var iWidth = 0;
+ for (var i = 0; i < oCache.iCells; i++) {
+ iWidth += $('thead tr th:eq('+(iCols-1-i)+')', s.nTable).outerWidth();
+ }
+ nTable.style.width = iWidth+"px";
+ oCache.nWrapper.style.width = iWidth+"px";
+ },
+
+
+ /**
+ * Equalise the heights of the rows in a given table node in a cross browser way. Note that this
+ * is more or less lifted as is from FixedColumns
+ * @method fnEqualiseHeights
+ * @returns void
+ * @param {string} parent Node type - thead, tbody or tfoot
+ * @param {element} original Original node to take the heights from
+ * @param {element} clone Copy the heights to
+ * @private
+ */
+ "fnEqualiseHeights": function ( parent, original, clone )
+ {
+ var that = this;
+ var originals = $(parent +' tr', original);
+ var height;
+
+ $(parent+' tr', clone).each( function (k) {
+ height = originals.eq( k ).css('height');
+
+ // This is nasty :-(. IE has a sub-pixel error even when setting
+ // the height below (the Firefox fix) which causes the fixed column
+ // to go out of alignment. Need to add a pixel before the assignment
+ // Can this be feature detected? Not sure how...
+ if ( navigator.appName == 'Microsoft Internet Explorer' ) {
+ height = parseInt( height, 10 ) + 1;
+ }
+
+ $(this).css( 'height', height );
+
+ // For Firefox to work, we need to also set the height of the
+ // original row, to the value that we read from it! Otherwise there
+ // is a sub-pixel rounding error
+ originals.eq( k ).css( 'height', height );
+ } );
+ }
+};
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Static properties and methods
+ * We use these for speed! This information is common to all instances of FixedHeader, so no
+ * point if having them calculated and stored for each different instance.
+ */
+
+/*
+ * Variable: oWin
+ * Purpose: Store information about the window positioning
+ * Scope: FixedHeader
+ */
+FixedHeader.oWin = {
+ "iScrollTop": 0,
+ "iScrollRight": 0,
+ "iScrollBottom": 0,
+ "iScrollLeft": 0,
+ "iHeight": 0,
+ "iWidth": 0
+};
+
+/*
+ * Variable: oDoc
+ * Purpose: Store information about the document size
+ * Scope: FixedHeader
+ */
+FixedHeader.oDoc = {
+ "iHeight": 0,
+ "iWidth": 0
+};
+
+/*
+ * Variable: afnScroll
+ * Purpose: Array of functions that are to be used for the scrolling components
+ * Scope: FixedHeader
+ */
+FixedHeader.afnScroll = [];
+
+/*
+ * Function: fnMeasure
+ * Purpose: Update the measurements for the window and document
+ * Returns: -
+ * Inputs: -
+ */
+FixedHeader.fnMeasure = function ()
+{
+ var
+ jqWin = $(window),
+ jqDoc = $(document),
+ oWin = FixedHeader.oWin,
+ oDoc = FixedHeader.oDoc;
+
+ oDoc.iHeight = jqDoc.height();
+ oDoc.iWidth = jqDoc.width();
+
+ oWin.iHeight = jqWin.height();
+ oWin.iWidth = jqWin.width();
+ oWin.iScrollTop = jqWin.scrollTop();
+ oWin.iScrollLeft = jqWin.scrollLeft();
+ oWin.iScrollRight = oDoc.iWidth - oWin.iScrollLeft - oWin.iWidth;
+ oWin.iScrollBottom = oDoc.iHeight - oWin.iScrollTop - oWin.iHeight;
+};
+
+
+FixedHeader.version = "2.1.2";
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Global processing
+ */
+
+/*
+ * Just one 'scroll' event handler in FixedHeader, which calls the required components. This is
+ * done as an optimisation, to reduce calculation and proagation time
+ */
+$(window).scroll( function () {
+ FixedHeader.fnMeasure();
+
+ for ( var i=0, iLen=FixedHeader.afnScroll.length ; i<iLen ; i++ ) {
+ FixedHeader.afnScroll[i]();
+ }
+} );
+
+
+$.fn.dataTable.FixedHeader = FixedHeader;
+$.fn.DataTable.FixedHeader = FixedHeader;
+
+
+return FixedHeader;
+}; // /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.FixedHeader ) {
+ // Otherwise simply initialise as normal, stopping multiple evaluation
+ factory( jQuery, jQuery.fn.dataTable );
+}
+
+
+})(window, document);
diff --git a/wqflask/wqflask/templates/correlation_page.html b/wqflask/wqflask/templates/correlation_page.html
index b60b4ea9..d53f930d 100755
--- a/wqflask/wqflask/templates/correlation_page.html
+++ b/wqflask/wqflask/templates/correlation_page.html
@@ -144,6 +144,7 @@
<script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/jquery.dataTables.js"></script>
<script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/dataTables.naturalSort.js"></script>
<script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/extensions/dataTables.colResize.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/extensions/dataTables.colReorder.js"></script>
<script language="javascript" type="text/javascript" src="/static/packages/DT_bootstrap/DT_bootstrap.js"></script>
<script language="javascript" type="text/javascript" src="/static/packages/TableTools/media/js/TableTools.min.js"></script>
<script language="javascript" type="text/javascript" src="//cdn.datatables.net/fixedheader/2.1.2/js/dataTables.fixedHeader.min.js"></script>
@@ -228,15 +229,14 @@
{ "type": "natural" },
{ "type": "natural" }
],
- "sDom": "Ztir",
+ "sDom": "RJtir",
"iDisplayLength": -1,
"autoWidth": true,
"bLengthChange": true,
"bDeferRender": true,
"bSortClasses": false,
- "scrollY": "600px",
- "scrollX": true,
- "scrollCollapse": true,
+ "scrollY": "700px",
+ "scrollCollapse": false,
"colResize": {
"tableWidthFixed": false
},
@@ -257,15 +257,14 @@
{ "type": "natural" },
{ "type": "natural" }
],
- "sDom": "Ztir",
+ "sDom": "RJtir",
"iDisplayLength": -1,
"autoWidth": true,
"bLengthChange": true,
"bDeferRender": true,
"bSortClasses": false,
- "scrollY": "600px",
- "scrollX": true,
- "scrollCollapse": true,
+ "scrollY": "700px",
+ "scrollCollapse": false,
"colResize": {
"tableWidthFixed": false
},
@@ -281,15 +280,14 @@
{ "type": "natural" },
{ "type": "natural" }
],
- "sDom": "Ztir",
+ "sDom": "RJtir",
"iDisplayLength": -1,
"autoWidth": true,
"bLengthChange": true,
"bDeferRender": true,
"bSortClasses": false,
- "scrollY": "600px",
- "scrollX": true,
- "scrollCollapse": true,
+ "scrollY": "700px",
+ "scrollCollapse": false,
"colResize": {
"tableWidthFixed": false
},
@@ -298,11 +296,6 @@
{% endif %}
console.timeEnd("Creating table");
- var table = $('#corr_results').DataTable();
- //new $.fn.dataTable.FixedHeader( table );
- new $.fn.dataTable.FixedColumns( table );
-
-
});
</script>
{% endblock %}
diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html
index 1ae2a25a..7c8bdb1b 100755
--- a/wqflask/wqflask/templates/search_result_page.html
+++ b/wqflask/wqflask/templates/search_result_page.html
@@ -4,7 +4,7 @@
<link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/css/jquery.dataTables.css" />
<link rel="stylesheet" type="text/css" href="/static/packages/DT_bootstrap/DT_bootstrap.css" />
<link rel="stylesheet" type="text/css" href="/static/packages/TableTools/media/css/TableTools.css" />
- <link rel="stylesheet" type="text/css" href="//cdn.datatables.net/fixedheader/2.1.2/css/dataTables.fixedHeader.css" >
+ <link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/extensions/dataTables.fixedHeader.css" >
<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/fixedcolumns/3.0.4/css/dataTables.fixedColumns.css">
{% endblock %}
{% block content %}
@@ -47,7 +47,7 @@
<button class="btn btn-primary"><span class="glyphicon glyphicon-download"></span> Download Table</button>
<br />
<br />
- <table class="table table-hover table-striped" id='trait_table' {% if dataset.type == 'Geno' %} width="400px" style="float: left;"{% endif %}>
+ <table class="table table-hover table-striped" id='trait_table' {% if dataset.type == 'Geno' %}width="400px"{% endif %} style="float: left;">
<thead>
<tr>
{% for header in header_fields %}
@@ -119,11 +119,11 @@
<script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/jquery.dataTables.min.js"></script>
<script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/dataTables.naturalSort.js"></script>
<script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/extensions/dataTables.colResize.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/extensions/dataTables.colReorder.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/extensions/dataTables.fixedHeader.js"></script>
+ <script language="javascript" type="text/javascript" src="//cdn.datatables.net/fixedcolumns/3.0.4/js/dataTables.fixedColumns.min.js"></script>
<script language="javascript" type="text/javascript" src="/static/packages/DT_bootstrap/DT_bootstrap.js"></script>
<script language="javascript" type="text/javascript" src="/static/packages/TableTools/media/js/TableTools.min.js"></script>
- <script language="javascript" type="text/javascript" src="//cdn.datatables.net/fixedheader/2.1.2/js/dataTables.fixedHeader.min.js"></script>
- <script language="javascript" type="text/javascript" src="//cdn.datatables.net/fixedcolumns/3.0.4/js/dataTables.fixedColumns.min.js"></script>
-
<script type="text/javascript" charset="utf-8">
function getValue(x) {
@@ -173,28 +173,33 @@
console.time("Creating table");
{% if dataset.type == 'ProbeSet' %}
- $('#trait_table').dataTable( {
+ $('#trait_table').DataTable( {
"columns": [
{ "type": "natural" },
{ "type": "natural" },
{ "type": "natural" },
- { "type": "natural", "width": "35%"},
- { "type": "natural", "width": "15%"},
{ "type": "natural" },
- { "type": "natural", "width": "8%"},
- { "type": "natural", "width": "15%"},
- { "type": "natural", "width": "7%"}
+ { "type": "natural" },
+ { "type": "natural" },
+ { "type": "natural" },
+ { "type": "natural" },
+ { "type": "natural" }
],
- "sDom": "Ztir",
+ "sDom": "RJtir",
"iDisplayLength": -1,
"autoWidth": true,
"bLengthChange": true,
"bDeferRender": true,
"bSortClasses": false,
+ "scrollY": "700px",
+ "scrollCollapse": false,
+ "colResize": {
+ "tableWidthFixed": false,
+ },
"paging": false
} );
{% elif dataset.type == 'Publish' %}
- $('#trait_table').dataTable( {
+ $('#trait_table').DataTable( {
"columns": [
{ "type": "natural" },
{ "type": "natural" },
@@ -205,36 +210,46 @@
{ "type": "natural", "width": "15%"},
{ "type": "natural" }
],
- "sDom": "Ztir",
+ "sDom": "RJtir",
"iDisplayLength": -1,
"autoWidth": true,
"bLengthChange": true,
"bDeferRender": true,
"bSortClasses": false,
+ "scrollY": "700px",
+ "scrollCollapse": false,
+ "colResize": {
+ "tableWidthFixed": false,
+ },
"paging": false
} );
{% elif dataset.type == 'Geno' %}
- $('#trait_table').dataTable( {
+ $('#trait_table').DataTable( {
"columns": [
{ "type": "natural" },
{ "type": "natural" },
{ "type": "natural", "width": "40%"}
],
- "sDom": "Ztir",
+ "sDom": "RJtir",
"iDisplayLength": -1,
"autoWidth": true,
"bLengthChange": true,
"bDeferRender": true,
"bSortClasses": false,
+ "scrollY": "700px",
+ "scrollCollapse": false,
+ "colResize": {
+ "tableWidthFixed": false,
+ },
"paging": false
} );
{% endif %}
console.timeEnd("Creating table");
-
- var table = $('#trait_table').DataTable();
- new $.fn.dataTable.FixedHeader( table );
- new $.fn.dataTable.FixedColumns( table );
+ //var table = $('#trait_table').DataTable();
+ //new $.fn.dataTable.FixedHeader( table );
+ //new $.fn.dataTable.FixedColumns( table );
+
});
</script>
{% endblock %}
diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html
index cdde5d9d..b4d6b85b 100755
--- a/wqflask/wqflask/templates/show_trait.html
+++ b/wqflask/wqflask/templates/show_trait.html
@@ -13,6 +13,8 @@
<link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/css/jquery.dataTables.css" />
<link rel="stylesheet" type="text/css" href="/static/packages/DT_bootstrap/DT_bootstrap.css" />
<link rel="stylesheet" type="text/css" href="/static/packages/TableTools/media/css/TableTools.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/extensions/dataTables.fixedHeader.css" >
+ <link rel="stylesheet" type="text/css" href="//cdn.datatables.net/fixedcolumns/3.0.4/css/dataTables.fixedColumns.css">
{% endblock %}
{% block content %} <!-- Start of body -->
@@ -146,6 +148,10 @@
<script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/jquery.dataTables.min.js"></script>
<script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/dataTables.scientific.js"></script>
<script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/dataTables.naturalSort.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/extensions/dataTables.colResize.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/extensions/dataTables.colReorder.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/extensions/dataTables.fixedHeader.js"></script>
+ <script language="javascript" type="text/javascript" src="//cdn.datatables.net/fixedcolumns/3.0.4/js/dataTables.fixedColumns.min.js"></script>
<script language="javascript" type="text/javascript" src="/static/packages/DT_bootstrap/DT_bootstrap.js"></script>
<script language="javascript" type="text/javascript" src="/static/packages/TableTools/media/js/TableTools.min.js"></script>
<script type="text/javascript" charset="utf-8">
@@ -195,68 +201,79 @@
});
console.time("Creating table");
-
- {% if sample_groups[0].se_exists() %}
- $('#samples_primary, #samples_other').find("tr.outlier").css('background-color', 'yellow')
- $('#samples_primary, #samples_other').dataTable( {
- //"sDom": "<<'span3'l><'span3'T><'span4'f>'row-fluid'r>t<'row-fluid'<'span6'i><'span6'p>>",
- "aoColumns": [
- { "sType": "natural" },
- null,
- { "sType": "cust-txt" },
- { "bSortable": false },
- { "sType": "cust-txt" }
+
+ $('#samples_primary, #samples_other').find("tr.outlier").css('background-color', 'yellow')
+ {% if sample_groups[0].se_exists() %}
+ $('#samples_primary, #samples_other').DataTable( {
+ "columns": [
+ { "type": "natural" },
+ { "type": "natural" },
+ { "type": "cust-txt" },
+ { "bSortable": false },
+ { "type": "cust-txt" }
+ ],
+ "sDom": "RJtir",
+ "oTableTools": {
+ "aButtons": [
+ "copy",
+ "print",
+ {
+ "sExtends": "collection",
+ "sButtonText": 'Save <span class="caret" />',
+ "aButtons": [ "csv", "xls", "pdf" ]
+ }
],
- "sDom": "ftr",
- "oTableTools": {
- "aButtons": [
- "copy",
- "print",
- {
- "sExtends": "collection",
- "sButtonText": 'Save <span class="caret" />',
- "aButtons": [ "csv", "xls", "pdf" ]
- }
- ],
- "sSwfPath": "/static/packages/TableTools/media/swf/copy_csv_xls_pdf.swf"
- },
- "bPaginate": false,
- "bLengthChange": true,
- "bDeferRender": true,
- "bSortClasses": false
- } );
- console.timeEnd("Creating table");
+ "sSwfPath": "/static/packages/TableTools/media/swf/copy_csv_xls_pdf.swf"
+ },
+ "iDisplayLength": -1,
+ "autoWidth": true,
+ "bLengthChange": true,
+ "bDeferRender": true,
+ "bSortClasses": false,
+ "scrollY": "600px",
+ "scrollCollapse": false,
+ "colResize": {
+ "tableWidthFixed": false
+ },
+ "paging": false
+ } );
+ console.timeEnd("Creating table");
{% else %}
-
-
- console.time("Creating table");
+ console.time("Creating table");
- $('#samples_primary, #samples_other').dataTable( {
- //"sDom": "<<'span3'l><'span3'T><'span4'f>'row-fluid'r>t<'row-fluid'<'span6'i><'span6'p>>",
- "aoColumns": [
- { "sType": "natural" },
- null,
- { "sType": "cust-txt" }
+ $('#samples_primary, #samples_other').DataTable( {
+ "columns": [
+ { "type": "natural" },
+ null,
+ { "type": "cust-txt" }
+ ],
+ "sDom": "RJtir",
+ "oTableTools": {
+ "aButtons": [
+ "copy",
+ "print",
+ {
+ "sExtends": "collection",
+ "sButtonText": 'Save <span class="caret" />',
+ "aButtons": [ "csv", "xls", "pdf" ]
+ }
],
- "sDom": "ftr",
- "oTableTools": {
- "aButtons": [
- "copy",
- "print",
- {
- "sExtends": "collection",
- "sButtonText": 'Save <span class="caret" />',
- "aButtons": [ "csv", "xls", "pdf" ]
- }
- ],
- "sSwfPath": "/static/packages/TableTools/media/swf/copy_csv_xls_pdf.swf"
- },
- "bPaginate": false,
- "bLengthChange": true,
- "bDeferRender": true,
- "bSortClasses": false
- } );
+ "sSwfPath": "/static/packages/TableTools/media/swf/copy_csv_xls_pdf.swf"
+ },
+ "iDisplayLength": -1,
+ "autoWidth": true,
+ "bLengthChange": true,
+ "bDeferRender": true,
+ "bSortClasses": false,
+ "scrollY": "600px",
+ "scrollX": true,
+ "scrollCollapse": false,
+ "colResize": {
+ "tableWidthFixed": false
+ },
+ "paging": false
+ } );
{% endif %}
});
</script>
diff --git a/wqflask/wqflask/templates/show_trait_edit_data.html b/wqflask/wqflask/templates/show_trait_edit_data.html
index a02dc409..8c919ee0 100755
--- a/wqflask/wqflask/templates/show_trait_edit_data.html
+++ b/wqflask/wqflask/templates/show_trait_edit_data.html
@@ -73,26 +73,25 @@
<br>
- <div id="edit_sample_lists">
+ <!--<div id="edit_sample_lists">-->
{% for sample_type in sample_groups %}
- <div class="sample_group">
+ <!--<div class="sample_group">-->
<h3>{{ sample_type.header }}</h3>
- <table cellpadding="0" cellspacing="0" border="0" class="table table-hover table-striped table-bordered"
- id="samples_{{ sample_type.sample_group_type }}">
+ <table class="table table-hover table-striped" id="samples_{{ sample_type.sample_group_type }}" style="float: left;">
<thead>
<tr>
- <td>Index</td>
- <td>Sample</td>
- <td>Value</td>
+ <th>Index</td>
+ <th>Sample</td>
+ <th>Value</td>
{% if sample_type.se_exists() %}
- <td>&nbsp;</td>
- <td>SE</td>
+ <th>&nbsp;</td>
+ <th>SE</td>
{% endif %}
{% for attribute in sample_type.attributes|sort() %}
- <td>
+ <th>
{{ sample_type.attributes[attribute].name }}
- </td>
+ </th>
{% endfor %}
</tr>
</thead>
@@ -148,9 +147,9 @@
{% endfor %}
</tbody>
</table>
- </div>
+ <!--</div>-->
{% endfor %}
- </div>
+ <!--</div>-->
<input type="hidden" name="Default_Name">