【问题标题】:jquery - Multiple selection filter with multiple categoriesjquery - 具有多个类别的多选过滤器
【发布时间】:2012-07-29 21:19:53
【问题描述】:

我有三类控件,每类都有几个选项:

    <ul class="series-selector-items">
        <li id="filter-type-A">A</li>
        <li id="filter-type-B">B</li>
        <li id="filter-type-C">C</li>
    </ul>
    <ul class="series-selector-items">
        <li id="filter-type-E">E</li>
        <li id="filter-type-F">F</li>
        <li id="filter-type-G">G</li>
    </ul>
    <ul class="series-selector-items">
       <li id="filter-type-H">H</li>
       <li id="filter-type-I">I</li>
       <li id="filter-type-J">J</li>
       <li id="filter-type-K">K</li>
    </ul>

然后我有一个列表,其中包含来自上述控件的属性组合的项目:

    <ul>
     <li class="A E H">Item AEH</li>
     <li class="A F I">Item AFI</li>
     <li class="A G J">Item AGJ</li>
     <li class="A G H">Item AGH</li>
     <li class="B E H">Item BEH</li>
     <li class="B F H">Item BFH</li>
     <li class="B F H">Item BFH</li>
     <li class="C E I">Item CEI</li>
     <li class="C G K">Item CEI</li>
etc etc...
    </ul>

我正在尝试找到一种方法来根据所选控制选项的组合过滤结果。我需要能够选择控制选项的任意组合(例如 A E H)并显示所有具有正确属性的项目(项目 AEH)。

每个类别中应可选择多个选项 (A B E K),并且类别应协同工作以显示具有正确元素组合的选项。如果从同一类别中选择了多个选项,它们的结果仍应显示。 我已将控制列表设为 li,但它们也可以是复选框。

用 jQuery 最好的方法是什么?

编辑:这是我迄今为止尝试过的一种方法,将选定的选项添加到数组中:

var seriesSelected = [];    
$('ul.series-selector-items').click(function(){

            //Select the series clicked and give it the "selected" class
            $(this).toggleClass("selected");

            //Once selected, add the series to the seriesSelected array
            if ($(this).hasClass('selected')) {
               seriesSelected.push($(this).attr('id'));
            }
            //If de-selecting (by toggling off the "selected class"), then remove from the seriesSelected array
            else {
                seriesToRemove = $(this).attr('id');
                seriesSelected = $.grep(seriesSelected, function(value) {
                return seriesToRemove != value;
               });
            }
        });

不知道从那里去哪里......

【问题讨论】:

  • 您尝试过什么吗?您是否遇到特定问题?
  • StackOverflow 101:尝试一下并发布一些代码。然后我们会为您修复它。 :)
  • 是的,请向我们展示您到目前为止所做的事情!
  • 我根据一些类似的问题尝试了几种不同的方法,但它们无法显示来自同一类别的多个选项stackoverflow.com/a/6527773

标签: jquery list filter


【解决方案1】:

Update with even better filtering

function filterItems() {
    var classSelectors = $(".selected").map(function() {
        var cls = this.id.split('-');
        return '.' + cls.splice(2).join('-');
    }).toArray().join('');

    if (classSelectors) {
        $('#items > li').filter(classSelectors).show('slow');
        $('#items > li').not(classSelectors).hide('slow');
    }
    else {
        //if no filter, show all
        $('#items > li').show('slow');
    }
}​


Updated Demo
$(document).ready(function() {
    $(".series-selector-items > li").click(function() {
        $(this).toggleClass('selected');
        filterItems();
    });
});

function filterItems() {
    var classSelectors = $(".selected").map(function() {
        var cls = this.id.split('-');
        return '.'+cls.splice(2).join('-');
    }).toArray();

    //if no filter, show all
    if(!classSelectors.length){
        $('#items > li').show('slow');
    }

    $('#items > li').filter(classSelectors.join('')).show('slow');

    $('#items > li').not(function() {
        var self = this;
        var showThis = true;
        $.each(classSelectors, function(i,value) {
            if(!$(self).is(value)) {
                showThis = false;
            }
        });
        return showThis;
    }).hide('slow');
}
​

