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