/* * File:        ColVis.js * Version:     1.0.8 * 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    */    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": [],            /**            * 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": true,            /**            * 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": 100,            /**            * 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": [],            /**            * 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._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._fnAddButtons();            /* Store the original visbility 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', 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();            });        },        /**        * Apply any customisation to the settings from the DataTables initialisation        *  @method  _fnApplyCustomisation        *  @returns void        *  @private         */        "_fnApplyCustomisation": function () {            var oConfig = this.s.oInit;            if (typeof oConfig.activate != 'undefined') {                this.s.activate = oConfig.activate;            }            if (typeof oConfig.buttonText != 'undefined') {                this.s.buttonText = oConfig.buttonText;            }            if (typeof oConfig.aiExclude != 'undefined') {                this.s.aiExclude = oConfig.aiExclude;            }            if (typeof oConfig.bRestore != 'undefined') {                this.s.bRestore = oConfig.bRestore;            }            if (typeof oConfig.sRestore != 'undefined') {                this.s.sRestore = oConfig.sRestore;            }            if (typeof oConfig.bShowAll != 'undefined') {                this.s.bShowAll = oConfig.bShowAll;            }            if (typeof oConfig.sShowAll != 'undefined') {                this.s.sShowAll = oConfig.sShowAll;            }            if (typeof oConfig.sAlign != 'undefined') {                this.s.sAlign = oConfig.sAlign;            }            if (typeof oConfig.fnStateChange != 'undefined') {                this.s.fnStateChange = oConfig.fnStateChange;            }            if (typeof oConfig.iOverlayFade != 'undefined') {                this.s.iOverlayFade = oConfig.iOverlayFade;            }            if (typeof oConfig.fnLabel != 'undefined') {                this.s.fnLabel = oConfig.fnLabel;            }            if (typeof oConfig.sSize != 'undefined') {                this.s.sSize = oConfig.sSize;            }            if (typeof oConfig.bCssPosition != 'undefined') {                this.s.bCssPosition = oConfig.bCssPosition;            }        },        /**        * 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 aoColumns = this.s.dt.aoColumns;            for (var i = 0, iLen = aoColumns.length; i < iLen; i++) {                if (this.dom.buttons[i] !== null) {                    if (aoColumns[i].bVisible) {                        $('input', this.dom.buttons[i]).attr('checked', 'checked');                    }                    else {                        $('input', this.dom.buttons[i]).removeAttr('checked');                    }                }            }        },        /**        * Loop through the columns in the table and as a new button for each one.        *  @method  _fnAddButtons        *  @returns void        *  @private         */        "_fnAddButtons": function () {            var 			nButton,			sExclude = "," + this.s.aiExclude.join(',') + ",";            for (var i = 0, iLen = this.s.dt.aoColumns.length; i < iLen; i++) {                if (sExclude.indexOf("," + i + ",") == -1) {                    nButton = this._fnDomColumnButton(i);                    this.dom.buttons.push(nButton);                    this.dom.collection.appendChild(nButton);                }                else {                    this.dom.buttons.push(null);                }            }            if (this.s.bRestore) {                nButton = this._fnDomRestoreButton();                nButton.className += " ColVis_Restore";                this.dom.buttons.push(nButton);                this.dom.collection.appendChild(nButton);            }            if (this.s.bShowAll) {                nButton = this._fnDomShowAllButton();                nButton.className += " ColVis_ShowAll";                this.dom.buttons.push(nButton);                this.dom.collection.appendChild(nButton);            }        },        /**        * Create a button which allows a "restore" action        *  @method  _fnDomRestoreButton        *  @returns {Node} Created button        *  @private         */        "_fnDomRestoreButton": function () {            var 			that = this,			nButton = document.createElement('button'),			nSpan = document.createElement('span');            nButton.className = !this.s.dt.bJUI ? "ColVis_Button TableTools_Button" :			"ColVis_Button TableTools_Button ui-button ui-state-default";            nButton.appendChild(nSpan);            $(nSpan).html('<span class="ColVis_title">' + this.s.sRestore + '</span>');            $(nButton).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);            });            return nButton;        },        /**        * Create a button which allows a "show all" action        *  @method  _fnDomShowAllButton        *  @returns {Node} Created button        *  @private         */        "_fnDomShowAllButton": function () {            var 			that = this,			nButton = document.createElement('button'),			nSpan = document.createElement('span');            nButton.className = !this.s.dt.bJUI ? "ColVis_Button TableTools_Button" :			"ColVis_Button TableTools_Button ui-button ui-state-default";            nButton.appendChild(nSpan);            $(nSpan).html('<span class="ColVis_title">' + this.s.sShowAll + '</span>');            $(nButton).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, true, false);                    }                }                that._fnAdjustOpenRows();                that.s.dt.oInstance.fnAdjustColumnSizing(false);                that.s.dt.oInstance.fnDraw(false);            });            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(			'<span class="ColVis_radio"><input type="checkbox"/></span>' +			'<span class="ColVis_title">' + sTitle + '</span>');            $(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 < iLen; i++) {                if (this.s.dt.oInstance[i] == this.s.dt.nTable) {                    return i;                }            }            return 0;        },        /**        * Create the DOM needed for the button and apply some base properties. All buttons start here        *  @method  _fnDomBaseButton        *  @param   {String} text Button text        *  @returns {Node} DIV element for the button        *  @private         */        "_fnDomBaseButton": function (text) {            var 			that = this,			nButton = document.createElement('button'),			nSpan = document.createElement('span'),			sEvent = this.s.activate == "mouseover" ? "mouseover" : "click";            nButton.className = !this.s.dt.bJUI ? "ColVis_Button TableTools_Button" :			"ColVis_Button TableTools_Button ui-button ui-state-default";            nButton.appendChild(nSpan);            nSpan.innerHTML = text;            $(nButton).bind(sEvent, function (e) {                that._fnCollectionShow();                e.preventDefault();            });            return nButton;        },        /**        * 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 () {            var that = this;            var nHidden = document.createElement('div');            nHidden.style.display = "none";            nHidden.className = !this.s.dt.bJUI ? "ColVis_collection TableTools_collection" :			"ColVis_collection TableTools_collection ui-buttonset ui-buttonset-multi";            if (!this.s.bCssPosition) {                nHidden.style.position = "absolute";            }            $(nHidden).css('opacity', 0);            return nHidden;        },        /**        * 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 TableTools_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 nBackground = document.createElement('div');            nBackground.style.position = "absolute";            nBackground.style.left = "0px";            nBackground.style.top = "0px";            nBackground.className = "ColVis_collectionBackground TableTools_collectionBackground";            $(nBackground).css('opacity', 0);            $(nBackground).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") {                $(nBackground).mouseover(function () {                    that.s.overcollection = false;                    that._fnCollectionHide.call(that, null, null);                });            }            return nBackground;        },        /**        * Show the show / hide list and the background        *  @method  _fnCollectionShow        *  @returns void        *  @private         */        "_fnCollectionShow": function () {            var that = this, i, iLen;            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.style.display = "block";            $(nHidden).css('opacity', 0);            var iWinHeight = $(window).height(), iDocHeight = $(document).height(),		 	iWinWidth = $(window).width(), iDocWidth = $(document).width();            nBackground.style.height = ((iWinHeight > iDocHeight) ? iWinHeight : iDocHeight) + "px";            nBackground.style.width = ((iWinWidth < iDocWidth) ? iWinWidth : iDocWidth) + "px";            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);            /* Resize the buttons */            if (this.s.sSize == "auto") {                var aiSizes = [];                this.dom.collection.style.width = "auto";                for (i = 0, iLen = this.dom.buttons.length; i < iLen; i++) {                    if (this.dom.buttons[i] !== null) {                        this.dom.buttons[i].style.width = "auto";                        aiSizes.push($(this.dom.buttons[i]).outerWidth());                    }                }                iMax = Math.max.apply(window, aiSizes);                for (i = 0, iLen = this.dom.buttons.length; i < iLen; i++) {                    if (this.dom.buttons[i] !== null) {                        this.dom.buttons[i].style.width = iMax + "px";                    }                }                this.dom.collection.style.width = iMax + "px";            }            /* Visual corrections to try and keep the collection visible */            if (!this.s.bCssPosition) {                nHidden.style.left = this.s.sAlign == "left" ?				iDivX + "px" : (iDivX - $(nHidden).outerWidth() + $(this.dom.button).outerWidth()) + "px";                var iDivWidth = $(nHidden).outerWidth();                var iDivHeight = $(nHidden).outerHeight();                if (iDivX + iDivWidth > iDocWidth) {                    nHidden.style.left = (iDocWidth - iDivWidth) + "px";                }            }            /* 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            */            setTimeout(function () {                $(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 (jQuery.browser.msie && jQuery.browser.version == "6.0") {                        that._fnDrawCallback();                    }                });            }, 10);            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 = 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();            }        }    };    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *    * 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.0.8";    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 = (typeof oDTSettings.oInit.oColVis == 'undefined') ?				{} : oDTSettings.oInit.oColVis;                var oColvis = new ColVis(oDTSettings, init);                return oColvis.dom.wrapper;            },            "cFeature": "C",            "sFeature": "ColVis"        });    }    else {        alert("Warning: ColVis requires DataTables 1.7 or greater - www.datatables.net/download");    }})(jQuery);