From 47f8aa8af2d73e1daf9b292768f9756a53005274 Mon Sep 17 00:00:00 2001 From: Naomi Date: Tue, 8 Apr 2014 17:03:54 -0400 Subject: [PATCH] CC-5788 : Library Cleanup adding clear/search buttons for advanced search. only saving library state when needed. --- .../controllers/LibraryController.php | 15 +- .../views/scripts/library/index.phtml | 8 - .../views/scripts/library/librarytabs.phtml | 6 + airtime_mvc/public/css/styles.css | 2 +- .../js/airtime/library/lib_separate_table.js | 77 +- .../public/js/airtime/showbuilder/builder.js | 23 +- .../plugin/dataTables.FixedHeader.js | 916 ------------------ .../plugin/dataTables.fnSetFilteringDelay.js | 38 - .../datatables/plugin/dataTables.pluginAPI.js | 19 - 9 files changed, 77 insertions(+), 1027 deletions(-) delete mode 100644 airtime_mvc/public/js/datatables/plugin/dataTables.FixedHeader.js delete mode 100644 airtime_mvc/public/js/datatables/plugin/dataTables.fnSetFilteringDelay.js diff --git a/airtime_mvc/application/controllers/LibraryController.php b/airtime_mvc/application/controllers/LibraryController.php index e6887136c..ade8fee96 100644 --- a/airtime_mvc/application/controllers/LibraryController.php +++ b/airtime_mvc/application/controllers/LibraryController.php @@ -27,12 +27,18 @@ class LibraryController extends Zend_Controller_Action $request = $this->getRequest(); $baseUrl = Application_Common_OsPath::getBaseDir(); + + $this->view->headLink()->appendStylesheet($baseUrl.'css/media_library.css?'.$CC_CONFIG['airtime_version']); + $this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.contextMenu.css?'.$CC_CONFIG['airtime_version']); + $this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/dataTables.colVis.css?'.$CC_CONFIG['airtime_version']); + $this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/dataTables.colReorder.css?'.$CC_CONFIG['airtime_version']); + $this->view->headLink()->appendStylesheet($baseUrl.'css/waveform.css?'.$CC_CONFIG['airtime_version']); + $this->view->headLink()->appendStylesheet($baseUrl.'css/playlist_builder.css?'.$CC_CONFIG['airtime_version']); $this->view->headScript()->appendFile($baseUrl.'js/blockui/jquery.blockUI.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/contextmenu/jquery.contextMenu.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/datatables/js/jquery.dataTables.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.pluginAPI.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); - $this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.fnSetFilteringDelay.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.ColVis.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.ColReorder.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.FixedColumns.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); @@ -43,13 +49,6 @@ class LibraryController extends Zend_Controller_Action $this->view->headScript()->appendFile($baseUrl.'js/airtime/library/events/lib_playlistbuilder.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/airtime/library/lib_separate_table.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/airtime/playlist/playlist.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); - - $this->view->headLink()->appendStylesheet($baseUrl.'css/media_library.css?'.$CC_CONFIG['airtime_version']); - $this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.contextMenu.css?'.$CC_CONFIG['airtime_version']); - $this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/dataTables.colVis.css?'.$CC_CONFIG['airtime_version']); - $this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/dataTables.colReorder.css?'.$CC_CONFIG['airtime_version']); - $this->view->headLink()->appendStylesheet($baseUrl.'css/waveform.css?'.$CC_CONFIG['airtime_version']); - $this->view->headLink()->appendStylesheet($baseUrl.'css/playlist_builder.css?'.$CC_CONFIG['airtime_version']); $this->view->headScript()->appendFile($baseUrl.'js/waveformplaylist/observer/observer.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/waveformplaylist/config.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); diff --git a/airtime_mvc/application/views/scripts/library/index.phtml b/airtime_mvc/application/views/scripts/library/index.phtml index 4fe3b0b46..84305a8c6 100644 --- a/airtime_mvc/application/views/scripts/library/index.phtml +++ b/airtime_mvc/application/views/scripts/library/index.phtml @@ -2,14 +2,6 @@ render('library/library.phtml') ?> -showPlaylist) { - $display = ""; -} else { - //$display = "display:none"; - $display = ""; -} -?>
render('playlist/playlist.phtml') ?>
diff --git a/airtime_mvc/application/views/scripts/library/librarytabs.phtml b/airtime_mvc/application/views/scripts/library/librarytabs.phtml index 56bd546f7..4bfb3fcbe 100644 --- a/airtime_mvc/application/views/scripts/library/librarytabs.phtml +++ b/airtime_mvc/application/views/scripts/library/librarytabs.phtml @@ -11,6 +11,8 @@ + +
@@ -21,6 +23,8 @@ + + @@ -34,6 +38,8 @@ + +
diff --git a/airtime_mvc/public/css/styles.css b/airtime_mvc/public/css/styles.css index 8e85cc1fe..f5b98b40a 100644 --- a/airtime_mvc/public/css/styles.css +++ b/airtime_mvc/public/css/styles.css @@ -2388,7 +2388,7 @@ fieldset.sb-criteria-fieldset{ overflow-x:auto; } -fieldset.closed dl, fieldset.closed textarea, fieldset.closed div, fieldset.closed h2 { +fieldset.closed dl, fieldset.closed textarea, fieldset.closed div, fieldset.closed h2, fieldset.closed button { display:none; } diff --git a/airtime_mvc/public/js/airtime/library/lib_separate_table.js b/airtime_mvc/public/js/airtime/library/lib_separate_table.js index bbe0e08a8..dfe37950c 100644 --- a/airtime_mvc/public/js/airtime/library/lib_separate_table.js +++ b/airtime_mvc/public/js/airtime/library/lib_separate_table.js @@ -7,6 +7,7 @@ var AIRTIME = (function(AIRTIME) { //stored in format chosenItems[tabname] = object of chosen ids for the tab. var chosenItems = {}, + datatablesSettings = {}, $library, LIB_SELECTED_CLASS = "lib-selected", LIB_ADD_CLASS = "lib-add", @@ -203,11 +204,21 @@ var AIRTIME = (function(AIRTIME) { } function datatablesDrawCallback(oSettings) { - var tabId = getActiveTabId(); highlightChosen(); mod.checkToolBarIcons(); } + + function libraryNeedSave(oData) { + var settings = getCurrentDatatableSettings(); + + if (settings["abVisCols"].join() === oData.abVisCols.join() + && settings["ColReorder"].join() === oData.ColReorder.join()) { + return false; + } + + return true; + } function createDatatable(config) { var key = "datatables-"+config.type+"-aoColumns", @@ -244,14 +255,17 @@ var AIRTIME = (function(AIRTIME) { delete oData.aoSearchCols; }, "fnStateSave": function (oSettings, oData) { - localStorage.setItem('datatables-'+ config.type, JSON.stringify(oData)); - - $.ajax({ - url: baseUrl+"usersettings/set-"+ config.type + "-datatable", - type: "POST", - data: {settings : oData, format: "json"}, - dataType: "json" - }); + + if (libraryNeedSave(oData)) { + localStorage.setItem('datatables-'+ config.type, JSON.stringify(oData)); + + $.ajax({ + url: baseUrl+"usersettings/set-"+ config.type + "-datatable", + type: "POST", + data: {settings : oData, format: "json"}, + dataType: "json" + }); + } }, "fnStateLoad": function fnLibStateLoad(oSettings) { var settings = localStorage.getItem('datatables-'+ config.type); @@ -265,27 +279,28 @@ var AIRTIME = (function(AIRTIME) { "fnStateLoadParams": function (oSettings, oData) { var i, length, - a = oData.abVisCols; + a = oData.abVisCols, + settings = getCurrentDatatableSettings(); - if (a) { - // putting serialized data back into the correct js type to make - // sure everything works properly. - for (i = 0, length = a.length; i < length; i++) { - if (typeof(a[i]) === "string") { - a[i] = (a[i] === "true") ? true : false; - } - } + // putting serialized data back into the correct js type to make + // sure everything works properly. + for (i = 0, length = a.length; i < length; i++) { + if (typeof(a[i]) === "string") { + a[i] = (a[i] === "true") ? true : false; + } } + + settings["abVisCols"] = a.slice(0); a = oData.ColReorder; - if (a) { - for (i = 0, length = a.length; i < length; i++) { - if (typeof(a[i]) === "string") { - a[i] = parseInt(a[i], 10); - } + for (i = 0, length = a.length; i < length; i++) { + if (typeof(a[i]) === "string") { + a[i] = parseInt(a[i], 10); } } + settings["ColReorder"] = a.slice(0); + //abVisible indices belong to the original column order. //use to fix up advanced search. abVisible = oData.abVisCols; @@ -346,7 +361,7 @@ var AIRTIME = (function(AIRTIME) { }); //append a search button - $panel.find(".dataTables_filter").append(''); + //$panel.find(".dataTables_filter").append(''); //only search on enter. $panel.on("keypress", ".advanced_search input", function(e) { @@ -355,6 +370,10 @@ var AIRTIME = (function(AIRTIME) { } }); + $panel.on("click", ".btn-clear", function(e) { + $panel.find(".advanced_search input").val(""); + }); + $panel.on("click", ".btn-search", function(e) { table.fnDraw(); }); @@ -410,6 +429,16 @@ var AIRTIME = (function(AIRTIME) { mod.getActiveTabId = getActiveTabId; + function getCurrentDatatableSettings() { + var tabId = getActiveTabId(); + + if (datatablesSettings[tabId] === undefined) { + datatablesSettings[tabId] = {}; + } + + return datatablesSettings[tabId]; + } + function getActiveDatatable() { var tabId = getActiveTabId(); diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js index a3f41cdce..e5063fabd 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js @@ -8,6 +8,7 @@ var AIRTIME = (function(AIRTIME){ $sbTable, $toolbar, $lib, + builderCheckTimeout, internalTimestamp = -1, internalShowInstances = [], hasGottenFirstAjax = false, @@ -73,7 +74,7 @@ var AIRTIME = (function(AIRTIME){ console.log("need to update builder table."); oTable.fnDraw(); } - setTimeout(checkScheduleUpdates, 5000); + builderCheckTimeout = setTimeout(checkScheduleUpdates, 5000); } }); } @@ -339,7 +340,7 @@ var AIRTIME = (function(AIRTIME){ //start this timeout //check if the timeline view needs updating. - checkScheduleUpdates(); + builderCheckTimeout = setTimeout(checkScheduleUpdates, 5000); } } } @@ -692,24 +693,22 @@ var AIRTIME = (function(AIRTIME){ //remove any selected nodes before the draw. "fnPreDrawCallback": function( oSettings ) { + clearTimeout(mod.timeout); + clearTimeout(builderCheckTimeout); + //make sure any dragging helpers are removed or else they'll be stranded on the screen. $("#draggingContainer").remove(); }, "fnDrawCallback": function fnBuilderDrawCallback(oSettings, json) { - //var timer1 = new Date().getTime(); - - var aData, + var aData, elements, i, length, temp, - $cursorRows, - $table = $(this); + $cursorRows; if ($(this).find("."+NOW_PLAYING_CLASS).length > 0) { mod.jumpToCurrentTrack(); } - - clearTimeout(mod.timeout); - + //only create the cursor arrows if the library is on the page. if ($lib.length > 0 && $lib.filter(":visible").length > 0) { @@ -747,9 +746,7 @@ var AIRTIME = (function(AIRTIME){ mod.checkToolBarIcons(); - //var timer2 = new Date().getTime(); - - //console.log(timer2 - timer1); + builderCheckTimeout = setTimeout(checkScheduleUpdates, 5000); }, // R = ColReorder, C = ColVis diff --git a/airtime_mvc/public/js/datatables/plugin/dataTables.FixedHeader.js b/airtime_mvc/public/js/datatables/plugin/dataTables.FixedHeader.js deleted file mode 100644 index e00ce1f34..000000000 --- a/airtime_mvc/public/js/datatables/plugin/dataTables.FixedHeader.js +++ /dev/null @@ -1,916 +0,0 @@ -/* - * File: FixedHeader.js - * Version: 2.0.5 - * Description: "Fix" a header at the top of the table, so it scrolls with the table - * Author: Allan Jardine (www.sprymedia.co.uk) - * Created: Wed 16 Sep 2009 19:46:30 BST - * Language: Javascript - * License: GPL v2 or BSD 3 point style - * Project: Just a little bit of fun - enjoy :-) - * Contact: www.sprymedia.co.uk/contact - * - * Copyright 2009-2010 Allan Jardine, all rights reserved. - * - * This source file is free software, under either the GPL v2 license or a - * BSD style license, available at: - * http://datatables.net/license_gpl2 - * http://datatables.net/license_bsd - */ - -/* - * Function: FixedHeader - * Purpose: Provide 'fixed' header, footer and columns on an HTML table - * Returns: object:FixedHeader - must be called with 'new' - * Inputs: mixed:mTable - target table - * 1. DataTable object - when using FixedHeader with DataTables, or - * 2. HTML table node - when using FixedHeader without DataTables - * object:oInit - initialisation settings, with the following properties (each optional) - * bool:top - fix the header (default true) - * bool:bottom - fix the footer (default false) - * bool:left - fix the left most column (default false) - * bool:right - fix the right most column (default false) - * int:zTop - fixed header zIndex - * int:zBottom - fixed footer zIndex - * int:zLeft - fixed left zIndex - * int:zRight - fixed right zIndex - */ -var FixedHeader = function ( mTable, oInit ) { - /* Sanity check - you just know it will happen */ - if ( typeof this.fnInit != 'function' ) - { - alert( "FixedHeader warning: FixedHeader must be initialised with the 'new' keyword." ); - return; - } - - var that = this; - var oSettings = { - "aoCache": [], - "oSides": { - "top": true, - "bottom": false, - "left": false, - "right": false - }, - "oZIndexes": { - "top": 104, - "bottom": 103, - "left": 102, - "right": 101 - }, - "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" */ - }, - "nTable": null, - "bUseAbsPos": false, - "bFooter": 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(); - }; - - /* Let's do it */ - this.fnInit( mTable, oInit ); - - /* Store the instance on the DataTables object for easy access */ - if ( typeof mTable.fnSettings == 'function' ) - { - mTable._oPluginFixedHeader = this; - } -}; - - -/* - * Variable: FixedHeader - * Purpose: Prototype for FixedHeader - * Scope: global - */ -FixedHeader.prototype = { - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Initialisation - */ - - /* - * Function: fnInit - * Purpose: The "constructor" - * Returns: - - * Inputs: {as FixedHeader function} - */ - fnInit: function ( oTable, oInit ) - { - var s = this.fnGetSettings(); - var that = this; - - /* Record the user definable settings */ - this.fnInitSettings( s, oInit ); - - /* DataTables specific stuff */ - if ( typeof oTable.fnSettings == 'function' ) - { - if ( typeof oTable.fnVersionCheck == 'functon' && - oTable.fnVersionCheck( '1.6.0' ) !== true ) - { - alert( "FixedHeader 2 required DataTables 1.6.0 or later. "+ - "Please upgrade your DataTables installation" ); - return; - } - - var oDtSettings = oTable.fnSettings(); - - 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.push( { - "fn": function () { - FixedHeader.fnMeasure(); - that._fnUpdateClones.call(that); - that._fnUpdatePositions.call(that); - }, - "sName": "FixedHeader" - } ); - } - else - { - s.nTable = oTable; - } - - s.bFooter = ($('>tfoot', s.nTable).length > 0) ? true : false; - - /* "Detect" browsers that don't support absolute positioing - or have bugs */ - s.bUseAbsPos = (jQuery.browser.msie && (jQuery.browser.version=="6.0"||jQuery.browser.version=="7.0")); - - /* 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 ) ); - } - if ( s.oSides.right ) - { - s.aoCache.push( that._fnCloneTable( "fixedRight", "FixedHeader_Right", that._fnCloneTRight ) ); - } - - /* Event listeners for window movement */ - FixedHeader.afnScroll.push( function () { - that._fnUpdatePositions.call(that); - } ); - - jQuery(window).resize( function () { - FixedHeader.fnMeasure(); - that._fnUpdateClones.call(that); - that._fnUpdatePositions.call(that); - } ); - - /* Get things right to start with */ - FixedHeader.fnMeasure(); - that._fnUpdateClones(); - that._fnUpdatePositions(); - }, - - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * 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 ( typeof oInit != 'undefined' ) - { - if ( typeof oInit.top != 'undefined' ) { - s.oSides.top = oInit.top; - } - if ( typeof oInit.bottom != 'undefined' ) { - s.oSides.bottom = oInit.bottom; - } - if ( typeof oInit.left != 'undefined' ) { - s.oSides.left = oInit.left; - } - if ( typeof oInit.right != 'undefined' ) { - s.oSides.right = oInit.right; - } - - if ( typeof oInit.zTop != 'undefined' ) { - s.oZIndexes.top = oInit.zTop; - } - if ( typeof oInit.zBottom != 'undefined' ) { - s.oZIndexes.bottom = oInit.zBottom; - } - if ( typeof oInit.zLeft != 'undefined' ) { - s.oZIndexes.left = oInit.zLeft; - } - if ( typeof oInit.zRight != 'undefined' ) { - s.oZIndexes.right = oInit.zRight; - } - } - - /* Detect browsers which have poor position:fixed support so we can use absolute positions. - * This is much slower since the position must be updated for each scroll, but widens - * compatibility - */ - s.bUseAbsPos = (jQuery.browser.msie && - (jQuery.browser.version=="6.0"||jQuery.browser.version=="7.0")); - }, - - /* - * Function: _fnCloneTable - * Purpose: Clone the table node and do basic initialisation - * Returns: - - * Inputs: - - */ - _fnCloneTable: function ( sType, sClass, fnClone ) - { - 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 ( jQuery(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 poistion 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 - }; - }, - - /* - * Function: _fnUpdatePositions - * Purpose: Get the current positioning of the table in the DOM - * Returns: - - * Inputs: - - */ - _fnMeasure: function () - { - var - s = this.fnGetSettings(), - m = s.oMes, - jqTable = jQuery(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 oWin.iScrollTop ) - { - /* 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 > 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 */ - if ( s.bUseAbsPos ) - { - this._fnUpdateCache( oCache, 'sPosition', "absolute", 'position', nTable.style ); - this._fnUpdateCache( oCache, 'sTop', oWin.iScrollTop+"px", 'top', nTable.style ); - this._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+"px", 'left', nTable.style ); - } - else - { - this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style ); - this._fnUpdateCache( oCache, 'sTop', "0px", '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; - } - }, - - - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Cloning functions - */ - - /* - * Function: _fnCloneThead - * Purpose: Clone the thead element - * Returns: - - * Inputs: object:oCache - the cahced values for this fixed element - */ - _fnCloneThead: 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 = jQuery(s.nTable).outerWidth()+"px"; - - /* Remove any children the cloned table has */ - while ( nTable.childNodes.length > 0 ) - { - jQuery('thead th', nTable).unbind( 'click' ); - nTable.removeChild( nTable.childNodes[0] ); - } - - /* Clone the DataTables header */ - var nThead = jQuery('thead', s.nTable).clone(true)[0]; - nTable.appendChild( nThead ); - - /* Copy the widths across - apparently a clone isn't good enough for this */ - jQuery("thead>tr th", s.nTable).each( function (i) { - jQuery("thead>tr th:eq("+i+")", nTable).width( jQuery(this).width() ); - } ); - - jQuery("thead>tr td", s.nTable).each( function (i) { - jQuery("thead>tr td:eq("+i+")", nTable).width( jQuery(this).width() ); - } ); - }, - - /* - * Function: _fnCloneTfoot - * Purpose: Clone the tfoot element - * Returns: - - * Inputs: object:oCache - the cahced 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 = jQuery(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 = jQuery('tfoot', s.nTable).clone(true)[0]; - nTable.appendChild( nTfoot ); - - /* Copy the widths across - apparently a clone isn't good enough for this */ - jQuery("tfoot:eq(0)>tr th", s.nTable).each( function (i) { - jQuery("tfoot:eq(0)>tr th:eq("+i+")", nTable).width( jQuery(this).width() ); - } ); - - jQuery("tfoot:eq(0)>tr td", s.nTable).each( function (i) { - jQuery("tfoot:eq(0)>tr th:eq("+i+")", nTable)[0].style.width( jQuery(this).width() ); - } ); - }, - - /* - * Function: _fnCloneTLeft - * Purpose: Clone the left column - * Returns: - - * Inputs: object:oCache - the cahced values for this fixed element - */ - _fnCloneTLeft: function ( oCache ) - { - var s = this.fnGetSettings(); - var nTable = oCache.nNode; - var nBody = $('tbody', s.nTable)[0]; - var iCols = $('tbody tr:eq(0) td', s.nTable).length; - var bRubbishOldIE = ($.browser.msie && ($.browser.version == "6.0" || $.browser.version == "7.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( jQuery("thead", s.nTable).clone(true)[0] ); - nTable.appendChild( jQuery("tbody", s.nTable).clone(true)[0] ); - if ( s.bFooter ) - { - nTable.appendChild( jQuery("tfoot", s.nTable).clone(true)[0] ); - } - - jQuery('thead tr th:gt(0)', nTable).remove(); - jQuery('tfoot tr th:gt(0)', nTable).remove(); - - /* Remove unneeded cells */ - $('tbody tr', nTable).each( function (k) { - $('td:gt(0)', this).remove(); - } ); - - this.fnEqualiseHeights( 'tbody', nBody.parentNode, nTable ); - - var iWidth = jQuery('thead tr th:eq(0)', s.nTable).outerWidth(); - nTable.style.width = iWidth+"px"; - oCache.nWrapper.style.width = iWidth+"px"; - }, - - /* - * Function: _fnCloneTRight - * Purpose: Clone the right most colun - * Returns: - - * Inputs: object:oCache - the cahced values for this fixed element - */ - _fnCloneTRight: function ( oCache ) - { - var s = this.fnGetSettings(); - var nBody = $('tbody', s.nTable)[0]; - var nTable = oCache.nNode; - var iCols = jQuery('tbody tr:eq(0) td', s.nTable).length; - var bRubbishOldIE = ($.browser.msie && ($.browser.version == "6.0" || $.browser.version == "7.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( jQuery("thead", s.nTable).clone(true)[0] ); - nTable.appendChild( jQuery("tbody", s.nTable).clone(true)[0] ); - if ( s.bFooter ) - { - nTable.appendChild( jQuery("tfoot", s.nTable).clone(true)[0] ); - } - jQuery('thead tr th:not(:nth-child('+iCols+'n))', nTable).remove(); - jQuery('tfoot tr th:not(:nth-child('+iCols+'n))', nTable).remove(); - - /* Remove unneeded cells */ - $('tbody tr', nTable).each( function (k) { - $('td:lt('+(iCols-1)+')', this).remove(); - } ); - - this.fnEqualiseHeights( 'tbody', nBody.parentNode, nTable ); - - var iWidth = jQuery('thead tr th:eq('+(iCols-1)+')', 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, - jqBoxHack = $(parent+' tr:eq(0)', original).children(':eq(0)'), - iBoxHack = jqBoxHack.outerHeight() - jqBoxHack.height(), - bRubbishOldIE = ($.browser.msie && ($.browser.version == "6.0" || $.browser.version == "7.0")); - - /* Remove cells which are not needed and copy the height from the original table */ - $(parent+' tr', clone).each( function (k) { - /* Can we use some kind of object detection here?! This is very nasty - damn browsers */ - if ( $.browser.mozilla || $.browser.opera ) - { - $(this).children().height( $(parent+' tr:eq('+k+')', original).outerHeight() ); - } - else - { - $(this).children().height( $(parent+' tr:eq('+k+')', original).outerHeight() - iBoxHack ); - } - - if ( !bRubbishOldIE ) - { - $(parent+' tr:eq('+k+')', original).height( $(parent+' tr:eq('+k+')', original).outerHeight() ); - } - } ); - } -}; - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * 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 = jQuery(window), - jqDoc = jQuery(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; -}; - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * 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 - */ -jQuery(window).scroll( function () { - FixedHeader.fnMeasure(); - for ( var i=0, iLen=FixedHeader.afnScroll.length ; i