Giter Club home page Giter Club logo

columnfilterwidgets's Introduction

This is an add-on for the DataTables plugin for jQuery that creates filtering widgets based on the data in table columns.

Widgets are grouped in a layout element, independent of source columns.

Multiple selections can be made for a column, and other widgets adjust to reflect the results.

Multiple values can be parsed from a single table cell using a delimiter (like a comma).

Selections can be grouped with the source dropdown, or all together in a common layout element.

Selections can be removed individually.

Examples: http://cyberhobo.github.io/column-filter-widgets-examples/extras/ColumnFilterWidgets/index.html

Working with DataTables

Find the DataTables source here: https://github.com/DataTables/DataTables

The included examples will only work within the DataTables source tree. Here's a quick git checkout:

$ git clone [email protected]:DataTables/DataTables.git
Cloning into DataTables...
...
$ cd DataTables
$ mkdir extras
$ cd extras
$ git clone [email protected]:cyberhobo/ColumnFilterWidgets.git
Cloning into ColumnFilterWidgets...

For DataTables usage, please refer to the DataTables web-pages: http://www.datatables.net

The ColumnFilterWidgets source can be found in the media/js/ directory of this source tree.

Options

Options are specified as a DataTables option, in an object called oColumnFilterWidgets:

$( '#example_table' ).dataTable( { 
	bPaginate: true,
	sDom: 'Wlfriptip',
	sPaginationType: 'full_numbers',
	oColumnFilterWidgets: {
		aiExclude: [ 0, 6 ],
		sSeparator: ',  ',
		bGroupTerms: true,
		aoColumnDefs: [
			{ bSort: false, sSeparator: ' / ', aiTargets: [ 2 ] },
			{ fnSort: function( a, b ) { return a-b; }, aiTargets: [ 3 ] }
		]
			
	}
} );

The possible options are:

  • aiExclude - an array of column indices for which column filter widgets should not be created.
  • bGroupTerms - enable grouping of selected terms in a single div element.
  • sSeparator - enable parsing of column contents into multiple terms separated by this string.
  • iMaxSelections - allow at most this number of selections from each column filter widget.

Contributing

Github offers ways to contribute code, write documentation, submit issues, suggest features, etc. Go nuts!

Donations are always encouraging.

License

ColumnFilterWidgets uses the same license as DataTables. DataTables is released with dual licensing, using the GPL v2 (license-gpl2.txt) and an BSD style license (license-bsd.txt). Please see the corresponding license file for details of these licenses. You are free to use, modify and distribute this software, but all copyright information must remain.

columnfilterwidgets's People

Contributors

abs0 avatar cyberhobo avatar jen-ari avatar smwise avatar zorfling avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

columnfilterwidgets's Issues

Filter fails with '-' or html entities

There seem to be quite a few cases where content will show up fine in the filter dropdown select, but fail to pickup the matching rows when selected:

Some examples:

<td class="filterable">-</td>
<td class="filterable">One &amp; two</td>

Thanks :)

It doesn't work when you specify aaData as an array of objects

It tries to find column by index, but can't so throws error.
This change (line 161):
widget.iColumn = widget.oColumn['mData'];

fixes the error.

