使用带有jQuery的多个复选框字段集隐藏/显示列表中的元素

时间:2015-02-26 18:11:29

标签: jquery list filter

我有以下HTML列表:

<ul id="results">
    <li class="music beginner">Music, Beginner</li>
    <li class="music expert">Music, Expert</li>
    <li class="cooking beginner">Cooking, Beginner</li>
    <li class="cooking expert">Cooking, Expert</li>
</ul>

每个列表项的class属性包含我想用来根据用户在复选框输入列表中的选择来过滤(即显示/隐藏)它们的值:

<form id="filter-container">
    <fieldset id="course-type">
        <label>Course Type</label>
        <input type="checkbox" name="music" />Music
        <input type="checkbox" name="cooking" />Cooking
    </fieldset>
<br />
    <fieldset id="course-level">
        <label>Course Level</label>
        <input type="checkbox" name="beginner" />Beginner
        <input type="checkbox" name="expert" />Expert
    </fieldset> 
</form>

当用户单击任何复选框时,以下jquery运行以尝试仅显示其类值对应于已检查输入的名称值的列表项:

$(document).ready(function () {

//make sure browser clears all checked boxes on reload
$(':checkbox:checked').prop('checked',false);

//hide all results
$('#results > li').hide();

//When any checkbox inside #filter-container is clicked ...
$('#filter-container').find('input:checkbox').live('click', function () {

    // ... 1. hide all results
    $('#results > li').hide();

    // ... 2. find the checked boxes in the "course-type" fieldset
    $('#course-type').find('input:checked').each(function () {

        // ... 3. show the results whose class has the value of the checked boxes'name
        $('#results > li.' + $(this).attr('name')).show();
    });

    // ... 4. find the checked boxes in the "course-level" fieldset
    $('#course-level').find('input:checked').each(function () {

        // ... 5. hide the results whose class doesn't have the value of the checked boxes' name
        $('#results > li:not(.' + $(this).attr('name')).hide();

    });
}); 
});

结果几乎可行。我遇到的麻烦是第二个(“课程级别”)字段集。例如,如果用户点击“音乐”,则它产生所需的结果,即“初学者”和“专家”级音乐列表项目都显示。如果用户点击“初学者”,则还会产生所需的结果:隐藏“专家”音乐列表项。问题是,当用户下次点击“专家”时,即他想要看到初学者和专家音乐结果时,两个音乐结果都被隐藏。

这是一个jsfiddle:http://jsfiddle.net/5a255e0j/

我认为问题是这一行只是隐藏物品但没有显示它们,但我无法解决:

$('#results > li:not(.' + $(this).attr('name')).hide();

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

我形成一个与每个选项组相对应的选择器,并按每个选项组进行过滤以形成要显示的列表。此代码还具有“全部”选项。每个复选框组中的复选框 - 如果选中,我会使用全选选择器&#39; *&#39;。

$(document).ready(function () {

    //make sure browser clears all checked boxes on reload
    $(':checkbox:checked').prop('checked',false);

    //check all of the "All" boxes on reload
    $('input.all').prop('checked',true);

    //When any checkbox inside #filter-container is clicked ...
    $('#filter-container').find('input:checkbox').live('click',    function () {
    var items = $('#results > li');
    var all_courses = $('#course-type input.all');
    var all_levels = $('#course-level input.all');
    // ... 1. hide all results
    items.hide();

    var course_sel = '*';
    if( ! all_courses.prop('selected'))
    {
        course_sel = 
        $('#course-type').find('input:checked').map(function () {    
        return '.' + $(this).attr('name');
        }).get().join();

    }

    var level_sel = '*';
    if( ! all_levels.prop('selected'))
    {
       level_sel = 
       $('#course-level').find('input:checked').map(function () {
       return '.' + $(this).attr('name');
       }).get().join();

   }

   items.filter(course_sel).filter(level_sel).show();
   });



});

答案 1 :(得分:1)

您似乎要做的就是以下内容:

显示所选类型的所有课程除非选中其中一个级别复选框,在这种情况下,仅显示已检查级别和类型的课程。

这让用户和代码感到困惑,因为这意味着如果选中 初学者复选框,或者取消选中初学者复选框,并且专家复选框也是选中。因此,您是否看到初学者课程不仅取决于初学者复选框,还取决于专家复选框。

我认为更简单的模型是选中所有级别复选框,然后只显示已检查级别和类型的课程。

无论您使用哪种型号,诀窍都是遍历这些项目,并确保项目的每个类名应显示如下:

    // ... 2. Hide all the results containing an unchecked class name
$('#results > li').each(function () {
    var classes = $(this).attr('class').split(" ");
    for ( var i = 0, l = classes.length; i<l; ++i ) {
        if (!($("input:checkbox[name='" + classes[i] +"']").is(':checked'))) {
            $(this).hide();
        }
    }
});

这是我实现更简单模型的jsfiddle: http://jsfiddle.net/dvew4yq3/

这是我实现原始模型的jsfiddle: http://jsfiddle.net/c4dp7gqk/