ColVis: new plug-in for DataTables - user control of column visibility

ColVis: new plug-in for DataTables - user control of column visibility

I'm pleased to announce the release of a new plug-in for DataTables called ColVis. ColVis will put a button next to the table, which when activated will show a list of the columns in the table, and provide the end-user with the option for showing, or hiding the columns. This can be particularly useful when there are a large number of columns, and you want to provide the end user with the option of selecting which columns they want to see.

Example:
http://datatables.net/release-datatables/extras/ColVis/

Download (place the extracted folder into the "extras" folder in the DataTables distribution):
http://datatables.net/releases/ColVis-1.0.1.zip

Features:
- Ability to exclude columns for the selection list
- Button activation can be click or mouseover
- Full style control

Thanks to giorgio79 for the donation to make this plug-in possible :-)

The ColVis code seem to have a lot of references to TableTools classes. Is this an oversight? For example, I want ColVis to float left. But the div has a class of both ColVis and TableTools, makeing it trickier.

No this is intentional. The idea was that ColVis could take the same styling as TableTools if you wanted, so no need to include the ColVis stylesheet (although that is TableTools 2 - which is not yet released). They should be arranged such that any styling given to the ColVis classes will take priority.

No I don't have an example of the two plug-ins working side by side on the web at the moment, but will look at putting one up at some point. Until then, editing the CSS is probably what it required, to separate the two out - just using additional constrains on the selectors for example.

It's not possible with the ColVis plug-in as it currently stands, but implementing your own method for doing that would simply be a case of setting the visibility on all the columns you want to show / hide in your group based on a single event action. It would probably be fairly straight forward to make ColVis do this if you poke around in the source.

Good call! Thanks for picking up on that. The problem comes about when initialising more than one table with a single DataTables call. What needs to happen is that the API index that DataTables is operating on should be changed as needed. This wasn't happening, but I've just committed a fix for it, which you can grab from here: http://github.com/DataTables/ColVis/blob/master/media/js/ColVis.js . It will be included in the next ColVis release.

Agreed - this is something that is going to be addressed soon. The next major release of DataTables is try to ensure that the class names are all brought into line. Frustrating that I didn't lay down hard guidelines for myself to follow initially, but something I intend to fix!

In ColVis
[code]
/**
* List of columns (integers) which should be grouped together and use Group Name on the button
* @property aoGroups
* @type Array
* @default []
*/
"aoGroups": []
[/code]

Create a new method to loop through aoGroups, find out if a column is in the group, if it is first column of a group, return the Group, if it is in the Group but not the first one, ignore it, return null. If it is not in any Group, create a single element Group
[code]
/**
* Loop through the columns in the table and as a new button for each one.
* @method _fnFindGroup
* @param {int} target Column in question
* @returns {Node} Group
* @private
*/
"_fnFindGroup": function ( target )
{
var
aiTargets, nGroup,
aoGroups = this.s.aoGroups;

The reason it does an Ajax request is before of this code in fnSetColumnVis (which is a DataTables API function that the plug-in hooks into):

[code]
/* Do a redraw incase anything depending on the table columns needs it
* (built-in: scrolling)
*/
_fnAjustColumnSizing( oSettings );
_fnDraw( oSettings );
_fnSaveState( oSettings );
[/code]
So it's needed to get the column sizes right, although we can get away without it when not using DataTables' scrolling options. At that point this code could be commented out. I've been thinking about making this an option in this function, and that could be passed up stream to ColVis. I've made a note in my to-do list.

One more thing here, I use server-side on first call but if the # of rows is small I display all rows using "iDisplayLength": -1 and then I remove server-side via fnInitComplete like this:
[code]
"fnInitComplete": function() {
this.fnSettings().oFeatures.bServerSide = false;
this.fnSettings().sAjaxSource = null;
},
[/code]

Now if I hide a column, no records are displayed (only displays the table headers) and it shows "showing 1 to 0 of x total records".

Not sure if this is a bug or an invalid feature combination on my side

I think I know what happened.
On first call with server-side on, the end count is like this:
_fnDraw line 2920
[code]
if ( oSettings.oFeatures.bServerSide )
{
iStart = 0;
iEnd = oSettings.aoData.length;
}
[/code]

On subsequent calls now that I disabled server-side, iEnd = oSettings._iDisplayEnd; which somehow resolve to zero

The work-around is I have to pass in _iDisplayEnd = number of rows along with disabling server-side

When using ColVis together with a Footer Callback (for page analysis - not the whole table) the callback function doesn't work anymore as the corresponding column is out of scop: --> nCells[3] is undefined