【问题标题】:jQuery Multiple Checkbox Page FilterjQuery 多复选框页面过滤器
【发布时间】:2011-09-25 10:39:16
【问题描述】:

我一直在试图弄清楚如何正确执行此操作,但似乎无法使其正常工作。

我想使用 jQuery 从本质上挑选我想在页面上显示的内容。我已经查看并试图找到一些脚本,有些工作,但不是我想要的。

页面将使用复选框作为“标签”,比如艺术、计算机、健康、视频游戏

 <div class="tags">
 <label><input type="checkbox" class="arts" /> Arts </label>
 <label><input type="checkbox" class="computers" /> Computers </label>
 <label><input type="checkbox" class="health" /> Health </label>
 <label><input type="checkbox" class="video-games" /> Video Games </label>
 </div>

然后在页面上会有结果,每个结果都有标签。

 <ul class="results">
 <li class="arts computers">
     Result 1
 </li>
 <li class="video-games">
     Result 2
 </li>
 <li class="computers health video-games">
     Result 3
 </li>
 <li class="arts video-games">
     Result 4
 </li>
 </ul>

我希望能够点击艺术和视频游戏,它会显示同时具有艺术和视频游戏的所有内容,因此结果 4。或者能够只选择计算机并返回结果 1 和 3。

我在想我可以做一些类似的事情

 $('.tags input').click( function() {
      $('.results > li').hide();
      //For each one checked
      $('input').is(':checked').each( function() {
           //Display that result
           $('.results li').hasClass($(this).attr('class')).show();
      });      
 });

但它不起作用,它只是隐藏了所有内容,然后不会回来显示其余部分。我知道逻辑完全错误,我认为我不应该以这种方式使用 each 吗?也许用它来抓取数组中的所有类,然后显示具有这些类的 li?

有什么想法吗?