【讨论】:

  • 其实每个类别(列表)中应该可以选择多个项目。
  • @digitopo 抱歉,没有意识到这一点。已更新。
  • 谢谢...这看起来很接近。我不需要生成的项目,因为我拥有一组特定于应用程序的项目列表。我使用的字母实际上只是占位符,使这个问题更通用。实际的控制选项和项目属性更像是“filter-type-womens”和“filter-type-youth”而且属性(类)出现的顺序应该不重要(不要以为你包括了这个,但是只是为了澄清)。我摆脱了生成功能(减去 .click),但现在 $('#series-selector-series > li').not(function() 似乎不起作用......
  • @digitopo 哦,好的。我更新了没有生成的元素。没有它它工作正常(见jsfiddle.net/XPUrt/6)。您可能遗漏了部分 html。
  • 我认为我在更改属性时缺少的部分是这一行:return '.'+$(this).text();由于属性 ex 中有几个带有撇号的控制选项。男士,我更喜欢使用元素的 id。我试图用 return $(this).attr("id"); 替换该行但此时它不起作用。
【解决方案2】:

可能是这样的:

$('li').not($("#sec li")).on('click', function() {
    if ($('.active').length < 3) {
        $(this).toggleClass('active');
        var letters=[];
        $('.active').each(function(i,e) {
            letters.push(e.id.replace('filter-type-',''));
        });
        if ($('.active').length == 3) {
            var elms = $('#sec li').filter(function() {
                if ($(this).is('.'+letters[0])&&$(this).is('.'+letters[1])&&$(this).is('.'+letters[2])) {
                    return this;
                }
            }).show();
            $('#sec li').not(elms).hide();
        }else{
            $('#sec li').hide();                               
        }
    }else{
        if ($(this).is('.active')) $(this).removeClass('active');
    }
});​

FIDDLE

【讨论】:

  • 此解决方案也仅在有组合时才显示项目。我可能没有很好地解释我在寻找什么,但您应该能够看到任何符合指定控件的选项。因此,如果您只选择 A,那么您将获得任何具有 A 类的项目。如果您选择 A 和 B,那么您将获得 A 和 B 项目。对我来说棘手的地方是,当您选择 A(第 1 类)然后选择 E(第 2 类)时,它应该显示同时具有 A 和 E 的所有内容,而不仅仅是具有 A 的所有内容和具有 E 的所有内容。
【解决方案3】:

这是我的解决方案:http://jsfiddle.net/NukGM/2/希望你喜欢!

点击字母,选中的字母(红色)将选中的 ID 累加到一个数组中。每次选择后,都会调用一个单独的方法,该方法会突出显示所选 ID 数组中存在的类的任何结果。

【讨论】:

  • 我查看了您的代码,但它似乎只在您进行组合时突出显示选项。我也想要以下功能:如果您只选择一个选项,则显示具有该属性的所有项目。
  • 啊,我明白了,我已经更新了我的答案。让我知道这是否正确。当然,我的示例只显示了如何定位元素,您需要进行隐藏/显示;)
  • 好的,我知道你做了什么,但我想弄清楚的是如何使用控制选项来限定结果。因此,如果您从 2 个不同的类别中选择控制选项,它们会将列表过滤到仅包含这两个属性的项目。当您从所有 3 个类别中选择选项时,也应如此。此外,您应该能够从同一类别中选择 2 个或更多选项。
  • 好的,大声笑,这很快就变得毛茸茸了!因此,澄清一下,当您选择“A”时,结果应该是“A”类的任何内容。如果我随后将“B”添加到我的选择中,这应该会导致任何具有“A”和“B”类的结果,对吗?最后,如果我将“C”添加到我的选择中,我们应该只得到具有“A B C”特定组合或其任何方向的结果,是吗?
  • 差不多...有3个类别。每个项目都有来自每个类别的 1 个属性。您只能通过从每个类别中选择 1 个控制选项来获得特定组合。例如,如果控件是:ABC DEF GHIJ,那么您将通过选择 ADG 创建一个特定的组合(就像在您概述的场景中一样)。如果你只选择 A 和 D,你应该得到所有具有 A 和 D 属性的项目。如果你选择 ABD,你应该得到所有具有 A 和 D 属性以及 B 和 D 属性的项目。这有意义吗?
