同位素:组合过滤+多重选择

问题描述 投票:1回答:5

对于那里的所有jQuery heros,我需要帮助! (再次)

我在互联网上发现了类似的问题,但到目前为止还没有答案: - /

我想用jquery同位素过滤一堆物品。我从插件主页调整了组合过滤器示例,它工作正常,看起来像这样:

$(function () {
var $container = $('#container'),
    filters = {};
$container.isotope({
    itemSelector: '.item',
    filter: '',
});

// filter links
$('.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;
}); });

和一些过滤菜单的HTML:

<div id="nav">
    <ul class="filter option-set" data-filter-group="who">
        <li><a href="#filter-who-any" data-filter-value="" class="selected">Any</a></li>
        <li><a href="#filter-who-boys" data-filter-value=".boys">Boys</a></li>
        <li><a href="#filter-who-girls" data-filter-value=".girls">Girls</a></li>
    </ul>

</div>

我设置了一个小提琴演示,其中有3个滤镜类别可以合并:jsFiddle

现在我想让从每个类别中选择多个标签:

第1类:OR b或c

第2类:OR b或c

第3类:OR b或c

desandro有一个check-box-example,但这不是我正在寻找的东西,因为我想在类别之间保持AND条件。基本上我想要3个过滤器类别,每个过滤器类别都有一些复选框(或链接,但我想复选框更实用)。我认为两个示例中使用的方法完全不同,我不知道如何组合它们的功能。

我希望你明白我的观点,任何人都可以帮我找到解决方案。

提前致谢!

jquery jquery-isotope
5个回答
13
投票

使用具有metafizzy同位素过滤的多种过滤器类型需要多维数组来保存每种过滤器类型的数组。

我有一个实例here

例子中的js是here

有关完整的代码说明,请参阅我对this question的回答


5
投票

看看这里

http://codepen.io/desandro/pen/btFfG

这是DrewT的答案,但来自同位素团队。

为了过滤,你所要做的就是将每个组放在同一个对象下

        var filters = {};//sould be outside the scope of the filtering function


  $a.click(function(){//filtering function
                var group = $optionSet.attr('data-filter-group');
             var filterGroup = filters[group];
                              if (!filterGroup) {
                                  filterGroup = filters[group] = [];
                              }
         filters[ group ].push($this.attr('data-filter-value'));
  })

现在你所要做的就是调用getComboFilter函数(你不必理解getComboFilter里面的代码,把它当成同位素的一部分)

     var comboFilter = getComboFilter( filters );
 $container.isotope({ filter: comboFilter});

function getComboFilter( filters ) {
  var i = 0;
  var comboFilters = [];
  var message = [];

  for ( var prop in filters ) {
    message.push( filters[ prop ].join(' ') );
    var filterGroup = filters[ prop ];
    // skip to next filter group if it doesn't have any values
    if ( !filterGroup.length ) {
      continue;
    }
    if ( i === 0 ) {
      // copy to new array
      comboFilters = filterGroup.slice(0);
    } else {
      var filterSelectors = [];
      // copy to fresh array
      var groupCombo = comboFilters.slice(0); // [ A, B ]
      // merge filter Groups
      for (var k=0, len3 = filterGroup.length; k < len3; k++) {
        for (var j=0, len2 = groupCombo.length; j < len2; j++) {
          filterSelectors.push( groupCombo[j] + filterGroup[k] ); // [ 1, 2 ]
        }

      }
      // apply filter selectors to combo filters for next group
      comboFilters = filterSelectors;
    }
    i++;
  }

  var comboFilter = comboFilters.join(', ');
  return comboFilter;
}

3
投票

以下是您可以使用多个选择下拉菜单的同位素组合过滤器的JS小提琴代码

$(document).ready(function(){
  // init Isotope
  var $grid = $('.grid').isotope({
    itemSelector: '.item'
  });

  // store filter for each group
  var filters = {};

  $('.filters').on('change', '.filters-select', function(){
    var $this = $(this);
    var filterGroup = $this.attr('data-filter-group');
    filters[ filterGroup ] = $this.val();
    var filterValue = concatValues( filters );
    $grid.isotope({ filter: filterValue });
  });

  // flatten object by concatting values
  function concatValues( obj ) {
    var value = '';
    for ( var prop in obj ) {
      value += obj[ prop ];
    }
    return value;
  }
});

https://jsfiddle.net/srikanthLavudia/vhrbqn6p/


0
投票