【问题讨论】:

    标签: php jquery mysql filter tags


    【解决方案1】:

    试试grep function。伪伪代码:

    $(yourstuff).grep(filter1).grep(filter2)...
    

    【讨论】:

    • 确切地说,这在这里有用吗?
    • “将显示同时具有艺术和视频游戏的所有内容”...所以我猜链式 grep 将实现该逻辑,但我可能错了。
    • 喜欢你的解决方案。不错。
    【解决方案2】:

    两个问题。

    1. 输入选择器 -.is 是一个函数,而不是一个选择器。
    2. hasClass- 也不是选择器。

    它们都返回truefalse,因此您不能像 jQuery 对象那样对它们的结果进行操作。

    http://jsfiddle.net/5z7M5/3/

     $('.tags input').click( function() {
          $('.results > li').hide();
          //For each one checked
          $('input:checked').each( function() {
    
               $('.'+$(this).attr('class')).show();
          });      
     });
    

    【讨论】:

    • 回复:问题 #1,OP 没有尝试使用 .is() 作为选择器。
    • .is(..).each(..)? 是的。
    • 抱歉,我不想学究气——我明白你现在的意思了。 实际问题#1是.is()返回一个布尔值。
    • 在他的用法中,他试图像 ":checked" 选择器一样使用它。我就是这个意思。
    【解决方案3】:
    • 使用复选框的.change() 事件。
    • .hasClass() 返回一个布尔值。
    • 将该信息存储在class 以外的属性中更有意义,例如reldata-* 属性。

    $('div.tags').delegate('input:checkbox', 'change', function()
    {
         var $lis = $('.results > li').hide();
         $('input:checked').each(function()
         {
              $lis.filter('.' + $(this).attr('rel')).show();
         });      
    }).find('input:checkbox').change();
    

    演示:http://jsfiddle.net/mattball/d2v4Q/


    @贾斯汀问

    您将如何更改此设置以仅返回匹配所有复选框而不是其中任何一个的 lis?

    将每个检查的输入中的东西(您使用的任何属性)放入一个数组,String.join('.') 它创建一个大类选择器,然后像以前一样 .filter() &lt;li&gt;s:

    var selector = $('input:checked').map(function ()
    {
        return $(this).attr('rel');
    }).get().join('.');
    $lis.filter(selector).doWhatever();
    

    【讨论】:

    • 您将如何更改此设置以仅返回匹配所有复选框而不是任何一个复选框的lis?
    • 非常感谢您的快速回复!工作,它很简单,所以我必须喜欢它。谢谢!只是好奇是否有一种简单的方法可以让它们全部显示出来,然后在我点击一个之后它就会开始过滤。我想将 $('.results > li).hide() 更改为 show() 然后添加一个 $('input:not(:checked)').each 并在里面添加一个 hide()?
    • @derno 哦,我实际上输入了额外的代码来启动所有 &lt;li&gt;s 隐藏。只需删除.find('input:checkbox').change() - 请参阅jsfiddle.net/mattball/gd276
    • @derno 还有,如果我的回答解决了你的问题,你介意accepting it吗?
    • @matt-ball 这实际上只是在开始时有效,但是如果您在检查了一些之后取消选中所有这些,那么它不会显示所有内容。关于如何做到这一点的任何想法?另外 - 接受了你的回答,因为我是新人所以不知道。
    【解决方案4】:

    我稍微改变了 Matt 的解决方案,使其能够满足您的要求。至少我是如何解释它的(仅显示与 all 所选类别匹配的项目)。不过,它绝不像马特的解决方案那样优雅:

    HTML:

    <div class="tags">
        <label><input type="checkbox" data-category="arts" /> Arts </label>
        <label><input type="checkbox" data-category="computers" /> Computers </label>
        <label><input type="checkbox" data-category="health" /> Health </label>
        <label><input type="checkbox" data-category="video-games" /> Video Games </label>
    </div>
    
    <ul class="results">
        <li data-category="arts computers">
            Result 1
        </li>
        <li data-category="video-games">
            Result 2
        </li>
        <li data-category="computers health video-games">
            Result 3
        </li>
        <li data-category="arts video-games">
            Result 4
        </li>
    </ul>
    

    还有 JS:

    $('div.tags').delegate('input:checkbox', 'change', function() {
        $('.results > li').hide();
    
        var selector = $('input:checked').map(function() {
            return $(this).attr('data-category');
        }).get();
    
        function matchesCategories(elem) {
            var elemCats = elem.attr('data-category');
    
            if (elemCats) {
                elemCats = elemCats.split(' ');
            } else {
                elemCats = Array();
            }
            for (var i = 0; i < selector.length; i++) {
                console.log("testing " + selector[i] + " in:");
                console.log(elemCats);
                if (jQuery.inArray(selector[i], elemCats) == -1) {
                    return false;
                }
            }
            return true;
        }
        $('.results > li').each(function(i, elem) {
            if (matchesCategories(jQuery(elem))) {
                $(elem).show();
            }
        });
    
    }).find('input:checkbox').change();
    

    如果你想试试,这里是我的jsfiddle entry (forked from Matt's)

    【讨论】:

    • 感谢这个几乎与马特相反的解决方案,这对我来说也可能非常有用!
    • 不能,我只有 10 个代表,需要 15 个 =(
    【解决方案5】:
    $('.tags')
        .on('update', function() {
            // Limit the selector(s) to search for:
            var $filters = $(this).find('input:checked');
    
            // Get the class names of interest
            // Return null (rather than "") to keep them out of the result array
            var $classes = $filters.map(function(){ return this.className || null; });
    
            // Use .replace() if your checkboxes might target multiple classes
            var selector = $classes.get().join('.').replace(/ /g,'.');
    
            var $results = $('ul.results > li').hide();
    
            if (selector) 
                $results.filter('.'+selector).show();
        })
    
        // Relay any changes to the display-state container (.tags)
        .on('change','input[type="checkbox"]',function() {
            $(event.currentTarget).trigger('update');
        })
    
        // When first loaded, apply the server-supplied checkbox state(s) to the page:
        .trigger('update');​
    

    我非常喜欢 .on() :) [jQuery 1.7+]

    http://jsfiddle.net/ne8dy/

    【讨论】:

      猜你喜欢
      • 2012-04-02
      • 2011-10-25
      • 2014-05-12
      • 1970-01-01
      • 2017-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多