Isotope Filtering - Issues when reset to start position

流过昼夜 提交于 2020-01-16 09:27:08

问题


I have built a Isotope grid layout to display projects, which also uses the Isotope filtering to sort through the projects quicker.

The filtering works fine until you try to put the dropdowns back to their default position "All Services" & "All Sectors". Then all the projects are hidden, when they should all be displayed.

http://www.ellyon.co.uk/wp/projects/

EDIT: Is it possibly a Jquery conflict? I've added my functions.php as im not 100% sure ive added scripts correctly.

functions.php

function add_isotope() {
    wp_register_script( 'isotope-init', get_template_directory_uri().'/js/isotope.js', array('jquery', 'isotope'),  true );
    wp_register_style( 'isotope-css', get_stylesheet_directory_uri() . '/styles/project.css' );

    wp_enqueue_script('isotope-init');
    wp_enqueue_style('isotope-css');
}
add_action( 'wp_enqueue_scripts', 'add_isotope' );

function modify_jquery() {
    if ( !is_admin() ) {
        wp_deregister_script( 'jquery' );
        wp_register_script( 'jquery', 'https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js', false, '3.2.1' );
        wp_enqueue_script( 'jquery' );
    }
}
add_action( 'init', 'modify_jquery' );

Isotope.js

// Grid
var $grid = $('.grid').isotope({
  itemSelector: '.grid-item',
  layoutMode: 'packery',
  columnWidth: '.grid-sizer',
  packery: {
    gutter: '.gutter-sizer'
  }
});


// state variable
var $expandedItem;

// expand when clicked
$grid.on( 'click', '.grid-item', function( event ) {
  var isExpanded = $expandedItem && event.currentTarget == $expandedItem[0];
  if ( isExpanded ) {
    // exit if already expanded
    return;
  }
  // un-expand previous
  if ( $expandedItem ) {
    $expandedItem.removeClass('gigante');
  }
  // set new & expand
  $expandedItem = $( event.currentTarget ).addClass('gigante');
  $grid.isotope('layout');
});

$grid.on( 'click', '.close-button button', function( event ) {
  $expandedItem.removeClass('gigante');
  // reset variable
  $expandedItem = null;
  $grid.isotope('layout');
  event.stopPropagation();
});

// Select Filters
$(function() {
    var $container = $('.grid'),
        $select = $('div#filterGroup select');
    filters = {};

    $container.isotope({
        itemSelector: '.grid-item'
    });
        $select.change(function() {
        var $this = $(this);

        var $optionSet = $this;
        var group = $optionSet.attr('data-filter-group');
    filters[group] = $this.find('option:selected').attr('data-filter-value');

        var isoFilters = [];
        for (var prop in filters) {
            isoFilters.push(filters[prop])
        }
        var selector = isoFilters.join('');

        $container.isotope({
            filter: selector
        });

        return false;
    });

    $grid.imagesLoaded().progress( function() {
      $grid.isotope('layout');
    });

});

回答1:


Asterisk, *, is a special case and need to be handled differently from other filter values such that:

  • if one or more non-asterisk value is selected, then all asterisks should be ignored
  • if no non-asterisk value is selected, then default to a single asterisk (show all).

There must be a number of ways to implement those rules. Here's one :

// Select Filters
$(function() {
    var $grid = $('.grid');
    var $selects = $('div#filterGroup select').change(function() {
        var selector = $selects.get().map(function(el) { // map the select elements ...
            return $(el).data('filter-value'); // ... to an array of filter-values
        }).filter(function(val) {
            return val !== '*' // filter out all '*' values
        }).join('') || '*'; // if joined array is empty-string, then default to a single '*'
        $grid.isotope({
            'filter': selector
        });
        return false;
    });
    ...
});

Note that the original code's filters object only adds unnecessary complexity. The DOM is very good at representing its own state, so instead of maintaining a persistent mapping in javascript, it's simpler to map both select elements directly to Array every time there is a change to either one of them.

The code would simplify slightly if the HTML was constructed as follows :

<select class="filter option-set" data-filter-group="services">
    <option value="">All Services</option>
    <option value='.cladding'>Cladding</option>
    ...
</select>
<select class="filter option-set" data-filter-group="sectors">
    <option value="">All Sectors</option>
    <option value='.commerical'>Commerical</option>
    ...
</select>

Then, the need to .filter() out asterisks would disappear, leaving :

$(function() {
    var $grid = $('.grid');
    var $selects = $('div#filterGroup select').change(function() {
        var selector = $selects.get().map(function(el) { // map the select elements ...
            return $(el).val(); // ... to an array of values
        }).join('') || '*'; // if joined array is empty-string, then default to a single '*'
        $grid.isotope({
            'filter': selector
        });
        return false;
    });
    ...
});


来源:https://stackoverflow.com/questions/50451048/isotope-filtering-issues-when-reset-to-start-position

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!