Pascal Cloverfield
Pascal Cloverfield

Reputation: 581

metafizzy's isotope - deactivate filter if no combination result

i'm using metafizzy' isotope for filtering items.

I've got 2 filter rows: category1 (cable,tools,stuff1,stuff2) and category2(cable1,cable2,tool1,tool2).

Is it possible to deactivate a filter (with CSS, e.g. grey out) if there will be no result when combining two categories?

Example: i click on the filter 'stuff2' and in category2 there is no item that matches so jQuery adds a class to category2 like grey them out.

My isotope code:

jQuery.noConflict();
(function($){
    var $container = $('#container'),
    filters = {};

$container.isotope({
  itemSelector : '.element',
      {mfilterscript}
      {mfilterscript2}
});

// filter buttons
$('.filter a').click(function(){
  var $this = $(this);
  // don't proceed if already selected
  if ( $this.hasClass('selected') ) {
    return;
  }

  var $optionSet = $this.parents('.option-set');
  // change selected class
  $optionSet.find('.selected').removeClass('selected');
  $this.addClass('selected');

  // store filter value in object
  // i.e. filters.color = 'red'
  var group = $optionSet.attr('data-filter-group');
  filters[ group ] = $this.attr('data-filter-value');
  // convert object into array
  var isoFilters = [];
  for ( var prop in filters ) {
    isoFilters.push( filters[ prop ] )
  }
  var selector = isoFilters.join('');
  $container.isotope({ filter: selector });

  return false;
});

})(jQuery);

Upvotes: 1

Views: 1744

Answers (1)

DrewT
DrewT

Reputation: 5072

It's absolutely possible.

You need to do a couple things

1) check the length of the filter array for all possible future filter combinations

For example, say you have a list of fruits all of which have a class "fruit" and a class for fruit type "apple", "pear", "orange" etc.

You would do something like this:

    $('a.fruit').each(function() {
            var $this = $(this);
            var getVal = $this.attr('data-filter-value');
            var numItems = $('img'+getVal+':not(.isotope-hidden)').length; // <-- This example is for filtering img tags but just replace it with whatever element you're actually filtering
            if(!$(this).hasClass('active') && !$that.hasClass('fruit') ){ // <-- i.e. it's a fruit that has not already disabled by previous filter combinations
                if(numItems === 0){
                    $this.addClass('disabled');
                }
                else {
                    $this.removeClass('disabled');
                }
            }
            else if( $this.hasClass('active') && $this.hasClass('disabled') ){
                $this.removeClass('disabled');
            }
            else if(!$(this).hasClass('active') ) {
                if(numItems > 0){
                    $this.removeClass('disabled');
                }
            }
        });

2) You're going to need to add some code to handle your disabled filters so they can't be triggered. The best place to do it is near the top of your filtering routine. I.e. before any filtering has been processed you want to exit the routine.

There's many ways to do it (e.preventDefaults for example, but it's maybe safer in this case to just return false so we don't have to worry about re-binding the default behaviour afterwards).

For example you might do something like this:

    $('.filter a').click(function(){
        // exit directly if filter already disabled
        if ($(this).hasClass('disabled') ){
            return false;
        } else if ($(this).hasClass('selected') ) {
            return false;
        }

        ... 

    }); // close routine

Here's a live example of everything working

And here's all the JavaScript for that example.

Hope that helps!

Upvotes: 5

Related Questions