【解决方案4】:

在这里,我用可理解的脚本在几个步骤中完成了上述查询的完整垃圾箱。您可以找到以下演示链接:

演示: http://codebins.com/bin/4ldqp90

HTML:

<!-- Select Category Combinators -->
<ul class="series-selector-items">
  <li id="filter-type-A">
    A
  </li>
  <li id="filter-type-B">
    B
  </li>
  <li id="filter-type-C">
    C
  </li>
</ul>
<ul class="series-selector-items">
  <li id="filter-type-E">
    E
  </li>
  <li id="filter-type-F">
    F
  </li>
  <li id="filter-type-G">
    G
  </li>
</ul>
<ul class="series-selector-items">
  <li id="filter-type-H">
    H
  </li>
  <li id="filter-type-I">
    I
  </li>
  <li id="filter-type-J">
    J
  </li>
  <li id="filter-type-K">
    K
  </li>
</ul>
<!-- Search Item from Follwing List based on selected category combinator-->
<ul class="list">
  <li class="A B H">
    Item ABH
  </li>
  <li class="A E H">
    Item AEH
  </li>
  <li class="A F I">
    Item AFI
  </li>
  <li class="A G J">
    Item AGJ
  </li>
  <li class="A G H">
    Item AGH
  </li>
  <li class="B C I">
    Item BCI
  </li>
  <li class="B E H">
    Item BEH
  </li>
  <li class="B F H">
    Item BFH
  </li>
  <li class="C B K">
    Item CBK
  </li>
  <li class="C E I">
    Item CEI
  </li>
  <li class="C G K">
    Item CGK
  </li>
</ul>

CSS:

.series-selector-items{
  display:inline-block;
  list-style:none;
  border:1px solid #3355f9;
  margin:0px;
  padding:0px;
  vertical-align:top;
  background:#fba5a2;
}
.series-selector-items li{
  padding:5px;
}
.series-selector-items li.selected{
  background:#f855f9;
}
.list{
  display:inline-block;
  list-style:none;
  border:1px solid #3355f9;
  margin:0px;
  padding:0px;
  vertical-align:top;
  background:#abd5f9;

}
.list li.searched{
  background: #3344ad;
  color:#dfdbab;
}
.list li{
  padding:3px;
}

jQuery:

$(function() {

     $(".series-selector-items li").click(function() {

            //Set Default UnSearched List
            $(".list li").removeClass("searched");

            var seriesSelected = new Array();
            //Select the series clicked and give it the "selected" class
            $(this).toggleClass("selected");

            //Get All selected combinators 
            $("li.selected").each(function() {
                seriesSelected.push($.trim($(this).attr('id')).replace('filter-type-', ''));

            });


            //Combinator Exists Then...
            if (seriesSelected.length == 3) {

                //Generate Class Name Combination
                var ClassNames = "." + seriesSelected[0] + "." + seriesSelected[1] + "." + seriesSelected[2];

                //Search Item based on Combinator
                if ($(".list li" + ClassNames).length > 0) {
                    //if Found then add Searched Class on Item
                    $(".list li" + ClassNames).addClass("searched");
                }

            } else {
                $(".list li").removeClass("searched");
            }


    });

});

演示: http://codebins.com/bin/4ldqp90

【讨论】:

    猜你喜欢
    • 2016-12-30
    • 2019-05-05
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多