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