Add datatables-1.9.4 and jquery-1.10.2 libraries
[proteocache.git] / webapp / resources / datatables-1.9.4 / extras / ColVis / media / js / ColVis.js
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);