src/pyams_skin/resources/js/ext/jquery-dataTables-colVis.js
changeset 0 bb4aabe07487
equal deleted inserted replaced
-1:000000000000 0:bb4aabe07487
       
     1 /*! ColVis 1.1.0
       
     2  * ©2010-2014 SpryMedia Ltd - datatables.net/license
       
     3  */
       
     4 
       
     5 /**
       
     6  * @summary     ColVis
       
     7  * @description Controls for column visibility in DataTables
       
     8  * @version     1.1.0
       
     9  * @file        dataTables.colReorder.js
       
    10  * @author      SpryMedia Ltd (www.sprymedia.co.uk)
       
    11  * @contact     www.sprymedia.co.uk/contact
       
    12  * @copyright   Copyright 2010-2014 SpryMedia Ltd.
       
    13  *
       
    14  * This source file is free software, available under the following license:
       
    15  *   MIT license - http://datatables.net/license/mit
       
    16  *
       
    17  * This source file is distributed in the hope that it will be useful, but
       
    18  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
       
    19  * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
       
    20  *
       
    21  * For details please refer to: http://www.datatables.net
       
    22  */
       
    23 
       
    24 (function (window, document, undefined) {
       
    25 
       
    26 
       
    27 	var factory = function ($, DataTable) {
       
    28 		"use strict";
       
    29 
       
    30 		/**
       
    31 		 * ColVis provides column visibility control for DataTables
       
    32 		 *
       
    33 		 * @class ColVis
       
    34 		 * @constructor
       
    35 		 * @param {object} DataTables settings object. With DataTables 1.10 this can
       
    36 		 *   also be and API instance, table node, jQuery collection or jQuery selector.
       
    37 		 * @param {object} ColVis configuration options
       
    38 		 */
       
    39 		var ColVis = function (oDTSettings, oInit) {
       
    40 			/* Santiy check that we are a new instance */
       
    41 			if (!this.CLASS || this.CLASS != "ColVis") {
       
    42 				alert("Warning: ColVis must be initialised with the keyword 'new'");
       
    43 			}
       
    44 
       
    45 			if (typeof oInit == 'undefined') {
       
    46 				oInit = {};
       
    47 			}
       
    48 
       
    49 			if ($.fn.dataTable.camelToHungarian) {
       
    50 				$.fn.dataTable.camelToHungarian(ColVis.defaults, oInit);
       
    51 			}
       
    52 
       
    53 
       
    54 			/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
       
    55 			 * Public class variables
       
    56 			 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
       
    57 
       
    58 			/**
       
    59 			 * @namespace Settings object which contains customisable information for
       
    60 			 *     ColVis instance. Augmented by ColVis.defaults
       
    61 			 */
       
    62 			this.s = {
       
    63 				/**
       
    64 				 * DataTables settings object
       
    65 				 *  @property dt
       
    66 				 *  @type     Object
       
    67 				 *  @default  null
       
    68 				 */
       
    69 				"dt": null,
       
    70 
       
    71 				/**
       
    72 				 * Customisation object
       
    73 				 *  @property oInit
       
    74 				 *  @type     Object
       
    75 				 *  @default  passed in
       
    76 				 */
       
    77 				"oInit": oInit,
       
    78 
       
    79 				/**
       
    80 				 * Flag to say if the collection is hidden
       
    81 				 *  @property hidden
       
    82 				 *  @type     boolean
       
    83 				 *  @default  true
       
    84 				 */
       
    85 				"hidden": true,
       
    86 
       
    87 				/**
       
    88 				 * Store the original visibility settings so they could be restored
       
    89 				 *  @property abOriginal
       
    90 				 *  @type     Array
       
    91 				 *  @default  []
       
    92 				 */
       
    93 				"abOriginal": []
       
    94 			};
       
    95 
       
    96 
       
    97 			/**
       
    98 			 * @namespace Common and useful DOM elements for the class instance
       
    99 			 */
       
   100 			this.dom = {
       
   101 				/**
       
   102 				 * Wrapper for the button - given back to DataTables as the node to insert
       
   103 				 *  @property wrapper
       
   104 				 *  @type     Node
       
   105 				 *  @default  null
       
   106 				 */
       
   107 				"wrapper": null,
       
   108 
       
   109 				/**
       
   110 				 * Activation button
       
   111 				 *  @property button
       
   112 				 *  @type     Node
       
   113 				 *  @default  null
       
   114 				 */
       
   115 				"button": null,
       
   116 
       
   117 				/**
       
   118 				 * Collection list node
       
   119 				 *  @property collection
       
   120 				 *  @type     Node
       
   121 				 *  @default  null
       
   122 				 */
       
   123 				"collection": null,
       
   124 
       
   125 				/**
       
   126 				 * Background node used for shading the display and event capturing
       
   127 				 *  @property background
       
   128 				 *  @type     Node
       
   129 				 *  @default  null
       
   130 				 */
       
   131 				"background": null,
       
   132 
       
   133 				/**
       
   134 				 * Element to position over the activation button to catch mouse events when using mouseover
       
   135 				 *  @property catcher
       
   136 				 *  @type     Node
       
   137 				 *  @default  null
       
   138 				 */
       
   139 				"catcher": null,
       
   140 
       
   141 				/**
       
   142 				 * List of button elements
       
   143 				 *  @property buttons
       
   144 				 *  @type     Array
       
   145 				 *  @default  []
       
   146 				 */
       
   147 				"buttons": [],
       
   148 
       
   149 				/**
       
   150 				 * List of group button elements
       
   151 				 *  @property groupButtons
       
   152 				 *  @type     Array
       
   153 				 *  @default  []
       
   154 				 */
       
   155 				"groupButtons": [],
       
   156 
       
   157 				/**
       
   158 				 * Restore button
       
   159 				 *  @property restore
       
   160 				 *  @type     Node
       
   161 				 *  @default  null
       
   162 				 */
       
   163 				"restore": null
       
   164 			};
       
   165 
       
   166 			/* Store global reference */
       
   167 			ColVis.aInstances.push(this);
       
   168 
       
   169 			/* Constructor logic */
       
   170 			this.s.dt = $.fn.dataTable.Api ?
       
   171 				new $.fn.dataTable.Api(oDTSettings).settings()[0] :
       
   172 				oDTSettings;
       
   173 
       
   174 			this._fnConstruct(oInit);
       
   175 			return this;
       
   176 		};
       
   177 
       
   178 
       
   179 		ColVis.prototype = {
       
   180 			/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
       
   181 			 * Public methods
       
   182 			 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
       
   183 
       
   184 			/**
       
   185 			 * Get the ColVis instance's control button so it can be injected into the
       
   186 			 * DOM
       
   187 			 *  @method  button
       
   188 			 *  @returns {node} ColVis button
       
   189 			 */
       
   190 			button: function () {
       
   191 				return this.dom.wrapper;
       
   192 			},
       
   193 
       
   194 			/**
       
   195 			 * Alias of `rebuild` for backwards compatibility
       
   196 			 *  @method  fnRebuild
       
   197 			 */
       
   198 			"fnRebuild": function () {
       
   199 				this.rebuild();
       
   200 			},
       
   201 
       
   202 			/**
       
   203 			 * Rebuild the list of buttons for this instance (i.e. if there is a column
       
   204 			 * header update)
       
   205 			 *  @method  fnRebuild
       
   206 			 */
       
   207 			rebuild: function () {
       
   208 				/* Remove the old buttons */
       
   209 				for (var i = this.dom.buttons.length - 1; i >= 0; i--) {
       
   210 					this.dom.collection.removeChild(this.dom.buttons[i]);
       
   211 				}
       
   212 				this.dom.buttons.splice(0, this.dom.buttons.length);
       
   213 
       
   214 				if (this.dom.restore) {
       
   215 					this.dom.restore.parentNode(this.dom.restore);
       
   216 				}
       
   217 
       
   218 				/* Re-add them (this is not the optimal way of doing this, it is fast and effective) */
       
   219 				this._fnAddGroups();
       
   220 				this._fnAddButtons();
       
   221 
       
   222 				/* Update the checkboxes */
       
   223 				this._fnDrawCallback();
       
   224 			},
       
   225 
       
   226 
       
   227 			/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
       
   228 			 * Private methods (they are of course public in JS, but recommended as private)
       
   229 			 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
       
   230 
       
   231 			/**
       
   232 			 * Constructor logic
       
   233 			 *  @method  _fnConstruct
       
   234 			 *  @returns void
       
   235 			 *  @private
       
   236 			 */
       
   237 			"_fnConstruct": function (init) {
       
   238 				this._fnApplyCustomisation(init);
       
   239 
       
   240 				var that = this;
       
   241 				var i, iLen;
       
   242 				this.dom.wrapper = document.createElement('div');
       
   243 				this.dom.wrapper.className = "ColVis";
       
   244 
       
   245 				this.dom.button = $('<button />', {
       
   246 					'class': !this.s.dt.bJUI ?
       
   247 						"ColVis_Button ColVis_MasterButton" :
       
   248 						"ColVis_Button ColVis_MasterButton ui-button ui-state-default"
       
   249 				})
       
   250 					.append('<span>' + this.s.buttonText + '</span>')
       
   251 					.bind(this.s.activate == "mouseover" ? "mouseover" : "click", function (e) {
       
   252 							  e.preventDefault();
       
   253 							  that._fnCollectionShow();
       
   254 						  })
       
   255 					.appendTo(this.dom.wrapper)[0];
       
   256 
       
   257 				this.dom.catcher = this._fnDomCatcher();
       
   258 				this.dom.collection = this._fnDomCollection();
       
   259 				this.dom.background = this._fnDomBackground();
       
   260 
       
   261 				this._fnAddGroups();
       
   262 				this._fnAddButtons();
       
   263 
       
   264 				/* Store the original visibility information */
       
   265 				for (i = 0, iLen = this.s.dt.aoColumns.length; i < iLen; i++) {
       
   266 					this.s.abOriginal.push(this.s.dt.aoColumns[i].bVisible);
       
   267 				}
       
   268 
       
   269 				/* Update on each draw */
       
   270 				this.s.dt.aoDrawCallback.push({
       
   271 												  "fn": function () {
       
   272 													  that._fnDrawCallback.call(that);
       
   273 												  },
       
   274 												  "sName": "ColVis"
       
   275 											  });
       
   276 
       
   277 				/* If columns are reordered, then we need to update our exclude list and
       
   278 				 * rebuild the displayed list
       
   279 				 */
       
   280 				$(this.s.dt.oInstance).bind('column-reorder', function (e, oSettings, oReorder) {
       
   281 					for (i = 0, iLen = that.s.aiExclude.length; i < iLen; i++) {
       
   282 						that.s.aiExclude[i] = oReorder.aiInvertMapping[ that.s.aiExclude[i] ];
       
   283 					}
       
   284 
       
   285 					var mStore = that.s.abOriginal.splice(oReorder.iFrom, 1)[0];
       
   286 					that.s.abOriginal.splice(oReorder.iTo, 0, mStore);
       
   287 
       
   288 					that.fnRebuild();
       
   289 				});
       
   290 
       
   291 				// Set the initial state
       
   292 				this._fnDrawCallback();
       
   293 			},
       
   294 
       
   295 
       
   296 			/**
       
   297 			 * Apply any customisation to the settings from the DataTables initialisation
       
   298 			 *  @method  _fnApplyCustomisation
       
   299 			 *  @returns void
       
   300 			 *  @private
       
   301 			 */
       
   302 			"_fnApplyCustomisation": function (init) {
       
   303 				$.extend(true, this.s, ColVis.defaults, init);
       
   304 
       
   305 				// Slightly messy overlap for the camelCase notation
       
   306 				if (!this.s.showAll && this.s.bShowAll) {
       
   307 					this.s.showAll = this.s.sShowAll;
       
   308 				}
       
   309 
       
   310 				if (!this.s.restore && this.s.bRestore) {
       
   311 					this.s.restore = this.s.sRestore;
       
   312 				}
       
   313 
       
   314 				// CamelCase to Hungarian for the column groups
       
   315 				var groups = this.s.groups;
       
   316 				var hungarianGroups = this.s.aoGroups;
       
   317 				if (groups) {
       
   318 					for (var i = 0, ien = groups.length; i < ien; i++) {
       
   319 						if (groups[i].title) {
       
   320 							hungarianGroups[i].sTitle = groups[i].title;
       
   321 						}
       
   322 						if (groups[i].columns) {
       
   323 							hungarianGroups[i].aiColumns = groups[i].columns;
       
   324 						}
       
   325 					}
       
   326 				}
       
   327 			},
       
   328 
       
   329 
       
   330 			/**
       
   331 			 * On each table draw, check the visibility checkboxes as needed. This allows any process to
       
   332 			 * update the table's column visibility and ColVis will still be accurate.
       
   333 			 *  @method  _fnDrawCallback
       
   334 			 *  @returns void
       
   335 			 *  @private
       
   336 			 */
       
   337 			"_fnDrawCallback": function () {
       
   338 				var columns = this.s.dt.aoColumns;
       
   339 				var buttons = this.dom.buttons;
       
   340 				var groups = this.s.aoGroups;
       
   341 				var button;
       
   342 
       
   343 				for (var i = 0, ien = buttons.length; i < ien; i++) {
       
   344 					button = buttons[i];
       
   345 
       
   346 					if (button.__columnIdx !== undefined) {
       
   347 						$('input', button).prop('checked', columns[ button.__columnIdx ].bVisible);
       
   348 					}
       
   349 				}
       
   350 
       
   351 				var allVisible = function (columnIndeces) {
       
   352 					for (var k = 0, kLen = columnIndeces.length; k < kLen; k++) {
       
   353 						if (columns[columnIndeces[k]].bVisible === false) {
       
   354 							return false;
       
   355 						}
       
   356 					}
       
   357 					return true;
       
   358 				};
       
   359 				var allHidden = function (columnIndeces) {
       
   360 					for (var m = 0 , mLen = columnIndeces.length; m < mLen; m++) {
       
   361 						if (columns[columnIndeces[m]].bVisible === true) {
       
   362 							return false;
       
   363 						}
       
   364 					}
       
   365 					return true;
       
   366 				};
       
   367 
       
   368 				for (var j = 0, jLen = groups.length; j < jLen; j++) {
       
   369 					if (allVisible(groups[j].aiColumns)) {
       
   370 						$('input', this.dom.groupButtons[j]).prop('checked', true);
       
   371 						$('input', this.dom.groupButtons[j]).prop('indeterminate', false);
       
   372 					}
       
   373 					else if (allHidden(groups[j].aiColumns)) {
       
   374 						$('input', this.dom.groupButtons[j]).prop('checked', false);
       
   375 						$('input', this.dom.groupButtons[j]).prop('indeterminate', false);
       
   376 					}
       
   377 					else {
       
   378 						$('input', this.dom.groupButtons[j]).prop('indeterminate', true);
       
   379 					}
       
   380 				}
       
   381 			},
       
   382 
       
   383 
       
   384 			/**
       
   385 			 * Loop through the groups (provided in the settings) and create a button for each.
       
   386 			 *  @method  _fnAddgroups
       
   387 			 *  @returns void
       
   388 			 *  @private
       
   389 			 */
       
   390 			"_fnAddGroups": function () {
       
   391 				var nButton;
       
   392 
       
   393 				if (typeof this.s.aoGroups != 'undefined') {
       
   394 					for (var i = 0, iLen = this.s.aoGroups.length; i < iLen; i++) {
       
   395 						nButton = this._fnDomGroupButton(i);
       
   396 						this.dom.groupButtons.push(nButton);
       
   397 						this.dom.buttons.push(nButton);
       
   398 						this.dom.collection.appendChild(nButton);
       
   399 					}
       
   400 				}
       
   401 			},
       
   402 
       
   403 
       
   404 			/**
       
   405 			 * Loop through the columns in the table and as a new button for each one.
       
   406 			 *  @method  _fnAddButtons
       
   407 			 *  @returns void
       
   408 			 *  @private
       
   409 			 */
       
   410 			"_fnAddButtons": function () {
       
   411 				var
       
   412 					nButton,
       
   413 					columns = this.s.dt.aoColumns;
       
   414 
       
   415 				if ($.inArray('all', this.s.aiExclude) === -1) {
       
   416 					for (var i = 0, iLen = columns.length; i < iLen; i++) {
       
   417 						if ($.inArray(i, this.s.aiExclude) === -1) {
       
   418 							nButton = this._fnDomColumnButton(i);
       
   419 							nButton.__columnIdx = i;
       
   420 							this.dom.buttons.push(nButton);
       
   421 						}
       
   422 					}
       
   423 				}
       
   424 
       
   425 				if (this.s.order === 'alpha') {
       
   426 					this.dom.buttons.sort(function (a, b) {
       
   427 						var titleA = columns[ a.__columnIdx ].sTitle;
       
   428 						var titleB = columns[ b.__columnIdx ].sTitle;
       
   429 
       
   430 						return titleA === titleB ?
       
   431 							0 :
       
   432 							titleA < titleB ?
       
   433 								-1 :
       
   434 								1;
       
   435 					});
       
   436 				}
       
   437 
       
   438 				if (this.s.restore) {
       
   439 					nButton = this._fnDomRestoreButton();
       
   440 					nButton.className += " ColVis_Restore";
       
   441 					this.dom.buttons.push(nButton);
       
   442 				}
       
   443 
       
   444 				if (this.s.showAll) {
       
   445 					nButton = this._fnDomShowAllButton();
       
   446 					nButton.className += " ColVis_ShowAll";
       
   447 					this.dom.buttons.push(nButton);
       
   448 				}
       
   449 
       
   450 				$(this.dom.collection).append(this.dom.buttons);
       
   451 			},
       
   452 
       
   453 
       
   454 			/**
       
   455 			 * Create a button which allows a "restore" action
       
   456 			 *  @method  _fnDomRestoreButton
       
   457 			 *  @returns {Node} Created button
       
   458 			 *  @private
       
   459 			 */
       
   460 			"_fnDomRestoreButton": function () {
       
   461 				var
       
   462 					that = this,
       
   463 					dt = this.s.dt;
       
   464 
       
   465 				return $(
       
   466 					'<li class="ColVis_Special ' + (dt.bJUI ? 'ui-button ui-state-default' : '') + '">' +
       
   467 						this.s.restore +
       
   468 						'</li>'
       
   469 				)
       
   470 					.click(function (e) {
       
   471 							   for (var i = 0, iLen = that.s.abOriginal.length; i < iLen; i++) {
       
   472 								   that.s.dt.oInstance.fnSetColumnVis(i, that.s.abOriginal[i], false);
       
   473 							   }
       
   474 							   that._fnAdjustOpenRows();
       
   475 							   that.s.dt.oInstance.fnAdjustColumnSizing(false);
       
   476 							   that.s.dt.oInstance.fnDraw(false);
       
   477 						   })[0];
       
   478 			},
       
   479 
       
   480 
       
   481 			/**
       
   482 			 * Create a button which allows a "show all" action
       
   483 			 *  @method  _fnDomShowAllButton
       
   484 			 *  @returns {Node} Created button
       
   485 			 *  @private
       
   486 			 */
       
   487 			"_fnDomShowAllButton": function () {
       
   488 				var
       
   489 					that = this,
       
   490 					dt = this.s.dt;
       
   491 
       
   492 				return $(
       
   493 					'<li class="ColVis_Special ' + (dt.bJUI ? 'ui-button ui-state-default' : '') + '">' +
       
   494 						this.s.showAll +
       
   495 						'</li>'
       
   496 				)
       
   497 					.click(function (e) {
       
   498 							   for (var i = 0, iLen = that.s.abOriginal.length; i < iLen; i++) {
       
   499 								   if (that.s.aiExclude.indexOf(i) === -1) {
       
   500 									   that.s.dt.oInstance.fnSetColumnVis(i, true, false);
       
   501 								   }
       
   502 							   }
       
   503 							   that._fnAdjustOpenRows();
       
   504 							   that.s.dt.oInstance.fnAdjustColumnSizing(false);
       
   505 							   that.s.dt.oInstance.fnDraw(false);
       
   506 						   })[0];
       
   507 			},
       
   508 
       
   509 
       
   510 			/**
       
   511 			 * Create the DOM for a show / hide group button
       
   512 			 *  @method  _fnDomGroupButton
       
   513 			 *  @param {int} i Group in question, order based on that provided in settings
       
   514 			 *  @returns {Node} Created button
       
   515 			 *  @private
       
   516 			 */
       
   517 			"_fnDomGroupButton": function (i) {
       
   518 				var
       
   519 					that = this,
       
   520 					dt = this.s.dt,
       
   521 					oGroup = this.s.aoGroups[i];
       
   522 
       
   523 				return $(
       
   524 					'<li class="ColVis_Special ' + (dt.bJUI ? 'ui-button ui-state-default' : '') + '">' +
       
   525 						'<label>' +
       
   526 						'<input type="checkbox" />' +
       
   527 						'<span>' + oGroup.sTitle + '</span>' +
       
   528 						'</label>' +
       
   529 						'</li>'
       
   530 				)
       
   531 					.click(function (e) {
       
   532 							   var showHide = !$('input', this).is(":checked");
       
   533 							   if (e.target.nodeName.toLowerCase() !== "li") {
       
   534 								   showHide = !showHide;
       
   535 							   }
       
   536 
       
   537 							   for (var j = 0; j < oGroup.aiColumns.length; j++) {
       
   538 								   that.s.dt.oInstance.fnSetColumnVis(oGroup.aiColumns[j], showHide);
       
   539 							   }
       
   540 						   })[0];
       
   541 			},
       
   542 
       
   543 
       
   544 			/**
       
   545 			 * Create the DOM for a show / hide button
       
   546 			 *  @method  _fnDomColumnButton
       
   547 			 *  @param {int} i Column in question
       
   548 			 *  @returns {Node} Created button
       
   549 			 *  @private
       
   550 			 */
       
   551 			"_fnDomColumnButton": function (i) {
       
   552 				var
       
   553 					that = this,
       
   554 					column = this.s.dt.aoColumns[i],
       
   555 					dt = this.s.dt;
       
   556 
       
   557 				var title = this.s.fnLabel === null ?
       
   558 					column.sTitle :
       
   559 					this.s.fnLabel(i, column.sTitle, column.nTh);
       
   560 
       
   561 				return $(
       
   562 					'<li ' + (dt.bJUI ? 'class="ui-button ui-state-default"' : '') + '>' +
       
   563 						'<label>' +
       
   564 						'<input type="checkbox" />' +
       
   565 						'<span>' + title + '</span>' +
       
   566 						'</label>' +
       
   567 						'</li>'
       
   568 				)
       
   569 					.click(function (e) {
       
   570 							   var showHide = !$('input', this).is(":checked");
       
   571 							   if (e.target.nodeName.toLowerCase() !== "li") {
       
   572 								   showHide = !showHide;
       
   573 							   }
       
   574 
       
   575 							   /* Need to consider the case where the initialiser created more than one table - change the
       
   576 								* API index that DataTables is using
       
   577 								*/
       
   578 							   var oldIndex = $.fn.dataTableExt.iApiIndex;
       
   579 							   $.fn.dataTableExt.iApiIndex = that._fnDataTablesApiIndex.call(that);
       
   580 
       
   581 							   // Optimisation for server-side processing when scrolling - don't do a full redraw
       
   582 							   if (dt.oFeatures.bServerSide) {
       
   583 								   that.s.dt.oInstance.fnSetColumnVis(i, showHide, false);
       
   584 								   that.s.dt.oInstance.fnAdjustColumnSizing(false);
       
   585 								   if (dt.oScroll.sX !== "" || dt.oScroll.sY !== "") {
       
   586 									   that.s.dt.oInstance.oApi._fnScrollDraw(that.s.dt);
       
   587 								   }
       
   588 								   that._fnDrawCallback();
       
   589 							   }
       
   590 							   else {
       
   591 								   that.s.dt.oInstance.fnSetColumnVis(i, showHide);
       
   592 							   }
       
   593 
       
   594 							   $.fn.dataTableExt.iApiIndex = oldIndex;
       
   595 							   /* Restore */
       
   596 
       
   597 							   if (that.s.fnStateChange !== null) {
       
   598 								   that.s.fnStateChange.call(that, i, showHide);
       
   599 							   }
       
   600 						   })[0];
       
   601 			},
       
   602 
       
   603 
       
   604 			/**
       
   605 			 * Get the position in the DataTables instance array of the table for this
       
   606 			 * instance of ColVis
       
   607 			 *  @method  _fnDataTablesApiIndex
       
   608 			 *  @returns {int} Index
       
   609 			 *  @private
       
   610 			 */
       
   611 			"_fnDataTablesApiIndex": function () {
       
   612 				for (var i = 0, iLen = this.s.dt.oInstance.length; i < iLen; i++) {
       
   613 					if (this.s.dt.oInstance[i] == this.s.dt.nTable) {
       
   614 						return i;
       
   615 					}
       
   616 				}
       
   617 				return 0;
       
   618 			},
       
   619 
       
   620 
       
   621 			/**
       
   622 			 * Create the element used to contain list the columns (it is shown and
       
   623 			 * hidden as needed)
       
   624 			 *  @method  _fnDomCollection
       
   625 			 *  @returns {Node} div container for the collection
       
   626 			 *  @private
       
   627 			 */
       
   628 			"_fnDomCollection": function () {
       
   629 				var that = this;
       
   630 				return $('<ul />', {
       
   631 					'class': !that.s.dt.bJUI ?
       
   632 						"ColVis_collection" :
       
   633 						"ColVis_collection ui-buttonset ui-buttonset-multi"
       
   634 				})
       
   635 					.css({
       
   636 							 'display': 'none',
       
   637 							 'opacity': 0,
       
   638 							 'position': !that.s.bCssPosition ?
       
   639 								 'absolute' :
       
   640 								 ''
       
   641 						 })[0];
       
   642 			},
       
   643 
       
   644 
       
   645 			/**
       
   646 			 * An element to be placed on top of the activate button to catch events
       
   647 			 *  @method  _fnDomCatcher
       
   648 			 *  @returns {Node} div container for the collection
       
   649 			 *  @private
       
   650 			 */
       
   651 			"_fnDomCatcher": function () {
       
   652 				var
       
   653 					that = this,
       
   654 					nCatcher = document.createElement('div');
       
   655 				nCatcher.className = "ColVis_catcher";
       
   656 
       
   657 				$(nCatcher).click(function () {
       
   658 					that._fnCollectionHide.call(that, null, null);
       
   659 				});
       
   660 
       
   661 				return nCatcher;
       
   662 			},
       
   663 
       
   664 
       
   665 			/**
       
   666 			 * Create the element used to shade the background, and capture hide events (it is shown and
       
   667 			 * hidden as needed)
       
   668 			 *  @method  _fnDomBackground
       
   669 			 *  @returns {Node} div container for the background
       
   670 			 *  @private
       
   671 			 */
       
   672 			"_fnDomBackground": function () {
       
   673 				var that = this;
       
   674 
       
   675 				var background = $('<div></div>')
       
   676 					.addClass('ColVis_collectionBackground')
       
   677 					.css('opacity', 0)
       
   678 					.click(function () {
       
   679 							   that._fnCollectionHide.call(that, null, null);
       
   680 						   });
       
   681 
       
   682 				/* When considering a mouse over action for the activation, we also consider a mouse out
       
   683 				 * which is the same as a mouse over the background - without all the messing around of
       
   684 				 * bubbling events. Use the catcher element to avoid messing around with bubbling
       
   685 				 */
       
   686 				if (this.s.activate == "mouseover") {
       
   687 					background.mouseover(function () {
       
   688 						that.s.overcollection = false;
       
   689 						that._fnCollectionHide.call(that, null, null);
       
   690 					});
       
   691 				}
       
   692 
       
   693 				return background[0];
       
   694 			},
       
   695 
       
   696 
       
   697 			/**
       
   698 			 * Show the show / hide list and the background
       
   699 			 *  @method  _fnCollectionShow
       
   700 			 *  @returns void
       
   701 			 *  @private
       
   702 			 */
       
   703 			"_fnCollectionShow": function () {
       
   704 				var that = this, i, iLen, iLeft;
       
   705 				var oPos = $(this.dom.button).offset();
       
   706 				var nHidden = this.dom.collection;
       
   707 				var nBackground = this.dom.background;
       
   708 				var iDivX = parseInt(oPos.left, 10);
       
   709 				var iDivY = parseInt(oPos.top + $(this.dom.button).outerHeight(), 10);
       
   710 
       
   711 				if (!this.s.bCssPosition) {
       
   712 					nHidden.style.top = iDivY + "px";
       
   713 					nHidden.style.left = iDivX + "px";
       
   714 				}
       
   715 
       
   716 				$(nHidden).css({
       
   717 								   'display': 'block',
       
   718 								   'opacity': 0
       
   719 							   });
       
   720 
       
   721 //		nBackground.style.bottom ='0px';
       
   722 //		nBackground.style.right = '0px';
       
   723 
       
   724 //		var oStyle = this.dom.catcher.style;
       
   725 //		oStyle.height = $(this.dom.button).outerHeight()+"px";
       
   726 //		oStyle.width = $(this.dom.button).outerWidth()+"px";
       
   727 //		oStyle.top = oPos.top+"px";
       
   728 //		oStyle.left = iDivX+"px";
       
   729 
       
   730 				document.body.appendChild(nBackground);
       
   731 				document.body.appendChild(nHidden);
       
   732 				document.body.appendChild(this.dom.catcher);
       
   733 
       
   734 				/* This results in a very small delay for the end user but it allows the animation to be
       
   735 				 * much smoother. If you don't want the animation, then the setTimeout can be removed
       
   736 				 */
       
   737 				$(nHidden).animate({"opacity": 1}, that.s.iOverlayFade);
       
   738 				$(nBackground).animate({"opacity": 0.1}, that.s.iOverlayFade, 'linear', function () {
       
   739 					/* In IE6 if you set the checked attribute of a hidden checkbox, then this is not visually
       
   740 					 * reflected. As such, we need to do it here, once it is visible. Unbelievable.
       
   741 					 */
       
   742 					if ($.browser && $.browser.msie && $.browser.version == "6.0") {
       
   743 						that._fnDrawCallback();
       
   744 					}
       
   745 				});
       
   746 
       
   747 				/* Visual corrections to try and keep the collection visible */
       
   748 				if (!this.s.bCssPosition) {
       
   749 					iLeft = ( this.s.sAlign == "left" ) ?
       
   750 						iDivX :
       
   751 						iDivX - $(nHidden).outerWidth() + $(this.dom.button).outerWidth();
       
   752 
       
   753 					nHidden.style.left = iLeft + "px";
       
   754 
       
   755 					var iDivWidth = $(nHidden).outerWidth();
       
   756 					var iDivHeight = $(nHidden).outerHeight();
       
   757 					var iDocWidth = $(document).width();
       
   758 
       
   759 					if (iLeft + iDivWidth > iDocWidth) {
       
   760 						nHidden.style.left = (iDocWidth - iDivWidth) + "px";
       
   761 					}
       
   762 				}
       
   763 
       
   764 				this.s.hidden = false;
       
   765 			},
       
   766 
       
   767 
       
   768 			/**
       
   769 			 * Hide the show / hide list and the background
       
   770 			 *  @method  _fnCollectionHide
       
   771 			 *  @returns void
       
   772 			 *  @private
       
   773 			 */
       
   774 			"_fnCollectionHide": function () {
       
   775 				var that = this;
       
   776 
       
   777 				if (!this.s.hidden && this.dom.collection !== null) {
       
   778 					this.s.hidden = true;
       
   779 
       
   780 					$(this.dom.collection).animate({"opacity": 0}, that.s.iOverlayFade, function (e) {
       
   781 						this.style.display = "none";
       
   782 					});
       
   783 
       
   784 					$(this.dom.background).animate({"opacity": 0}, that.s.iOverlayFade, function (e) {
       
   785 						document.body.removeChild(that.dom.background);
       
   786 						document.body.removeChild(that.dom.catcher);
       
   787 					});
       
   788 				}
       
   789 			},
       
   790 
       
   791 
       
   792 			/**
       
   793 			 * Alter the colspan on any fnOpen rows
       
   794 			 */
       
   795 			"_fnAdjustOpenRows": function () {
       
   796 				var aoOpen = this.s.dt.aoOpenRows;
       
   797 				var iVisible = this.s.dt.oApi._fnVisbleColumns(this.s.dt);
       
   798 
       
   799 				for (var i = 0, iLen = aoOpen.length; i < iLen; i++) {
       
   800 					aoOpen[i].nTr.getElementsByTagName('td')[0].colSpan = iVisible;
       
   801 				}
       
   802 			}
       
   803 		};
       
   804 
       
   805 
       
   806 		/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
       
   807 		 * Static object methods
       
   808 		 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
       
   809 
       
   810 		/**
       
   811 		 * Rebuild the collection for a given table, or all tables if no parameter given
       
   812 		 *  @method  ColVis.fnRebuild
       
   813 		 *  @static
       
   814 		 *  @param   object oTable DataTable instance to consider - optional
       
   815 		 *  @returns void
       
   816 		 */
       
   817 		ColVis.fnRebuild = function (oTable) {
       
   818 			var nTable = null;
       
   819 			if (typeof oTable != 'undefined') {
       
   820 				nTable = oTable.fnSettings().nTable;
       
   821 			}
       
   822 
       
   823 			for (var i = 0, iLen = ColVis.aInstances.length; i < iLen; i++) {
       
   824 				if (typeof oTable == 'undefined' || nTable == ColVis.aInstances[i].s.dt.nTable) {
       
   825 					ColVis.aInstances[i].fnRebuild();
       
   826 				}
       
   827 			}
       
   828 		};
       
   829 
       
   830 
       
   831 		ColVis.defaults = {
       
   832 			/**
       
   833 			 * Mode of activation. Can be 'click' or 'mouseover'
       
   834 			 *  @property activate
       
   835 			 *  @type     string
       
   836 			 *  @default  click
       
   837 			 */
       
   838 			active: 'click',
       
   839 
       
   840 			/**
       
   841 			 * Text used for the button
       
   842 			 *  @property buttonText
       
   843 			 *  @type     string
       
   844 			 *  @default  Show / hide columns
       
   845 			 */
       
   846 			buttonText: 'Show / hide columns',
       
   847 
       
   848 			/**
       
   849 			 * List of columns (integers) which should be excluded from the list
       
   850 			 *  @property aiExclude
       
   851 			 *  @type     array
       
   852 			 *  @default  []
       
   853 			 */
       
   854 			aiExclude: [],
       
   855 
       
   856 			/**
       
   857 			 * Show restore button
       
   858 			 *  @property bRestore
       
   859 			 *  @type     boolean
       
   860 			 *  @default  false
       
   861 			 */
       
   862 			bRestore: false,
       
   863 
       
   864 			/**
       
   865 			 * Restore button text
       
   866 			 *  @property sRestore
       
   867 			 *  @type     string
       
   868 			 *  @default  Restore original
       
   869 			 */
       
   870 			sRestore: 'Restore original',
       
   871 
       
   872 			/**
       
   873 			 * Show Show-All button
       
   874 			 *  @property bShowAll
       
   875 			 *  @type     boolean
       
   876 			 *  @default  false
       
   877 			 */
       
   878 			bShowAll: false,
       
   879 
       
   880 			/**
       
   881 			 * Show All button text
       
   882 			 *  @property sShowAll
       
   883 			 *  @type     string
       
   884 			 *  @default  Restore original
       
   885 			 */
       
   886 			sShowAll: 'Show All',
       
   887 
       
   888 			/**
       
   889 			 * Position of the collection menu when shown - align "left" or "right"
       
   890 			 *  @property sAlign
       
   891 			 *  @type     string
       
   892 			 *  @default  left
       
   893 			 */
       
   894 			sAlign: 'left',
       
   895 
       
   896 			/**
       
   897 			 * Callback function to tell the user when the state has changed
       
   898 			 *  @property fnStateChange
       
   899 			 *  @type     function
       
   900 			 *  @default  null
       
   901 			 */
       
   902 			fnStateChange: null,
       
   903 
       
   904 			/**
       
   905 			 * Overlay animation duration in mS
       
   906 			 *  @property iOverlayFade
       
   907 			 *  @type     integer|false
       
   908 			 *  @default  500
       
   909 			 */
       
   910 			iOverlayFade: 500,
       
   911 
       
   912 			/**
       
   913 			 * Label callback for column names. Takes three parameters: 1. the
       
   914 			 * column index, 2. the column title detected by DataTables and 3. the
       
   915 			 * TH node for the column
       
   916 			 *  @property fnLabel
       
   917 			 *  @type     function
       
   918 			 *  @default  null
       
   919 			 */
       
   920 			fnLabel: null,
       
   921 
       
   922 			/**
       
   923 			 * Indicate if the column list should be positioned by Javascript,
       
   924 			 * visually below the button or allow CSS to do the positioning
       
   925 			 *  @property bCssPosition
       
   926 			 *  @type     boolean
       
   927 			 *  @default  false
       
   928 			 */
       
   929 			bCssPosition: false,
       
   930 
       
   931 			/**
       
   932 			 * Group buttons
       
   933 			 *  @property aoGroups
       
   934 			 *  @type     array
       
   935 			 *  @default  []
       
   936 			 */
       
   937 			aoGroups: [],
       
   938 
       
   939 			/**
       
   940 			 * Button ordering - 'alpha' (alphabetical) or 'column' (table column
       
   941 			 * order)
       
   942 			 *  @property order
       
   943 			 *  @type     string
       
   944 			 *  @default  column
       
   945 			 */
       
   946 			order: 'column'
       
   947 		};
       
   948 
       
   949 
       
   950 		/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
       
   951 		 * Static object properties
       
   952 		 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
       
   953 
       
   954 		/**
       
   955 		 * Collection of all ColVis instances
       
   956 		 *  @property ColVis.aInstances
       
   957 		 *  @static
       
   958 		 *  @type     Array
       
   959 		 *  @default  []
       
   960 		 */
       
   961 		ColVis.aInstances = [];
       
   962 
       
   963 
       
   964 		/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
       
   965 		 * Constants
       
   966 		 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
       
   967 
       
   968 		/**
       
   969 		 * Name of this class
       
   970 		 *  @constant CLASS
       
   971 		 *  @type     String
       
   972 		 *  @default  ColVis
       
   973 		 */
       
   974 		ColVis.prototype.CLASS = "ColVis";
       
   975 
       
   976 
       
   977 		/**
       
   978 		 * ColVis version
       
   979 		 *  @constant  VERSION
       
   980 		 *  @type      String
       
   981 		 *  @default   See code
       
   982 		 */
       
   983 		ColVis.VERSION = "1.1.0";
       
   984 		ColVis.prototype.VERSION = ColVis.VERSION;
       
   985 
       
   986 
       
   987 		/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
       
   988 		 * Initialisation
       
   989 		 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
       
   990 
       
   991 		/*
       
   992 		 * Register a new feature with DataTables
       
   993 		 */
       
   994 		if (typeof $.fn.dataTable == "function" &&
       
   995 			typeof $.fn.dataTableExt.fnVersionCheck == "function" &&
       
   996 			$.fn.dataTableExt.fnVersionCheck('1.7.0')) {
       
   997 			$.fn.dataTableExt.aoFeatures.push({
       
   998 												  "fnInit": function (oDTSettings) {
       
   999 													  var init = oDTSettings.oInit;
       
  1000 													  var colvis = new ColVis(oDTSettings, init.colVis || init.oColVis || {});
       
  1001 													  return colvis.button();
       
  1002 												  },
       
  1003 												  "cFeature": "C",
       
  1004 												  "sFeature": "ColVis"
       
  1005 											  });
       
  1006 		}
       
  1007 		else {
       
  1008 			alert("Warning: ColVis requires DataTables 1.7 or greater - www.datatables.net/download");
       
  1009 		}
       
  1010 
       
  1011 
       
  1012 // Make ColVis accessible from the DataTables instance
       
  1013 		$.fn.dataTable.ColVis = ColVis;
       
  1014 		$.fn.DataTable.ColVis = ColVis;
       
  1015 
       
  1016 
       
  1017 		return ColVis;
       
  1018 	}; // /factory
       
  1019 
       
  1020 
       
  1021 	factory(jQuery, jQuery.fn.dataTable);
       
  1022 
       
  1023 
       
  1024 })(window, document);
       
  1025