dataTables.ColVis.js 25 KB

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