To make aiExclude work with mData instead of column indexes, we need to change line 116 to:
if ( oColumn.bVisible && sExcludeList.indexOf( '|' + oColumn.mData + '|' ) < 0 ) {

Replacing $.each with for loop in ColumnFilterWidget.prototype.fnDraw

Desperately trying to overcome the issue with 40-50 second page loads in IE11, things improved a bit when replacing a $.each loop with a simple for loop as proposed in this thread: http://datatables.net/forums/discussion/4739/beating-the-ie-dead-horse/p2

I am now having a go at replacing another $.each loop a for loop in the ColumnFilterWidget.prototype.fnDraw function, and the code works well in my early test environment, unless there's something I overlooked?

I replaced:

$.each( aData, function( i, sValue ) { //slow in IE11
    var asValues = widget.sSeparator ? sValue.split( new RegExp( widget.sSeparator ) ) : [ sValue ];
    $.each( asValues, function( j, sOption ) {
        if ( !oDistinctOptions.hasOwnProperty( sOption ) ) {
            oDistinctOptions[sOption] = true;
            aDistinctOptions.push( sOption );
        }
    } );
} );

with:

var aDataLength = aData.length;
for (var i = 0; i < aDataLength; i++) {
    var sValue = aData[i]
    var asValues = widget.sSeparator ? sValue.split( new RegExp( widget.sSeparator ) ) : [ sValue ];   
    for (var a = 0; a < aDataLength; a++) {
        if ( asValues[a] ) {
            var sOption = asValues[a]
            if ( !oDistinctOptions.hasOwnProperty( sOption ) ) { 
                oDistinctOptions[sOption] = true;
                aDistinctOptions.push( sOption );
            }
        }
    }   
}

ColumnFilterWidget.prototype.fnDraw on table redraw slows loading, sorting, etc

When dealing with large datasets, the performance slowdown on re-populating the select dropdowns on any change in the datatable redraw is significant and the cost is exponential. In a test on a table with 10 columns and 11k rows, the load time goes from 8sec to 25sec in Firefox (no firebug). Furthermore when using the sorting plugin and sorting, this triggers a redraw which slows down sorts significantly as well.

While I understand the helpfulness of maintaining updated filterable values, I would recommend adding a way to make this function called more selectively and leave that option up to the developer to trigger manually - such as on a filter selection.

I've commented out the fnDraw() below and this greatly speeds loading and sorts.

oDataTableSettings.aoDrawCallback.push( {
name: 'ColumnFilterWidgets',
fn: function() {
$.each( me.aoWidgets, function( i, oWidget ) {
//oWidget.fnDraw();
} );
}
} );

Match filters width and alignment to columns

As a UI/UX designer it would be nice to have these filters match the width and alignment to columns. this way there is a clear visual of what column you are sorting and is also aesthetically pleasing. I am floating and styling the widths accordingly, but does not work very well with a fluid or responsive UI.

sSeparator on column brake <br />

Hi,

the sSeparator does not work correctly for column brake:

sSeparator: '\s_
+\s_'

The values in dropdowns are correcly separated, but the search does not seem to work - rows containing column breaks are not selected.

Filter invisible columns

DataTables is capable of filtering invisible columns, so ColumnFilterWidgets probably should too, as requested here.

This might unexpectedly add widgets for invisible columns in existing installations. If that's not desired, the aiExclude parameter will need to be used to get rid of unwanted widgets.

StateSave Request

The state of the filter is held when refreshing the browser but once that data is filtered out it cant be removed after refreshing. For example I'll filter on all Apple entries and then refresh the browser. You can no longer uncheck Apples and show all the data again. So once you filter and end your session you can't unfilter that item. I was wondering if this was an bug or could possibly be added.

filters in TFOOT elements

It would be nice to have the filters for each column in the footer for each column in the table. I didn't see a way to do this. I added a 'bFooter' option in oDataTableSettings.oInit.oColumnFilterWidgets and hacked/modified ColumnFilterWidgets to accomplish this. I'm sure my hack isn't the best way to do this. Here's my modification to ColumnFilterWidgets():

var ColumnFilterWidgets = function( oDataTableSettings ) {
    var me = this;
    var sExcludeList = '';
    me.$WidgetContainer = $( '<div class="column-filter-widgets"></div>' );
    me.$MenuContainer = me.$WidgetContainer;
    me.$TermContainer = null;
    me.aoWidgets = [];
    me.sSeparator = '';
    if ( 'oColumnFilterWidgets' in oDataTableSettings.oInit ) {
        if ( 'aiExclude' in oDataTableSettings.oInit.oColumnFilterWidgets ) {
            sExcludeList = '|' + oDataTableSettings.oInit.oColumnFilterWidgets.aiExclude.join( '|' ) + '|';
        }
        if ( 'bGroupTerms' in oDataTableSettings.oInit.oColumnFilterWidgets && oDataTableSettings.oInit.oColumnFilterWidgets.bGroupTerms ) {
            me.$MenuContainer = $( '<div class="column-filter-widget-menus"></div>' );
            me.$TermContainer = $( '<div class="column-filter-widget-selected-terms"></div>' ).hide();
        }
    }

    // Add a widget for each visible and filtered column
    $.each( oDataTableSettings.aoColumns, function ( i, oColumn ) {
        var $columnTh = $( oColumn.nTh );
        var $WidgetElem = $( '<div class="column-filter-widget"></div>' );
        if ( sExcludeList.indexOf( '|' + i + '|' ) < 0 ) {
            me.aoWidgets.push( new ColumnFilterWidget( $WidgetElem, oDataTableSettings, i, me ) );
        }
        // START CHANGES
        if ('bFooter' in oDataTableSettings.oInit.oColumnFilterWidgets && oDataTableSettings.oInit.oColumnFilterWidgets) {
            $(oDataTableSettings.nTFoot.getElementsByTagName('tr')[0].getElementsByTagName('th')[i]).append('<div class="column-filter-widgets"></div>');
            $(oDataTableSettings.nTFoot.getElementsByTagName('tr')[0].getElementsByTagName('th')[i].getElementsByTagName('div')[0]).append($WidgetElem);

        } else
        // END CHANGES
            me.$MenuContainer.append( $WidgetElem );
    } );
    if ( me.$TermContainer ) {
        me.$WidgetContainer.append( me.$MenuContainer );
        me.$WidgetContainer.append( me.$TermContainer );
    }
    oDataTableSettings.aoDrawCallback.push( {
        name: 'ColumnFilterWidgets',
        fn: function() {
            $.each( me.aoWidgets, function( i, oWidget ) {
                oWidget.fnDraw();
            } );
        }
    } );

    return me;
};

Populating the default selection from the ColumnFilterWidgets dropdown based on a variable

I am using the TablePress Wordpress plugin that relies on the Datatables plugin for jQuery.

I am looking for a way to put a dynamic value (string of YYYY-MM that I have stored in a variable) into the selection from the ColumnFilterWidgets dropdown.

As I am lacking JS coding skills myself, I am looking for some hints (or ready to copy/adapt code) to accomplish this.

Any help is much appreciated.

Filter fails when table cells have interior wrapper

< td >value< /td > < /code > works just fine for filtering value.

For some reason < td >< span >value< /span >< /td > shows up in the filters list but when selected it shows an empty result set.

I couldn't quite figure out how to do the code markdown in github.

Filtering via custom elements

Does is possible to do filtering via different custom elements (for example first column via 'img' group, other via simple a/text list, third via select ).

That can be useful for more friendly visualization, when we show above the table, logo brands, for example.

Lowercase and upercase in dropdown box

Hi, i found problem. When i have informations in table in lower and uper case, uper case sorts first, and lower after it. Can it be somehow repaired?

for example
Box, Car, Zero, ant, glove is in dropdown box, but it have to be ant, Box, Car, glove, Zero

Tag filter-terms with html-classes

If ColumnFilterWidget would tag filter-terms with unique classes i could highlight them in different styles. That would be useful for a better user experience.

More flexible widget menu sorting

Currently terms in the menus are sorted with a simple alpha sort.

It would probably be possible to make the sort terms that consist only of digits numerically, while doing an alpha sort on all other strings. That seems like a reasonable default.

Additionally, we could probably make it an option to supply a sorting function.

This, like other options, would make sense to apply individually to columns, but that's probably a matter for a separate (bigger) issue.

oDataTable.fnVersionCheck issue

In the current code, the version check for DataTables determining whether to use the fnGetColumnData function or the new "search: 'applied'" method is phrased like this:

if( widget.oDataTable.fnVersionCheck( '1.10.0' ))

This performs the check for each fnDraw operation. Since the version of DataTables will not change between draw operations, you could check against a set variable instead, such as this:

var usefnGetColumnData = true
var dataTableVersion = $.fn.dataTable.version.split('.');
if (parseInt(dataTableVersion[0]) > 0 && parseInt(dataTableVersion[1]) > 0 ) usefnGetColumnData = false  

and in the 'ColumnFilterWidget.prototype.fnDraw' function, replace the fnVersionCheck line with the following if ( usefnGetColumnData === false ), making the final check look like this:

if ( usefnGetColumnData === false ) aData = widget.oDataTable.api().column( widget.iColumn, { search: 'applied' } ).data().sort().unique();
else aData = widget.oDataTable.fnGetColumnData( widget.iColumn );

columnfilterwidgets

Could you please provide me with instructions how to install the plugin to the datatables program? I need to know which files have to be modified and which directories to look at. Also what will be the code added to the files so the plugin will work.

Thanks,
Constantine

Date filter unique

Hello,

If i have these dates:

2020-02-23 14:00
2020-02-23 10:00

2020-02-22 14:00
2020-02-22 10:00

2020-02-19 10:00

I would like the filter liste give :

2020-02-23
2020-02-22
2020-02-19

And when i choose

2020-02-23

gives :
2020-02-23 14:00
2020-02-23 10:00
as results database

It's possible?
Thx

datatables 1.10 - empty selectboxes

Hi, i updated datatables to 1.10 version, but column filter widget stop working. Selectboxes appears as empty (disabled) and in html source they have only one option value [Object Object]. Had someone same issue? Im using data from javascript source and columnDefs and render to process them.

Very slow performance in IE with large data set

I was seeing a > 30 second load time for a 2,000 row data set.

I tracked down the offending code in the fnDraw method.

$.each(aDistinctOptions, function (i, sOption) {
    var sText;
    sText = $('<div>' + sOption + '</div>').text();
    widget.$Select.append($('<option></option>').attr('value', sOption).text(sText));
});

Both the jQuery append and each are fairly slow in IE when used this way. I did some searching and found an improvement to this code.

var iLength = aDistinctOptions.length;
var aOptions = [];
var i = 0;
for (var a = 0; a < iLength; a += 1) {
    aOptions[i++] = '<option value="';
    aOptions[i++] = aDistinctOptions[a];
    aOptions[i++] = '">';
    aOptions[i++] = aDistinctOptions[a];
    aOptions[i++] = '</option>';
}
widget.$Select.append(aOptions.join(''));

I hope this can help someone else out.

Drop down header is displaying html

Hi,
I've implemented this on my SharePoint site and DataTables loads perfectly but for each column drop-down, it's displaying the full html inside the header.
So instead of the label displaying, it shows the following:
<div sortable="" sortdisable="" filterdisable="" filterable="" filterdisablemessage="" name="Proximity" ctxnum="653" displayname="Proximity" fieldtype="DateTime" resulttype="" sortfields="View={67c3e33b-8110-4eaa-be19-28d5c67f2c0a}&amp;SortField=Proximity&amp;SortDir=Asc" class="ms-vh-div"><a id="diidSortProximity" onfocus="OnFocusFilter(this)" href="javascript:" onclick="javascript:return OnClickFilter(this,event);" sortingfields="View={67c3e33b-8110-4eaa-be19-28d5c67f2c0a}&amp;SortField=Proximity&amp;SortDir=Asc">Proximity<img src="/_layouts/images/blank.gif" class="ms-hidden" border="0" width="1" height="1" alt=""></a><img src="/_layouts/images/blank.gif" alt="" border="0"><img src="/_layouts/images/blank.gif" border="0" alt=""></div><div class="s4-ctx"><span>&nbsp;</span><a onfocus="OnChildColumn(this.parentNode.parentNode); return false;" onclick="PopMenuFromChevron(event); return false;" href="javascript:;" title="Open Menu"></a><span>&nbsp;</span></div>

So the label should be "Proximity". The drop-down values display correctly as text.

Does anyone know what I need to change in the ColumnFilterWidgets.js file to render this as html?

Filter alignment by column

Aligning the columns of the filter is a problem.
When we do not exclude the column it can be aligned somewhat.
It would be better if there was a short way in addition to the plugin

I usign this code:
$('#table thead').append('' + '<tr id="searchTr">'+ '<th></th>' + '<th></th>' + '</tr>'); $('#searchTr th:eq(0)').append($('.widget-0'));

thanks

Default select value with server side

its missing in this.
that we want to have a default select options to be there.
Because in server side data table in one page records there may not be all possible values of select.
So there is requirement to have options to with some fixed default values.

option: filters shown as checkboxes

Lets have an option for filters shown as check-boxes in addition to the default option of select dropdown with div texts showing selected items.

Who wants it? Can we have it?

Text search breaks the filters reset

Reported by JEKO via email:

I play with your site http://www.hungercenter.org/subjects/advocacy-and-education/ and i found this small bug (i need it fixed for my site :) ):
when your write something in the free words search box and you select something from the dropdowns, the reset button is not working properly, you should add this:
".keyup();" at the end of the "$( '#publications_table_wrapper .dataTables_filter input' ).val( '' );"
or the reset is not total and the free search words is still working (it appear blank, but the selection is still active).
Sorry for my bad english, thanks again!

Memorize filter in session PHP

Hello,

I would like memorize the filter in session PHP, and loading filters from PHP session to memorize the old state after changing page?

It's possible?

skipped columns get rendered anyway

First of all, thanks for this amazing plugin. I hope backend data loading will work one day.

The issue I found is that div's with class 'column-filter-widget' get rendered as an empty div when the div is in the aiExclude list. This can kind of ruin layout in some browsers.

These are the lines responsible:

// Add a widget for each visible and filtered column
        $.each( oDataTableSettings.aoColumns, function ( i, oColumn ) {
            var $columnTh = $( oColumn.nTh );
            var $WidgetElem = $( '<div class="column-filter-widget"></div>' );
            if ( oColumn.bVisible && sExcludeList.indexOf( '|' + i + '|' ) < 0 ) {
                me.aoWidgets.push( new ColumnFilterWidget( $WidgetElem, oDataTableSettings, i, me ) );
            }
            me.$MenuContainer.append( $WidgetElem );
        } );

This was my solution

// Add a widget for each visible and filtered column
        $.each( oDataTableSettings.aoColumns, function ( i, oColumn ) {
            var $columnTh = $( oColumn.nTh );
            if ( sExcludeList.indexOf( '|' + i + '|' ) < 0 ) {
                var $WidgetElem = $( '<div class="column-filter-widget"></div>' );
                me.aoWidgets.push( new ColumnFilterWidget( $WidgetElem, oDataTableSettings, i, me ) );
                me.$MenuContainer.append( $WidgetElem );
            }
        } );

I also assume the "columnTh" variable can go. As far as I can see, it is not used anywhere.

ResetAllFilter button issue

Hi, I used the code of ResetAllFilters from
#1

But the problem i am facing now is that my filters are not getting reset. The filter select-list from which i choose filter-term , on click of ResetAllFilters button these terms don't get reinserted into the select-list of that filter.

What i am doing wrong?
Here is the code.

$.fn.dataTableExt.oApi.fnResetAllFilters = function (oSettings, bDraw) {
for(iCol = 0; iCol < oSettings.aoPreSearchCols.length; iCol++) {
oSettings.aoPreSearchCols[ iCol ].sSearch = '';
}
$('.filter-term').remove();
oSettings.oPreviousSearch.sSearch = '';
if(typeof bDraw === 'undefined') bDraw = true;
if(bDraw) this.fnDraw();
}

// button click event
$("button").click(function(e){
e.preventDefault();
// 'myDataTable' is the name you gave the datatable at initialisation - oTable or similar
$('#example').dataTable().fnResetAllFilters();
});

column filter widget modification

Is there any way you can tell if it is possible to do the following:
So we don't want multiple text-boxes or drop-down boxes filtering each column, but would like the following:
Have one drop down box listing all the columns. Depending which column is selected in that that drop-down box, it will have the regular search text-box next to it, to write what we wish to search.
When this modification can be done your plugin?

Thanks,
Constantine

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.