0

I am using Datatables 1.10 and YADCF 0.8.9.beta.24.

My filter inputs are shown in a dropdown menu inside each table head th. I want to show/hide an active-filter-icon in the th where a filter is applied, but I don't know how to react properly to any change / selecting / remove event with the different YADCF filter types, specially with the YADCF clear button. (I'm using select2, text, range_date and auto_complete).

What I tried:

$('#my-table thead').on('change', function(e) {
  if( $(e.target).val() ) {
    $(e.target).closest('th').addClass('filtered_col');
  } else {
    $(e.target).closest('th').removeClass('filtered_col');
  }
});

//Change event triggers when selecting with 'select2' 
//and when removing items with Select2 remove button, 
//works also selecting with 'auto_complete' filters 
//but not whith any YADCF clear button 
//or when selecting with type 'text' or 'range_date'.

I tried with specific event hanlers for Select2 filters ('selecting' and 'removed'), but those are not fired when using the YADCF clear button.

I also tried:

oTable.on( 'search.dt', function() {
    $(this).find('th').each(function() {
      if ( $(this).find('.select2-search-choice').length || $(this).find('.inuse').length ) {
        $(this).addClass('filtered_col');
      } else {
        $(this).removeClass('filtered_col');
      }
    });
});

//It works selecting with 'auto_complete' and with 'text' types.
//and with respective YADCF Clear button.
//also selecting with 'select2' type and clearing with Select2 clear button,
//but NOT clearing select2 with YADCF clear button 
//'range_date' is not being targeted here.

So, how could I react to active filters to show and hide an active icon when the user filters each column?

EDIT: As suggested in @Daniel's Answer (thank you :), I tried to listen to DOMSubtreeModified:

  $('#main_container').find('.yadcf-filter-wrapper').bind('DOMSubtreeModified', function(e) {
    if( $(e.target).closest('th').find('.select2-search-choice').length || $(e.target).closest('th').find('.inuse').length ) {
      $(e.target).closest('th').addClass('filtered_col');
    } else {
      $(e.target).closest('th').removeClass('filtered_col');
    }

  });
  //Event is only firing with 'select2' filtering and clearing
  //No other filter types are firing this event, although one CSS class is being added in 'text' filters.

Soo, I tried now to modify jquery's addClass / removeClass, to make them trigger some events (as suggested in this answer):

  (function(){
    var originalAddClass = jQuery.fn.addClass;
    var originalRmvClass = jQuery.fn.removeClass;
    jQuery.fn.addClass = function(){
      // Execute the original method.
      var result = originalAddClass.apply( this, arguments );
      // trigger a custom event
      jQuery(this).trigger('cssClassAdded');
      // return the original result
      return result;
    }
    jQuery.fn.removeClass = function(){
      var result = originalRmvClass.apply( this, arguments );
      jQuery(this).trigger('cssClassRmvd');
      return result;
    }
  })();

  // And then..
  $(function() {
    $('.yadcf-filter-wrapper').on('cssClassAdded', function(){ 
      if( $(this).closest('th').find('.select2-search-choice').length || $(this).closest('th').find('.inuse').length ) {
        $(this).closest('th').find('.fa-filter').css('display', 'block');
      }
    });
    $('.yadcf-filter-wrapper').on('cssClassRmvd', function(){ 
      if( !$(this).closest('th').find('.select2-search-choice').length && !$(this).closest('th').find('.inuse').length ) {
        $(this).closest('th').find('.fa-filter').css('display', 'none');
      }
    });
  });
  //This is the best approach, since is working with 'text', 'select2' and 'auto_complete', with both filtering and clearing actions.
  //'range_date' is the only one I still need to cover.

As said, with this last example I could solve the problem in all filter types but 'range_date'. The only idea I have now is, as suggested by @Daniel, to modify YADCF to introduce some class in this case (for manteinance reasons I'd like to avoid this).

I expected that 'inuse' class would be added as well in range_date filters. It would do the trick, with my last approach. Is YADCF so desiged, to only introduce this class in some filter types and not in all of them? Maybe I am missing something?

I still would appreciate any better solution to solve this, specially for 'range_date', which I couldn't solve at all.

Thanks

Community
  • 1
  • 1
chimos
  • 664
  • 2
  • 14
  • 34

2 Answers2

0

You can try to listen to dom change event of the filters because when filter in use yadcf adds a class inuse to the filter and when filter is being cleared the inuse class is being removed, it will work for most of the filters (except select2) for select2 you can patch yadcf to add / remove the inuse class to the select filter (not the the visible one but the original one that gets the select2-offscreen class when select2 is being created)

For example

$('.yadcf-filter').bind('DOMSubtreeModified', function(e) {
      alert('class changed');
});
Daniel
  • 36,833
  • 10
  • 119
  • 200
  • Thanks for your quick answer. But actually, only the 'select2' filters are firing this `DOMSubtreeModified` event, 'text', 'date-range' and 'auto_complete' are not (although `inuse` class is being added in the case of 'text' filters). – chimos Sep 06 '16 at 11:28
  • Please, see my 'EDIT' in the question. – chimos Sep 06 '16 at 11:59
0

I know this is an old question, but I just found a different (& easier) way to archive this. Maybe it helps someone else.

Just hook on the "draw" event from the datatable and add/remove a css class depending on oSavedState.columns...

    $('#my-table').on('draw.dt', function (e, oSettings) {
            var th = $('tr th',this); // find all TH elements of current table

            $.each(oSettings.oSavedState.columns, function( index, col ) {
                if (th.length > index){
                    if (col.search && col.search.search != ""){ // filter is active
                        $(th[index]).addClass('filtered_col'); // add class to col's TH
                    } else {
                        $(th[index]).removeClass('filtered_col'); // remove class from col's TH
                    }
                }
            });
        });

Rest is css...

Should work using any filter-plugin or even manually added filters.

UPDATE:

If you don't use stateSave on your datatable, (or even then - it's even shorter) it might be better to use aoPreSearchCols instead of oSavedState.columns:

    $('#my-table').on( 'draw.dt', function (e,oSettings) {
        var th = $('tr th',this);
        $.each(oSettings.aoPreSearchCols, function( index, search ) {
            if (th.length > index){
                if (search.sSearch != ""){
                    $(th[index]).addClass('col-filtered');
                } else {
                    $(th[index]).removeClass('col-filtered');
                }
            }
        });
    });
huelke
  • 1
  • 1