/* * File: ColVis.js * Version: 1.1.0-dev * CVS: $Id$ * Description: Controls for column visiblity in DataTables * Author: Allan Jardine (www.sprymedia.co.uk) * Created: Wed Sep 15 18:23:29 BST 2010 * Modified: $Date$ by $Author$ * Language: Javascript * License: GPL v2 or BSD 3 point style * Project: Just a little bit of fun :-) * Contact: www.sprymedia.co.uk/contact * * Copyright 2010-2011 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($) { /** * ColVis provides column visiblity control for DataTables * @class ColVis * @constructor * @param {object} DataTables settings object */ 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 = {}; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Public class variables * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** * @namespace Settings object which contains customisable information for ColVis instance */ this.s = { /** * DataTables settings object * @property dt * @type Object * @default null */ "dt": null, /** * Customisation object * @property oInit * @type Object * @default passed in */ "oInit": oInit, /** * Callback function to tell the user when the state has changed * @property fnStateChange * @type function * @default null */ "fnStateChange": null, /** * Mode of activation. Can be 'click' or 'mouseover' * @property activate * @type String * @default click */ "activate": "click", /** * Position of the collection menu when shown - align "left" or "right" * @property sAlign * @type String * @default right */ "sAlign": "left", /** * Text used for the button * @property buttonText * @type String * @default Show / hide columns */ "buttonText": "Show / hide columns", /** * Flag to say if the collection is hidden * @property hidden * @type boolean * @default true */ "hidden": true, /** * List of columns (integers) which should be excluded from the list * @property aiExclude * @type Array * @default [] */ "aiExclude": [], /** * Group buttons * @property aoGroups * @type Array * @default [] */ "aoGroups": [], /** * Store the original viisbility settings so they could be restored * @property abOriginal * @type Array * @default [] */ "abOriginal": [], /** * Show Show-All button * @property bShowAll * @type Array * @default [] */ "bShowAll": false, /** * Show All button text * @property sShowAll * @type String * @default Restore original */ "sShowAll": "Show All", /** * Show restore button * @property bRestore * @type Array * @default [] */ "bRestore": false, /** * Restore button text * @property sRestore * @type String * @default Restore original */ "sRestore": "Restore original", /** * Overlay animation duration in mS * @property iOverlayFade * @type Integer * @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 ColVis should automatically calculate the size of buttons or not. The default * is for it to do so. Set to "css" to disable the automatic sizing * @property sSize * @type String * @default auto */ "sSize": "auto", /** * 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 }; /** * @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 = oDTSettings; this._fnConstruct(); return this; }; ColVis.prototype = { /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Public methods * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** * Rebuild the list of buttons for this instance (i.e. if there is a column header update) * @method fnRebuild * @returns void */ "fnRebuild": function () { /* Remove the old buttons */ for ( var i=this.dom.buttons.length-1 ; i>=0 ; i-- ) { if ( this.dom.buttons[i] !== null ) { this.dom.collection.removeChild( this.dom.buttons[i] ); } } this.dom.buttons.splice( 0, this.dom.buttons.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 () { this._fnApplyCustomisation(); var that = this; var i, iLen; this.dom.wrapper = document.createElement('div'); this.dom.wrapper.className = "ColVis TableTools"; this.dom.button = this._fnDomBaseButton( this.s.buttonText ); this.dom.button.className += " ColVis_MasterButton"; this.dom.wrapper.appendChild( this.dom.button ); this.dom.catcher = this._fnDomCatcher(); this.dom.collection = this._fnDomCollection(); this.dom.background = this._fnDomBackground(); this._fnAddGroups(); this._fnAddButtons(); /* Store the original visbility information */ for ( i=0, iLen=this.s.dt.aoColumns.length ; i'+this.s.sRestore+'' ); $(nButton).click( function (e) { for ( var i=0, iLen=that.s.abOriginal.length ; i'+this.s.sShowAll+'' ); $(nButton).click( function (e) { for ( var i=0, iLen=that.s.abOriginal.length ; i'+ ''+sTitle+'' ); $(nButton).click( function (e) { var showHide = !$('input', this).is(":checked"); if ( e.target.nodeName.toLowerCase() == "input" ) { showHide = $('input', this).is(":checked"); } for ( var j=0 ; j < oGroup.aiColumns.length ; j++ ) { that.s.dt.oInstance.fnSetColumnVis( oGroup.aiColumns[j], showHide ); } }); return nButton; }, /** * 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, oColumn = this.s.dt.aoColumns[i], nButton = document.createElement('button'), nSpan = document.createElement('span'), dt = this.s.dt; nButton.className = !dt.bJUI ? "ColVis_Button TableTools_Button" : "ColVis_Button TableTools_Button ui-button ui-state-default"; nButton.appendChild( nSpan ); var sTitle = this.s.fnLabel===null ? oColumn.sTitle : this.s.fnLabel( i, oColumn.sTitle, oColumn.nTh ); $(nSpan).html( ''+ ''+sTitle+'' ); $(nButton).click( function (e) { var showHide = !$('input', this).is(":checked"); if ( e.target.nodeName.toLowerCase() == "input" ) { showHide = $('input', this).is(":checked"); } /* 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 && (dt.oScroll.sX !== "" || dt.oScroll.sY !== "" ) ) { that.s.dt.oInstance.fnSetColumnVis( i, showHide, false ); that.s.dt.oInstance.fnAdjustColumnSizing( false ); 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 ) { that.s.fnStateChange.call( that, i, showHide ); } } ); return nButton; }, /** * 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