我可以使它工作,但它并不像我在第一个实例中想象的那么简单。我想你需要记住几件事:

  1. 如果您想使用限制性条件,那么我建议不要使用“data-filter-value”选项。相反,将过滤器变量作为类。然后,您需要在onclick事件中自己激发同位素功能。这是因为否则当用户单击按钮并且您将无法实现限制性AND时,您将触发“默认”同位素功能。
  2. 在同一方向,您将需要为要使用的嵌套过滤器选项的每个组合使用新的变量名称(因此为新类)。否则,我没有看到其他方式(目前)获得限制性条件。

关于限制性和非限制性AND子句的这个概念就像外部和内部连接之间的区别。如果你想处理两个过滤器,一个是另一个过滤器的子过滤器,那么你应该使用这个概念。 一个例子就是可以按品牌过滤的电子书列表,另一个基于它们所属的不同范围价格的子过滤器。

我在下面给出了一个代码示例,我实现了这个想法,它可以给你一个我的意思:

HTML:

<!--Filters section -->
<div id="filters">
    <ul id="optionSet1" class="option-set" data-option-key="filter">
           <li><a id="filter10" href="#filter" class="selected">Everything</a></li>
        <c:forEach var="brand" items="${brands}" varStatus="status" >
             <li><a id="filter1${status.count}" href="#filter" class='${brand}'>${brand}</a></li>
        </c:forEach>
    </ul>
    <ul id="optionSet2" class="option-set" data-option-key="filter">
        <li><a id="filter20" href="#filter" class="selected">Any Price</a>  </li>
    <c:forEach var="brandPrice" items="${brandPrices}" varStatus="status" >
        <li><a id="filter2${status.count}" href="#filter" class='${brandPrice}'>${brandPrice}</a></li>
    </c:forEach>
    </ul>
</div>  


<!--Elements to filter -->
<div id="portfolio-wrapper" class="row">
    <c:forEach var="publication" items="${publications}" varStatus="status" >               
        <div class='span4 portfolio-item ${publication.filterOption1} ${publication.filterOption2} ${publication.filterOption3}...'>
<!-- filterOption3 would be the combination of filterOption1 and filterOption2, you can make this building a string as the addition of filterOption1 and filterOption2 strings-->
            <!--Content to display-->           
    </c:forEach>
</div>

JavaScript的:

$(function(){

        $("a[id^='filter1']").on('click', function() {
//          alert($(this).attr('class'));
//          alert($('#optionSet2 .selected').attr('class'));
            var myclass = $('#optionSet2 .selected').attr('class');
            myclass = myclass.replace(' selected','');
            myclass = myclass.replace('selected','');
            var myclass2 = $(this).attr('class');
            myclass2 = myclass2.replace(' selected','');
            myclass2 = myclass2.replace('selected','');
            if($(myclass=='' && myclass2==''){
                $('#portfolio-wrapper').isotope({ filter: '*'});
            }else if(myclass==''){
                $('#portfolio-wrapper').isotope({ filter: '.'+ myclass2+'' });
            }else if(myclass2==''){
                $('#portfolio-wrapper').isotope({ filter: '.'+myclass+'' });
            }else{

                $('#portfolio-wrapper').isotope({ filter: '.'+myclass2+myclass+''});
            }   
        });

        $("a[id^='filter2']").on('click', function() {
//          alert($(this).attr('class'));
//          alert($('#optionSet1 .selected').attr('class'));
            var myclass = $('#optionSet1 .selected').attr('class');
            myclass = myclass.replace(' selected','');
            myclass = myclass.replace('selected','');
            var myclass2 = $(this).attr('class');
            myclass2 = myclass2.replace(' selected','');
            myclass2 = myclass2.replace('selected','');
            if(myclass=='' && myclass2==''){
                $('#portfolio-wrapper').isotope({ filter: '*'});
            }else if(myclass==''){
                $('#portfolio-wrapper').isotope({ filter: '.'+ myclass2+'' });
            }else if(myclass2==''){
                $('#portfolio-wrapper').isotope({ filter: '.'+myclass+'' });
            }else{

                $('#portfolio-wrapper').isotope({ filter: '.'+myclass+myclass2+''});
            }
        });

});

0
投票

很抱歉疏通这个问题,但我最近遇到了同样的问题,并且(imho)浪费了很多时间用组合选择器来解决这个问题。 (将数组A中的每个类与数组B中的每个类组合起来,等等)

使用过滤功能。它允许任意复杂性,并且可能是所有非平凡案例的正确选择。

最重要的是,使用选择器没有性能优势(如果将选择器直接馈入querySelector或jQuery调用,您可能会期望这样做)。 Isotope遍历每个项目并将选择器应用为函数,无论如何:

return function( item ) {
  return matchesSelector( item.element, filter );
};

因此,您可以将过滤逻辑放入函数中,而不是尝试生成选择器字符串。

© www.soinside.com 2019 - 2024. All rights reserved.