dataTables.colVis.js 26 KB

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