public/admin/plugins/datatables/extensions/ColVis/js/dataTables.colVis.js in admin-sys-1.0.2 vs public/admin/plugins/datatables/extensions/ColVis/js/dataTables.colVis.js in admin-sys-1.1.0

- old
+ new

@@ -1,1123 +1,1123 @@ -/*! ColVis 1.1.2 - * ©2010-2015 SpryMedia Ltd - datatables.net/license - */ - -/** - * @summary ColVis - * @description Controls for column visibility in DataTables - * @version 1.1.2 - * @file dataTables.colReorder.js - * @author SpryMedia Ltd (www.sprymedia.co.uk) - * @contact www.sprymedia.co.uk/contact - * @copyright Copyright 2010-2015 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) { - - -var factory = function( $, DataTable ) { -"use strict"; - -/** - * ColVis provides column visibility control for DataTables - * - * @class ColVis - * @constructor - * @param {object} DataTables settings object. With DataTables 1.10 this can - * also be and API instance, table node, jQuery collection or jQuery selector. - * @param {object} ColVis configuration options - */ -var ColVis = function( oDTSettings, oInit ) -{ - /* Santiy check that we are a new instance */ - if ( !this.CLASS || this.CLASS != "ColVis" ) - { - alert( "Warning: ColVis must be initialised with the keyword 'new'" ); - } - - if ( typeof oInit == 'undefined' ) - { - oInit = {}; - } - - var camelToHungarian = $.fn.dataTable.camelToHungarian; - if ( camelToHungarian ) { - camelToHungarian( ColVis.defaults, ColVis.defaults, true ); - camelToHungarian( ColVis.defaults, oInit ); - } - - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Public class variables - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - /** - * @namespace Settings object which contains customisable information for - * ColVis instance. Augmented by ColVis.defaults - */ - this.s = { - /** - * DataTables settings object - * @property dt - * @type Object - * @default null - */ - "dt": null, - - /** - * Customisation object - * @property oInit - * @type Object - * @default passed in - */ - "oInit": oInit, - - /** - * Flag to say if the collection is hidden - * @property hidden - * @type boolean - * @default true - */ - "hidden": true, - - /** - * Store the original visibility settings so they could be restored - * @property abOriginal - * @type Array - * @default [] - */ - "abOriginal": [] - }; - - - /** - * @namespace Common and useful DOM elements for the class instance - */ - this.dom = { - /** - * Wrapper for the button - given back to DataTables as the node to insert - * @property wrapper - * @type Node - * @default null - */ - "wrapper": null, - - /** - * Activation button - * @property button - * @type Node - * @default null - */ - "button": null, - - /** - * Collection list node - * @property collection - * @type Node - * @default null - */ - "collection": null, - - /** - * Background node used for shading the display and event capturing - * @property background - * @type Node - * @default null - */ - "background": null, - - /** - * Element to position over the activation button to catch mouse events when using mouseover - * @property catcher - * @type Node - * @default null - */ - "catcher": null, - - /** - * List of button elements - * @property buttons - * @type Array - * @default [] - */ - "buttons": [], - - /** - * List of group button elements - * @property groupButtons - * @type Array - * @default [] - */ - "groupButtons": [], - - /** - * Restore button - * @property restore - * @type Node - * @default null - */ - "restore": null - }; - - /* Store global reference */ - ColVis.aInstances.push( this ); - - /* Constructor logic */ - this.s.dt = $.fn.dataTable.Api ? - new $.fn.dataTable.Api( oDTSettings ).settings()[0] : - oDTSettings; - - this._fnConstruct( oInit ); - return this; -}; - - - -ColVis.prototype = { - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Public methods - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - /** - * Get the ColVis instance's control button so it can be injected into the - * DOM - * @method button - * @returns {node} ColVis button - */ - button: function () - { - return this.dom.wrapper; - }, - - /** - * Alias of `rebuild` for backwards compatibility - * @method fnRebuild - */ - "fnRebuild": function () - { - this.rebuild(); - }, - - /** - * Rebuild the list of buttons for this instance (i.e. if there is a column - * header update) - * @method fnRebuild - */ - rebuild: function () - { - /* Remove the old buttons */ - for ( var i=this.dom.buttons.length-1 ; i>=0 ; i-- ) { - this.dom.collection.removeChild( this.dom.buttons[i] ); - } - this.dom.buttons.splice( 0, this.dom.buttons.length ); - this.dom.groupButtons.splice(0, this.dom.groupButtons.length); - - if ( this.dom.restore ) { - this.dom.restore.parentNode( this.dom.restore ); - } - - /* Re-add them (this is not the optimal way of doing this, it is fast and effective) */ - this._fnAddGroups(); - this._fnAddButtons(); - - /* Update the checkboxes */ - this._fnDrawCallback(); - }, - - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Private methods (they are of course public in JS, but recommended as private) - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - /** - * Constructor logic - * @method _fnConstruct - * @returns void - * @private - */ - "_fnConstruct": function ( init ) - { - this._fnApplyCustomisation( init ); - - var that = this; - var i, iLen; - this.dom.wrapper = document.createElement('div'); - this.dom.wrapper.className = "ColVis"; - - this.dom.button = $( '<button />', { - 'class': !this.s.dt.bJUI ? - "ColVis_Button ColVis_MasterButton" : - "ColVis_Button ColVis_MasterButton ui-button ui-state-default" - } ) - .append( '<span>'+this.s.buttonText+'</span>' ) - .bind( this.s.activate=="mouseover" ? "mouseover" : "click", function (e) { - e.preventDefault(); - that._fnCollectionShow(); - } ) - .appendTo( this.dom.wrapper )[0]; - - this.dom.catcher = this._fnDomCatcher(); - this.dom.collection = this._fnDomCollection(); - this.dom.background = this._fnDomBackground(); - - this._fnAddGroups(); - this._fnAddButtons(); - - /* Store the original visibility information */ - for ( i=0, iLen=this.s.dt.aoColumns.length ; i<iLen ; i++ ) - { - this.s.abOriginal.push( this.s.dt.aoColumns[i].bVisible ); - } - - /* Update on each draw */ - this.s.dt.aoDrawCallback.push( { - "fn": function () { - that._fnDrawCallback.call( that ); - }, - "sName": "ColVis" - } ); - - /* If columns are reordered, then we need to update our exclude list and - * rebuild the displayed list - */ - $(this.s.dt.oInstance).bind( 'column-reorder.dt', function ( e, oSettings, oReorder ) { - for ( i=0, iLen=that.s.aiExclude.length ; i<iLen ; i++ ) { - that.s.aiExclude[i] = oReorder.aiInvertMapping[ that.s.aiExclude[i] ]; - } - - var mStore = that.s.abOriginal.splice( oReorder.iFrom, 1 )[0]; - that.s.abOriginal.splice( oReorder.iTo, 0, mStore ); - - that.fnRebuild(); - } ); - - $(this.s.dt.oInstance).bind( 'destroy.dt', function () { - $(that.dom.wrapper).remove(); - } ); - - // Set the initial state - this._fnDrawCallback(); - }, - - - /** - * Apply any customisation to the settings from the DataTables initialisation - * @method _fnApplyCustomisation - * @returns void - * @private - */ - "_fnApplyCustomisation": function ( init ) - { - $.extend( true, this.s, ColVis.defaults, init ); - - // Slightly messy overlap for the camelCase notation - if ( ! this.s.showAll && this.s.bShowAll ) { - this.s.showAll = this.s.sShowAll; - } - - if ( ! this.s.restore && this.s.bRestore ) { - this.s.restore = this.s.sRestore; - } - - // CamelCase to Hungarian for the column groups - var groups = this.s.groups; - var hungarianGroups = this.s.aoGroups; - if ( groups ) { - for ( var i=0, ien=groups.length ; i<ien ; i++ ) { - if ( groups[i].title ) { - hungarianGroups[i].sTitle = groups[i].title; - } - if ( groups[i].columns ) { - hungarianGroups[i].aiColumns = groups[i].columns; - } - } - } - }, - - - /** - * On each table draw, check the visibility checkboxes as needed. This allows any process to - * update the table's column visibility and ColVis will still be accurate. - * @method _fnDrawCallback - * @returns void - * @private - */ - "_fnDrawCallback": function () - { - var columns = this.s.dt.aoColumns; - var buttons = this.dom.buttons; - var groups = this.s.aoGroups; - var button; - - for ( var i=0, ien=buttons.length ; i<ien ; i++ ) { - button = buttons[i]; - - if ( button.__columnIdx !== undefined ) { - $('input', button).prop( 'checked', columns[ button.__columnIdx ].bVisible ); - } - } - - var allVisible = function ( columnIndeces ) { - for ( var k=0, kLen=columnIndeces.length ; k<kLen ; k++ ) - { - if ( columns[columnIndeces[k]].bVisible === false ) { return false; } - } - return true; - }; - var allHidden = function ( columnIndeces ) { - for ( var m=0 , mLen=columnIndeces.length ; m<mLen ; m++ ) - { - if ( columns[columnIndeces[m]].bVisible === true ) { return false; } - } - return true; - }; - - for ( var j=0, jLen=groups.length ; j<jLen ; j++ ) - { - if ( allVisible(groups[j].aiColumns) ) - { - $('input', this.dom.groupButtons[j]).prop('checked', true); - $('input', this.dom.groupButtons[j]).prop('indeterminate', false); - } - else if ( allHidden(groups[j].aiColumns) ) - { - $('input', this.dom.groupButtons[j]).prop('checked', false); - $('input', this.dom.groupButtons[j]).prop('indeterminate', false); - } - else - { - $('input', this.dom.groupButtons[j]).prop('indeterminate', true); - } - } - }, - - - /** - * Loop through the groups (provided in the settings) and create a button for each. - * @method _fnAddgroups - * @returns void - * @private - */ - "_fnAddGroups": function () - { - var nButton; - - if ( typeof this.s.aoGroups != 'undefined' ) - { - for ( var i=0, iLen=this.s.aoGroups.length ; i<iLen ; i++ ) - { - nButton = this._fnDomGroupButton( i ); - this.dom.groupButtons.push( nButton ); - this.dom.buttons.push( nButton ); - this.dom.collection.appendChild( nButton ); - } - } - }, - - - /** - * Loop through the columns in the table and as a new button for each one. - * @method _fnAddButtons - * @returns void - * @private - */ - "_fnAddButtons": function () - { - var - nButton, - columns = this.s.dt.aoColumns; - - if ( $.inArray( 'all', this.s.aiExclude ) === -1 ) { - for ( var i=0, iLen=columns.length ; i<iLen ; i++ ) - { - if ( $.inArray( i, this.s.aiExclude ) === -1 ) - { - nButton = this._fnDomColumnButton( i ); - nButton.__columnIdx = i; - this.dom.buttons.push( nButton ); - } - } - } - - if ( this.s.order === 'alpha' ) { - this.dom.buttons.sort( function ( a, b ) { - var titleA = columns[ a.__columnIdx ].sTitle; - var titleB = columns[ b.__columnIdx ].sTitle; - - return titleA === titleB ? - 0 : - titleA < titleB ? - -1 : - 1; - } ); - } - - if ( this.s.restore ) - { - nButton = this._fnDomRestoreButton(); - nButton.className += " ColVis_Restore"; - this.dom.buttons.push( nButton ); - } - - if ( this.s.showAll ) - { - nButton = this._fnDomShowXButton( this.s.showAll, true ); - nButton.className += " ColVis_ShowAll"; - this.dom.buttons.push( nButton ); - } - - if ( this.s.showNone ) - { - nButton = this._fnDomShowXButton( this.s.showNone, false ); - nButton.className += " ColVis_ShowNone"; - this.dom.buttons.push( nButton ); - } - - $(this.dom.collection).append( this.dom.buttons ); - }, - - - /** - * Create a button which allows a "restore" action - * @method _fnDomRestoreButton - * @returns {Node} Created button - * @private - */ - "_fnDomRestoreButton": function () - { - var - that = this, - dt = this.s.dt; - - return $( - '<li class="ColVis_Special '+(dt.bJUI ? 'ui-button ui-state-default' : '')+'">'+ - this.s.restore+ - '</li>' - ) - .click( function (e) { - for ( var i=0, iLen=that.s.abOriginal.length ; i<iLen ; i++ ) - { - that.s.dt.oInstance.fnSetColumnVis( i, that.s.abOriginal[i], false ); - } - that._fnAdjustOpenRows(); - that.s.dt.oInstance.fnAdjustColumnSizing( false ); - that.s.dt.oInstance.fnDraw( false ); - } )[0]; - }, - - - /** - * Create a button which allows show all and show node actions - * @method _fnDomShowXButton - * @returns {Node} Created button - * @private - */ - "_fnDomShowXButton": function ( str, action ) - { - var - that = this, - dt = this.s.dt; - - return $( - '<li class="ColVis_Special '+(dt.bJUI ? 'ui-button ui-state-default' : '')+'">'+ - str+ - '</li>' - ) - .click( function (e) { - for ( var i=0, iLen=that.s.abOriginal.length ; i<iLen ; i++ ) - { - if (that.s.aiExclude.indexOf(i) === -1) - { - that.s.dt.oInstance.fnSetColumnVis( i, action, false ); - } - } - that._fnAdjustOpenRows(); - that.s.dt.oInstance.fnAdjustColumnSizing( false ); - that.s.dt.oInstance.fnDraw( false ); - } )[0]; - }, - - - /** - * Create the DOM for a show / hide group button - * @method _fnDomGroupButton - * @param {int} i Group in question, order based on that provided in settings - * @returns {Node} Created button - * @private - */ - "_fnDomGroupButton": function ( i ) - { - var - that = this, - dt = this.s.dt, - oGroup = this.s.aoGroups[i]; - - return $( - '<li class="ColVis_Special '+(dt.bJUI ? 'ui-button ui-state-default' : '')+'">'+ - '<label>'+ - '<input type="checkbox" />'+ - '<span>'+oGroup.sTitle+'</span>'+ - '</label>'+ - '</li>' - ) - .click( function (e) { - var showHide = !$('input', this).is(":checked"); - if ( e.target.nodeName.toLowerCase() !== "li" ) - { - showHide = ! showHide; - } - - for ( var j=0 ; j < oGroup.aiColumns.length ; j++ ) - { - that.s.dt.oInstance.fnSetColumnVis( oGroup.aiColumns[j], showHide ); - } - } )[0]; - }, - - - /** - * Create the DOM for a show / hide button - * @method _fnDomColumnButton - * @param {int} i Column in question - * @returns {Node} Created button - * @private - */ - "_fnDomColumnButton": function ( i ) - { - var - that = this, - column = this.s.dt.aoColumns[i], - dt = this.s.dt; - - var title = this.s.fnLabel===null ? - column.sTitle : - this.s.fnLabel( i, column.sTitle, column.nTh ); - - return $( - '<li '+(dt.bJUI ? 'class="ui-button ui-state-default"' : '')+'>'+ - '<label>'+ - '<input type="checkbox" />'+ - '<span>'+title+'</span>'+ - '</label>'+ - '</li>' - ) - .click( function (e) { - var showHide = !$('input', this).is(":checked"); - if ( e.target.nodeName.toLowerCase() !== "li" ) - { - if ( e.target.nodeName.toLowerCase() == "input" || that.s.fnStateChange === null ) - { - showHide = ! showHide; - } - } - - /* Need to consider the case where the initialiser created more than one table - change the - * API index that DataTables is using - */ - var oldIndex = $.fn.dataTableExt.iApiIndex; - $.fn.dataTableExt.iApiIndex = that._fnDataTablesApiIndex.call(that); - - // Optimisation for server-side processing when scrolling - don't do a full redraw - if ( dt.oFeatures.bServerSide ) - { - that.s.dt.oInstance.fnSetColumnVis( i, showHide, false ); - that.s.dt.oInstance.fnAdjustColumnSizing( false ); - if (dt.oScroll.sX !== "" || dt.oScroll.sY !== "" ) - { - that.s.dt.oInstance.oApi._fnScrollDraw( that.s.dt ); - } - that._fnDrawCallback(); - } - else - { - that.s.dt.oInstance.fnSetColumnVis( i, showHide ); - } - - $.fn.dataTableExt.iApiIndex = oldIndex; /* Restore */ - - if ( that.s.fnStateChange !== null ) - { - if ( e.target.nodeName.toLowerCase() == "span" ) - { - e.preventDefault(); - } - that.s.fnStateChange.call( that, i, showHide ); - } - } )[0]; - }, - - - /** - * Get the position in the DataTables instance array of the table for this - * instance of ColVis - * @method _fnDataTablesApiIndex - * @returns {int} Index - * @private - */ - "_fnDataTablesApiIndex": function () - { - for ( var i=0, iLen=this.s.dt.oInstance.length ; i<iLen ; i++ ) - { - if ( this.s.dt.oInstance[i] == this.s.dt.nTable ) - { - return i; - } - } - return 0; - }, - - - /** - * Create the element used to contain list the columns (it is shown and - * hidden as needed) - * @method _fnDomCollection - * @returns {Node} div container for the collection - * @private - */ - "_fnDomCollection": function () - { - return $('<ul />', { - 'class': !this.s.dt.bJUI ? - "ColVis_collection" : - "ColVis_collection ui-buttonset ui-buttonset-multi" - } ) - .css( { - 'display': 'none', - 'opacity': 0, - 'position': ! this.s.bCssPosition ? - 'absolute' : - '' - } )[0]; - }, - - - /** - * An element to be placed on top of the activate button to catch events - * @method _fnDomCatcher - * @returns {Node} div container for the collection - * @private - */ - "_fnDomCatcher": function () - { - var - that = this, - nCatcher = document.createElement('div'); - nCatcher.className = "ColVis_catcher"; - - $(nCatcher).click( function () { - that._fnCollectionHide.call( that, null, null ); - } ); - - return nCatcher; - }, - - - /** - * Create the element used to shade the background, and capture hide events (it is shown and - * hidden as needed) - * @method _fnDomBackground - * @returns {Node} div container for the background - * @private - */ - "_fnDomBackground": function () - { - var that = this; - - var background = $('<div></div>') - .addClass( 'ColVis_collectionBackground' ) - .css( 'opacity', 0 ) - .click( function () { - that._fnCollectionHide.call( that, null, null ); - } ); - - /* When considering a mouse over action for the activation, we also consider a mouse out - * which is the same as a mouse over the background - without all the messing around of - * bubbling events. Use the catcher element to avoid messing around with bubbling - */ - if ( this.s.activate == "mouseover" ) - { - background.mouseover( function () { - that.s.overcollection = false; - that._fnCollectionHide.call( that, null, null ); - } ); - } - - return background[0]; - }, - - - /** - * Show the show / hide list and the background - * @method _fnCollectionShow - * @returns void - * @private - */ - "_fnCollectionShow": function () - { - var that = this, i, iLen, iLeft; - var oPos = $(this.dom.button).offset(); - var nHidden = this.dom.collection; - var nBackground = this.dom.background; - var iDivX = parseInt(oPos.left, 10); - var iDivY = parseInt(oPos.top + $(this.dom.button).outerHeight(), 10); - - if ( ! this.s.bCssPosition ) - { - nHidden.style.top = iDivY+"px"; - nHidden.style.left = iDivX+"px"; - } - - $(nHidden).css( { - 'display': 'block', - 'opacity': 0 - } ); - - nBackground.style.bottom ='0px'; - nBackground.style.right = '0px'; - - var oStyle = this.dom.catcher.style; - oStyle.height = $(this.dom.button).outerHeight()+"px"; - oStyle.width = $(this.dom.button).outerWidth()+"px"; - oStyle.top = oPos.top+"px"; - oStyle.left = iDivX+"px"; - - document.body.appendChild( nBackground ); - document.body.appendChild( nHidden ); - document.body.appendChild( this.dom.catcher ); - - /* This results in a very small delay for the end user but it allows the animation to be - * much smoother. If you don't want the animation, then the setTimeout can be removed - */ - $(nHidden).animate({"opacity": 1}, that.s.iOverlayFade); - $(nBackground).animate({"opacity": 0.1}, that.s.iOverlayFade, 'linear', function () { - /* In IE6 if you set the checked attribute of a hidden checkbox, then this is not visually - * reflected. As such, we need to do it here, once it is visible. Unbelievable. - */ - if ( $.browser && $.browser.msie && $.browser.version == "6.0" ) - { - that._fnDrawCallback(); - } - }); - - /* Visual corrections to try and keep the collection visible */ - if ( !this.s.bCssPosition ) - { - iLeft = ( this.s.sAlign=="left" ) ? - iDivX : - iDivX - $(nHidden).outerWidth() + $(this.dom.button).outerWidth(); - - nHidden.style.left = iLeft+"px"; - - var iDivWidth = $(nHidden).outerWidth(); - var iDivHeight = $(nHidden).outerHeight(); - var iDocWidth = $(document).width(); - - if ( iLeft + iDivWidth > iDocWidth ) - { - nHidden.style.left = (iDocWidth-iDivWidth)+"px"; - } - } - - this.s.hidden = false; - }, - - - /** - * Hide the show / hide list and the background - * @method _fnCollectionHide - * @returns void - * @private - */ - "_fnCollectionHide": function ( ) - { - var that = this; - - if ( !this.s.hidden && this.dom.collection !== null ) - { - this.s.hidden = true; - - $(this.dom.collection).animate({"opacity": 0}, that.s.iOverlayFade, function (e) { - this.style.display = "none"; - } ); - - $(this.dom.background).animate({"opacity": 0}, that.s.iOverlayFade, function (e) { - document.body.removeChild( that.dom.background ); - document.body.removeChild( that.dom.catcher ); - } ); - } - }, - - - /** - * Alter the colspan on any fnOpen rows - */ - "_fnAdjustOpenRows": function () - { - var aoOpen = this.s.dt.aoOpenRows; - var iVisible = this.s.dt.oApi._fnVisbleColumns( this.s.dt ); - - for ( var i=0, iLen=aoOpen.length ; i<iLen ; i++ ) { - aoOpen[i].nTr.getElementsByTagName('td')[0].colSpan = iVisible; - } - } -}; - - - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Static object methods - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/** - * Rebuild the collection for a given table, or all tables if no parameter given - * @method ColVis.fnRebuild - * @static - * @param object oTable DataTable instance to consider - optional - * @returns void - */ -ColVis.fnRebuild = function ( oTable ) -{ - var nTable = null; - if ( typeof oTable != 'undefined' ) - { - nTable = $.fn.dataTable.Api ? - new $.fn.dataTable.Api( oTable ).table().node() : - oTable.fnSettings().nTable; - } - - for ( var i=0, iLen=ColVis.aInstances.length ; i<iLen ; i++ ) - { - if ( typeof oTable == 'undefined' || nTable == ColVis.aInstances[i].s.dt.nTable ) - { - ColVis.aInstances[i].fnRebuild(); - } - } -}; - - -ColVis.defaults = { - /** - * Mode of activation. Can be 'click' or 'mouseover' - * @property activate - * @type string - * @default click - */ - active: 'click', - - /** - * Text used for the button - * @property buttonText - * @type string - * @default Show / hide columns - */ - buttonText: 'Show / hide columns', - - /** - * List of columns (integers) which should be excluded from the list - * @property aiExclude - * @type array - * @default [] - */ - aiExclude: [], - - /** - * Show restore button - * @property bRestore - * @type boolean - * @default false - */ - bRestore: false, - - /** - * Restore button text - * @property sRestore - * @type string - * @default Restore original - */ - sRestore: 'Restore original', - - /** - * Show Show-All button - * @property bShowAll - * @type boolean - * @default false - */ - bShowAll: false, - - /** - * Show All button text - * @property sShowAll - * @type string - * @default Restore original - */ - sShowAll: 'Show All', - - /** - * Position of the collection menu when shown - align "left" or "right" - * @property sAlign - * @type string - * @default left - */ - sAlign: 'left', - - /** - * Callback function to tell the user when the state has changed - * @property fnStateChange - * @type function - * @default null - */ - fnStateChange: null, - - /** - * Overlay animation duration in mS - * @property iOverlayFade - * @type integer|false - * @default 500 - */ - iOverlayFade: 500, - - /** - * Label callback for column names. Takes three parameters: 1. the - * column index, 2. the column title detected by DataTables and 3. the - * TH node for the column - * @property fnLabel - * @type function - * @default null - */ - fnLabel: null, - - /** - * Indicate if the column list should be positioned by Javascript, - * visually below the button or allow CSS to do the positioning - * @property bCssPosition - * @type boolean - * @default false - */ - bCssPosition: false, - - /** - * Group buttons - * @property aoGroups - * @type array - * @default [] - */ - aoGroups: [], - - /** - * Button ordering - 'alpha' (alphabetical) or 'column' (table column - * order) - * @property order - * @type string - * @default column - */ - order: 'column' -}; - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Static object properties - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/** - * Collection of all ColVis instances - * @property ColVis.aInstances - * @static - * @type Array - * @default [] - */ -ColVis.aInstances = []; - - - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Constants - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/** - * Name of this class - * @constant CLASS - * @type String - * @default ColVis - */ -ColVis.prototype.CLASS = "ColVis"; - - -/** - * ColVis version - * @constant VERSION - * @type String - * @default See code - */ -ColVis.VERSION = "1.1.2"; -ColVis.prototype.VERSION = ColVis.VERSION; - - - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Initialisation - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Register a new feature with DataTables - */ -if ( typeof $.fn.dataTable == "function" && - typeof $.fn.dataTableExt.fnVersionCheck == "function" && - $.fn.dataTableExt.fnVersionCheck('1.7.0') ) -{ - $.fn.dataTableExt.aoFeatures.push( { - "fnInit": function( oDTSettings ) { - var init = oDTSettings.oInit; - var colvis = new ColVis( oDTSettings, init.colVis || init.oColVis || {} ); - return colvis.button(); - }, - "cFeature": "C", - "sFeature": "ColVis" - } ); -} -else -{ - alert( "Warning: ColVis requires DataTables 1.7 or greater - www.datatables.net/download"); -} - - -// Make ColVis accessible from the DataTables instance -$.fn.dataTable.ColVis = ColVis; -$.fn.DataTable.ColVis = ColVis; - - -return ColVis; -}; // /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.ColVis ) { - // Otherwise simply initialise as normal, stopping multiple evaluation - factory( jQuery, jQuery.fn.dataTable ); -} - - -})(window, document); - +/*! ColVis 1.1.2 + * ©2010-2015 SpryMedia Ltd - datatables.net/license + */ + +/** + * @summary ColVis + * @description Controls for column visibility in DataTables + * @version 1.1.2 + * @file dataTables.colReorder.js + * @author SpryMedia Ltd (www.sprymedia.co.uk) + * @contact www.sprymedia.co.uk/contact + * @copyright Copyright 2010-2015 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) { + + +var factory = function( $, DataTable ) { +"use strict"; + +/** + * ColVis provides column visibility control for DataTables + * + * @class ColVis + * @constructor + * @param {object} DataTables settings object. With DataTables 1.10 this can + * also be and API instance, table node, jQuery collection or jQuery selector. + * @param {object} ColVis configuration options + */ +var ColVis = function( oDTSettings, oInit ) +{ + /* Santiy check that we are a new instance */ + if ( !this.CLASS || this.CLASS != "ColVis" ) + { + alert( "Warning: ColVis must be initialised with the keyword 'new'" ); + } + + if ( typeof oInit == 'undefined' ) + { + oInit = {}; + } + + var camelToHungarian = $.fn.dataTable.camelToHungarian; + if ( camelToHungarian ) { + camelToHungarian( ColVis.defaults, ColVis.defaults, true ); + camelToHungarian( ColVis.defaults, oInit ); + } + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Public class variables + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * @namespace Settings object which contains customisable information for + * ColVis instance. Augmented by ColVis.defaults + */ + this.s = { + /** + * DataTables settings object + * @property dt + * @type Object + * @default null + */ + "dt": null, + + /** + * Customisation object + * @property oInit + * @type Object + * @default passed in + */ + "oInit": oInit, + + /** + * Flag to say if the collection is hidden + * @property hidden + * @type boolean + * @default true + */ + "hidden": true, + + /** + * Store the original visibility settings so they could be restored + * @property abOriginal + * @type Array + * @default [] + */ + "abOriginal": [] + }; + + + /** + * @namespace Common and useful DOM elements for the class instance + */ + this.dom = { + /** + * Wrapper for the button - given back to DataTables as the node to insert + * @property wrapper + * @type Node + * @default null + */ + "wrapper": null, + + /** + * Activation button + * @property button + * @type Node + * @default null + */ + "button": null, + + /** + * Collection list node + * @property collection + * @type Node + * @default null + */ + "collection": null, + + /** + * Background node used for shading the display and event capturing + * @property background + * @type Node + * @default null + */ + "background": null, + + /** + * Element to position over the activation button to catch mouse events when using mouseover + * @property catcher + * @type Node + * @default null + */ + "catcher": null, + + /** + * List of button elements + * @property buttons + * @type Array + * @default [] + */ + "buttons": [], + + /** + * List of group button elements + * @property groupButtons + * @type Array + * @default [] + */ + "groupButtons": [], + + /** + * Restore button + * @property restore + * @type Node + * @default null + */ + "restore": null + }; + + /* Store global reference */ + ColVis.aInstances.push( this ); + + /* Constructor logic */ + this.s.dt = $.fn.dataTable.Api ? + new $.fn.dataTable.Api( oDTSettings ).settings()[0] : + oDTSettings; + + this._fnConstruct( oInit ); + return this; +}; + + + +ColVis.prototype = { + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Public methods + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * Get the ColVis instance's control button so it can be injected into the + * DOM + * @method button + * @returns {node} ColVis button + */ + button: function () + { + return this.dom.wrapper; + }, + + /** + * Alias of `rebuild` for backwards compatibility + * @method fnRebuild + */ + "fnRebuild": function () + { + this.rebuild(); + }, + + /** + * Rebuild the list of buttons for this instance (i.e. if there is a column + * header update) + * @method fnRebuild + */ + rebuild: function () + { + /* Remove the old buttons */ + for ( var i=this.dom.buttons.length-1 ; i>=0 ; i-- ) { + this.dom.collection.removeChild( this.dom.buttons[i] ); + } + this.dom.buttons.splice( 0, this.dom.buttons.length ); + this.dom.groupButtons.splice(0, this.dom.groupButtons.length); + + if ( this.dom.restore ) { + this.dom.restore.parentNode( this.dom.restore ); + } + + /* Re-add them (this is not the optimal way of doing this, it is fast and effective) */ + this._fnAddGroups(); + this._fnAddButtons(); + + /* Update the checkboxes */ + this._fnDrawCallback(); + }, + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Private methods (they are of course public in JS, but recommended as private) + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * Constructor logic + * @method _fnConstruct + * @returns void + * @private + */ + "_fnConstruct": function ( init ) + { + this._fnApplyCustomisation( init ); + + var that = this; + var i, iLen; + this.dom.wrapper = document.createElement('div'); + this.dom.wrapper.className = "ColVis"; + + this.dom.button = $( '<button />', { + 'class': !this.s.dt.bJUI ? + "ColVis_Button ColVis_MasterButton" : + "ColVis_Button ColVis_MasterButton ui-button ui-state-default" + } ) + .append( '<span>'+this.s.buttonText+'</span>' ) + .bind( this.s.activate=="mouseover" ? "mouseover" : "click", function (e) { + e.preventDefault(); + that._fnCollectionShow(); + } ) + .appendTo( this.dom.wrapper )[0]; + + this.dom.catcher = this._fnDomCatcher(); + this.dom.collection = this._fnDomCollection(); + this.dom.background = this._fnDomBackground(); + + this._fnAddGroups(); + this._fnAddButtons(); + + /* Store the original visibility information */ + for ( i=0, iLen=this.s.dt.aoColumns.length ; i<iLen ; i++ ) + { + this.s.abOriginal.push( this.s.dt.aoColumns[i].bVisible ); + } + + /* Update on each draw */ + this.s.dt.aoDrawCallback.push( { + "fn": function () { + that._fnDrawCallback.call( that ); + }, + "sName": "ColVis" + } ); + + /* If columns are reordered, then we need to update our exclude list and + * rebuild the displayed list + */ + $(this.s.dt.oInstance).bind( 'column-reorder.dt', function ( e, oSettings, oReorder ) { + for ( i=0, iLen=that.s.aiExclude.length ; i<iLen ; i++ ) { + that.s.aiExclude[i] = oReorder.aiInvertMapping[ that.s.aiExclude[i] ]; + } + + var mStore = that.s.abOriginal.splice( oReorder.iFrom, 1 )[0]; + that.s.abOriginal.splice( oReorder.iTo, 0, mStore ); + + that.fnRebuild(); + } ); + + $(this.s.dt.oInstance).bind( 'destroy.dt', function () { + $(that.dom.wrapper).remove(); + } ); + + // Set the initial state + this._fnDrawCallback(); + }, + + + /** + * Apply any customisation to the settings from the DataTables initialisation + * @method _fnApplyCustomisation + * @returns void + * @private + */ + "_fnApplyCustomisation": function ( init ) + { + $.extend( true, this.s, ColVis.defaults, init ); + + // Slightly messy overlap for the camelCase notation + if ( ! this.s.showAll && this.s.bShowAll ) { + this.s.showAll = this.s.sShowAll; + } + + if ( ! this.s.restore && this.s.bRestore ) { + this.s.restore = this.s.sRestore; + } + + // CamelCase to Hungarian for the column groups + var groups = this.s.groups; + var hungarianGroups = this.s.aoGroups; + if ( groups ) { + for ( var i=0, ien=groups.length ; i<ien ; i++ ) { + if ( groups[i].title ) { + hungarianGroups[i].sTitle = groups[i].title; + } + if ( groups[i].columns ) { + hungarianGroups[i].aiColumns = groups[i].columns; + } + } + } + }, + + + /** + * On each table draw, check the visibility checkboxes as needed. This allows any process to + * update the table's column visibility and ColVis will still be accurate. + * @method _fnDrawCallback + * @returns void + * @private + */ + "_fnDrawCallback": function () + { + var columns = this.s.dt.aoColumns; + var buttons = this.dom.buttons; + var groups = this.s.aoGroups; + var button; + + for ( var i=0, ien=buttons.length ; i<ien ; i++ ) { + button = buttons[i]; + + if ( button.__columnIdx !== undefined ) { + $('input', button).prop( 'checked', columns[ button.__columnIdx ].bVisible ); + } + } + + var allVisible = function ( columnIndeces ) { + for ( var k=0, kLen=columnIndeces.length ; k<kLen ; k++ ) + { + if ( columns[columnIndeces[k]].bVisible === false ) { return false; } + } + return true; + }; + var allHidden = function ( columnIndeces ) { + for ( var m=0 , mLen=columnIndeces.length ; m<mLen ; m++ ) + { + if ( columns[columnIndeces[m]].bVisible === true ) { return false; } + } + return true; + }; + + for ( var j=0, jLen=groups.length ; j<jLen ; j++ ) + { + if ( allVisible(groups[j].aiColumns) ) + { + $('input', this.dom.groupButtons[j]).prop('checked', true); + $('input', this.dom.groupButtons[j]).prop('indeterminate', false); + } + else if ( allHidden(groups[j].aiColumns) ) + { + $('input', this.dom.groupButtons[j]).prop('checked', false); + $('input', this.dom.groupButtons[j]).prop('indeterminate', false); + } + else + { + $('input', this.dom.groupButtons[j]).prop('indeterminate', true); + } + } + }, + + + /** + * Loop through the groups (provided in the settings) and create a button for each. + * @method _fnAddgroups + * @returns void + * @private + */ + "_fnAddGroups": function () + { + var nButton; + + if ( typeof this.s.aoGroups != 'undefined' ) + { + for ( var i=0, iLen=this.s.aoGroups.length ; i<iLen ; i++ ) + { + nButton = this._fnDomGroupButton( i ); + this.dom.groupButtons.push( nButton ); + this.dom.buttons.push( nButton ); + this.dom.collection.appendChild( nButton ); + } + } + }, + + + /** + * Loop through the columns in the table and as a new button for each one. + * @method _fnAddButtons + * @returns void + * @private + */ + "_fnAddButtons": function () + { + var + nButton, + columns = this.s.dt.aoColumns; + + if ( $.inArray( 'all', this.s.aiExclude ) === -1 ) { + for ( var i=0, iLen=columns.length ; i<iLen ; i++ ) + { + if ( $.inArray( i, this.s.aiExclude ) === -1 ) + { + nButton = this._fnDomColumnButton( i ); + nButton.__columnIdx = i; + this.dom.buttons.push( nButton ); + } + } + } + + if ( this.s.order === 'alpha' ) { + this.dom.buttons.sort( function ( a, b ) { + var titleA = columns[ a.__columnIdx ].sTitle; + var titleB = columns[ b.__columnIdx ].sTitle; + + return titleA === titleB ? + 0 : + titleA < titleB ? + -1 : + 1; + } ); + } + + if ( this.s.restore ) + { + nButton = this._fnDomRestoreButton(); + nButton.className += " ColVis_Restore"; + this.dom.buttons.push( nButton ); + } + + if ( this.s.showAll ) + { + nButton = this._fnDomShowXButton( this.s.showAll, true ); + nButton.className += " ColVis_ShowAll"; + this.dom.buttons.push( nButton ); + } + + if ( this.s.showNone ) + { + nButton = this._fnDomShowXButton( this.s.showNone, false ); + nButton.className += " ColVis_ShowNone"; + this.dom.buttons.push( nButton ); + } + + $(this.dom.collection).append( this.dom.buttons ); + }, + + + /** + * Create a button which allows a "restore" action + * @method _fnDomRestoreButton + * @returns {Node} Created button + * @private + */ + "_fnDomRestoreButton": function () + { + var + that = this, + dt = this.s.dt; + + return $( + '<li class="ColVis_Special '+(dt.bJUI ? 'ui-button ui-state-default' : '')+'">'+ + this.s.restore+ + '</li>' + ) + .click( function (e) { + for ( var i=0, iLen=that.s.abOriginal.length ; i<iLen ; i++ ) + { + that.s.dt.oInstance.fnSetColumnVis( i, that.s.abOriginal[i], false ); + } + that._fnAdjustOpenRows(); + that.s.dt.oInstance.fnAdjustColumnSizing( false ); + that.s.dt.oInstance.fnDraw( false ); + } )[0]; + }, + + + /** + * Create a button which allows show all and show node actions + * @method _fnDomShowXButton + * @returns {Node} Created button + * @private + */ + "_fnDomShowXButton": function ( str, action ) + { + var + that = this, + dt = this.s.dt; + + return $( + '<li class="ColVis_Special '+(dt.bJUI ? 'ui-button ui-state-default' : '')+'">'+ + str+ + '</li>' + ) + .click( function (e) { + for ( var i=0, iLen=that.s.abOriginal.length ; i<iLen ; i++ ) + { + if (that.s.aiExclude.indexOf(i) === -1) + { + that.s.dt.oInstance.fnSetColumnVis( i, action, false ); + } + } + that._fnAdjustOpenRows(); + that.s.dt.oInstance.fnAdjustColumnSizing( false ); + that.s.dt.oInstance.fnDraw( false ); + } )[0]; + }, + + + /** + * Create the DOM for a show / hide group button + * @method _fnDomGroupButton + * @param {int} i Group in question, order based on that provided in settings + * @returns {Node} Created button + * @private + */ + "_fnDomGroupButton": function ( i ) + { + var + that = this, + dt = this.s.dt, + oGroup = this.s.aoGroups[i]; + + return $( + '<li class="ColVis_Special '+(dt.bJUI ? 'ui-button ui-state-default' : '')+'">'+ + '<label>'+ + '<input type="checkbox" />'+ + '<span>'+oGroup.sTitle+'</span>'+ + '</label>'+ + '</li>' + ) + .click( function (e) { + var showHide = !$('input', this).is(":checked"); + if ( e.target.nodeName.toLowerCase() !== "li" ) + { + showHide = ! showHide; + } + + for ( var j=0 ; j < oGroup.aiColumns.length ; j++ ) + { + that.s.dt.oInstance.fnSetColumnVis( oGroup.aiColumns[j], showHide ); + } + } )[0]; + }, + + + /** + * Create the DOM for a show / hide button + * @method _fnDomColumnButton + * @param {int} i Column in question + * @returns {Node} Created button + * @private + */ + "_fnDomColumnButton": function ( i ) + { + var + that = this, + column = this.s.dt.aoColumns[i], + dt = this.s.dt; + + var title = this.s.fnLabel===null ? + column.sTitle : + this.s.fnLabel( i, column.sTitle, column.nTh ); + + return $( + '<li '+(dt.bJUI ? 'class="ui-button ui-state-default"' : '')+'>'+ + '<label>'+ + '<input type="checkbox" />'+ + '<span>'+title+'</span>'+ + '</label>'+ + '</li>' + ) + .click( function (e) { + var showHide = !$('input', this).is(":checked"); + if ( e.target.nodeName.toLowerCase() !== "li" ) + { + if ( e.target.nodeName.toLowerCase() == "input" || that.s.fnStateChange === null ) + { + showHide = ! showHide; + } + } + + /* Need to consider the case where the initialiser created more than one table - change the + * API index that DataTables is using + */ + var oldIndex = $.fn.dataTableExt.iApiIndex; + $.fn.dataTableExt.iApiIndex = that._fnDataTablesApiIndex.call(that); + + // Optimisation for server-side processing when scrolling - don't do a full redraw + if ( dt.oFeatures.bServerSide ) + { + that.s.dt.oInstance.fnSetColumnVis( i, showHide, false ); + that.s.dt.oInstance.fnAdjustColumnSizing( false ); + if (dt.oScroll.sX !== "" || dt.oScroll.sY !== "" ) + { + that.s.dt.oInstance.oApi._fnScrollDraw( that.s.dt ); + } + that._fnDrawCallback(); + } + else + { + that.s.dt.oInstance.fnSetColumnVis( i, showHide ); + } + + $.fn.dataTableExt.iApiIndex = oldIndex; /* Restore */ + + if ( that.s.fnStateChange !== null ) + { + if ( e.target.nodeName.toLowerCase() == "span" ) + { + e.preventDefault(); + } + that.s.fnStateChange.call( that, i, showHide ); + } + } )[0]; + }, + + + /** + * Get the position in the DataTables instance array of the table for this + * instance of ColVis + * @method _fnDataTablesApiIndex + * @returns {int} Index + * @private + */ + "_fnDataTablesApiIndex": function () + { + for ( var i=0, iLen=this.s.dt.oInstance.length ; i<iLen ; i++ ) + { + if ( this.s.dt.oInstance[i] == this.s.dt.nTable ) + { + return i; + } + } + return 0; + }, + + + /** + * Create the element used to contain list the columns (it is shown and + * hidden as needed) + * @method _fnDomCollection + * @returns {Node} div container for the collection + * @private + */ + "_fnDomCollection": function () + { + return $('<ul />', { + 'class': !this.s.dt.bJUI ? + "ColVis_collection" : + "ColVis_collection ui-buttonset ui-buttonset-multi" + } ) + .css( { + 'display': 'none', + 'opacity': 0, + 'position': ! this.s.bCssPosition ? + 'absolute' : + '' + } )[0]; + }, + + + /** + * An element to be placed on top of the activate button to catch events + * @method _fnDomCatcher + * @returns {Node} div container for the collection + * @private + */ + "_fnDomCatcher": function () + { + var + that = this, + nCatcher = document.createElement('div'); + nCatcher.className = "ColVis_catcher"; + + $(nCatcher).click( function () { + that._fnCollectionHide.call( that, null, null ); + } ); + + return nCatcher; + }, + + + /** + * Create the element used to shade the background, and capture hide events (it is shown and + * hidden as needed) + * @method _fnDomBackground + * @returns {Node} div container for the background + * @private + */ + "_fnDomBackground": function () + { + var that = this; + + var background = $('<div></div>') + .addClass( 'ColVis_collectionBackground' ) + .css( 'opacity', 0 ) + .click( function () { + that._fnCollectionHide.call( that, null, null ); + } ); + + /* When considering a mouse over action for the activation, we also consider a mouse out + * which is the same as a mouse over the background - without all the messing around of + * bubbling events. Use the catcher element to avoid messing around with bubbling + */ + if ( this.s.activate == "mouseover" ) + { + background.mouseover( function () { + that.s.overcollection = false; + that._fnCollectionHide.call( that, null, null ); + } ); + } + + return background[0]; + }, + + + /** + * Show the show / hide list and the background + * @method _fnCollectionShow + * @returns void + * @private + */ + "_fnCollectionShow": function () + { + var that = this, i, iLen, iLeft; + var oPos = $(this.dom.button).offset(); + var nHidden = this.dom.collection; + var nBackground = this.dom.background; + var iDivX = parseInt(oPos.left, 10); + var iDivY = parseInt(oPos.top + $(this.dom.button).outerHeight(), 10); + + if ( ! this.s.bCssPosition ) + { + nHidden.style.top = iDivY+"px"; + nHidden.style.left = iDivX+"px"; + } + + $(nHidden).css( { + 'display': 'block', + 'opacity': 0 + } ); + + nBackground.style.bottom ='0px'; + nBackground.style.right = '0px'; + + var oStyle = this.dom.catcher.style; + oStyle.height = $(this.dom.button).outerHeight()+"px"; + oStyle.width = $(this.dom.button).outerWidth()+"px"; + oStyle.top = oPos.top+"px"; + oStyle.left = iDivX+"px"; + + document.body.appendChild( nBackground ); + document.body.appendChild( nHidden ); + document.body.appendChild( this.dom.catcher ); + + /* This results in a very small delay for the end user but it allows the animation to be + * much smoother. If you don't want the animation, then the setTimeout can be removed + */ + $(nHidden).animate({"opacity": 1}, that.s.iOverlayFade); + $(nBackground).animate({"opacity": 0.1}, that.s.iOverlayFade, 'linear', function () { + /* In IE6 if you set the checked attribute of a hidden checkbox, then this is not visually + * reflected. As such, we need to do it here, once it is visible. Unbelievable. + */ + if ( $.browser && $.browser.msie && $.browser.version == "6.0" ) + { + that._fnDrawCallback(); + } + }); + + /* Visual corrections to try and keep the collection visible */ + if ( !this.s.bCssPosition ) + { + iLeft = ( this.s.sAlign=="left" ) ? + iDivX : + iDivX - $(nHidden).outerWidth() + $(this.dom.button).outerWidth(); + + nHidden.style.left = iLeft+"px"; + + var iDivWidth = $(nHidden).outerWidth(); + var iDivHeight = $(nHidden).outerHeight(); + var iDocWidth = $(document).width(); + + if ( iLeft + iDivWidth > iDocWidth ) + { + nHidden.style.left = (iDocWidth-iDivWidth)+"px"; + } + } + + this.s.hidden = false; + }, + + + /** + * Hide the show / hide list and the background + * @method _fnCollectionHide + * @returns void + * @private + */ + "_fnCollectionHide": function ( ) + { + var that = this; + + if ( !this.s.hidden && this.dom.collection !== null ) + { + this.s.hidden = true; + + $(this.dom.collection).animate({"opacity": 0}, that.s.iOverlayFade, function (e) { + this.style.display = "none"; + } ); + + $(this.dom.background).animate({"opacity": 0}, that.s.iOverlayFade, function (e) { + document.body.removeChild( that.dom.background ); + document.body.removeChild( that.dom.catcher ); + } ); + } + }, + + + /** + * Alter the colspan on any fnOpen rows + */ + "_fnAdjustOpenRows": function () + { + var aoOpen = this.s.dt.aoOpenRows; + var iVisible = this.s.dt.oApi._fnVisbleColumns( this.s.dt ); + + for ( var i=0, iLen=aoOpen.length ; i<iLen ; i++ ) { + aoOpen[i].nTr.getElementsByTagName('td')[0].colSpan = iVisible; + } + } +}; + + + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Static object methods + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/** + * Rebuild the collection for a given table, or all tables if no parameter given + * @method ColVis.fnRebuild + * @static + * @param object oTable DataTable instance to consider - optional + * @returns void + */ +ColVis.fnRebuild = function ( oTable ) +{ + var nTable = null; + if ( typeof oTable != 'undefined' ) + { + nTable = $.fn.dataTable.Api ? + new $.fn.dataTable.Api( oTable ).table().node() : + oTable.fnSettings().nTable; + } + + for ( var i=0, iLen=ColVis.aInstances.length ; i<iLen ; i++ ) + { + if ( typeof oTable == 'undefined' || nTable == ColVis.aInstances[i].s.dt.nTable ) + { + ColVis.aInstances[i].fnRebuild(); + } + } +}; + + +ColVis.defaults = { + /** + * Mode of activation. Can be 'click' or 'mouseover' + * @property activate + * @type string + * @default click + */ + active: 'click', + + /** + * Text used for the button + * @property buttonText + * @type string + * @default Show / hide columns + */ + buttonText: 'Show / hide columns', + + /** + * List of columns (integers) which should be excluded from the list + * @property aiExclude + * @type array + * @default [] + */ + aiExclude: [], + + /** + * Show restore button + * @property bRestore + * @type boolean + * @default false + */ + bRestore: false, + + /** + * Restore button text + * @property sRestore + * @type string + * @default Restore original + */ + sRestore: 'Restore original', + + /** + * Show Show-All button + * @property bShowAll + * @type boolean + * @default false + */ + bShowAll: false, + + /** + * Show All button text + * @property sShowAll + * @type string + * @default Restore original + */ + sShowAll: 'Show All', + + /** + * Position of the collection menu when shown - align "left" or "right" + * @property sAlign + * @type string + * @default left + */ + sAlign: 'left', + + /** + * Callback function to tell the user when the state has changed + * @property fnStateChange + * @type function + * @default null + */ + fnStateChange: null, + + /** + * Overlay animation duration in mS + * @property iOverlayFade + * @type integer|false + * @default 500 + */ + iOverlayFade: 500, + + /** + * Label callback for column names. Takes three parameters: 1. the + * column index, 2. the column title detected by DataTables and 3. the + * TH node for the column + * @property fnLabel + * @type function + * @default null + */ + fnLabel: null, + + /** + * Indicate if the column list should be positioned by Javascript, + * visually below the button or allow CSS to do the positioning + * @property bCssPosition + * @type boolean + * @default false + */ + bCssPosition: false, + + /** + * Group buttons + * @property aoGroups + * @type array + * @default [] + */ + aoGroups: [], + + /** + * Button ordering - 'alpha' (alphabetical) or 'column' (table column + * order) + * @property order + * @type string + * @default column + */ + order: 'column' +}; + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Static object properties + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/** + * Collection of all ColVis instances + * @property ColVis.aInstances + * @static + * @type Array + * @default [] + */ +ColVis.aInstances = []; + + + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Constants + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/** + * Name of this class + * @constant CLASS + * @type String + * @default ColVis + */ +ColVis.prototype.CLASS = "ColVis"; + + +/** + * ColVis version + * @constant VERSION + * @type String + * @default See code + */ +ColVis.VERSION = "1.1.2"; +ColVis.prototype.VERSION = ColVis.VERSION; + + + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Initialisation + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Register a new feature with DataTables + */ +if ( typeof $.fn.dataTable == "function" && + typeof $.fn.dataTableExt.fnVersionCheck == "function" && + $.fn.dataTableExt.fnVersionCheck('1.7.0') ) +{ + $.fn.dataTableExt.aoFeatures.push( { + "fnInit": function( oDTSettings ) { + var init = oDTSettings.oInit; + var colvis = new ColVis( oDTSettings, init.colVis || init.oColVis || {} ); + return colvis.button(); + }, + "cFeature": "C", + "sFeature": "ColVis" + } ); +} +else +{ + alert( "Warning: ColVis requires DataTables 1.7 or greater - www.datatables.net/download"); +} + + +// Make ColVis accessible from the DataTables instance +$.fn.dataTable.ColVis = ColVis; +$.fn.DataTable.ColVis = ColVis; + + +return ColVis; +}; // /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.ColVis ) { + // Otherwise simply initialise as normal, stopping multiple evaluation + factory( jQuery, jQuery.fn.dataTable ); +} + + +})(window, document); +