列表中的 Hide/show 个元素使用 jQuery 的多个复选框字段集

Hide/show elements in a list using multiple checkbox fieldsets with jQuery

我有以下 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 属性包含我想用来根据用户在复选框输入列表中的选择来过滤(即 show/hide)它们的值:

<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 以尝试仅显示其 class 值对应于选中输入的名称值的列表项:

$(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();

    });
}); 
});

结果差不多了。我遇到的问题是第二个 ("course-level") 字段集。例如,如果用户单击 "music",它会产生所需的结果,即同时显示 "beginner" 和 "expert" 级别的音乐列表项。如果用户随后单击 "beginner,",也会产生所需的结果:"expert" 音乐列表项被隐藏。问题是,当用户下次点击 "expert," 时,即他想同时查看初学者和专家音乐结果时,这两个音乐结果都被隐藏了。

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

我认为问题是这一行只隐藏项目而不显示它们,但我无法解决:

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

有什么想法吗?

您似乎正在尝试执行以下操作:

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

这让用户和代码感到困惑,因为这意味着您想查看初学者级别 类 if either 初学者复选框是否被选中或初学者复选框未选中,专家复选框也未选中。因此,您是否看到初学者课程不仅取决于初学者复选框,还取决于专家复选框。

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

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

    // ... 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/

我形成一个 select 或对应于每个选项组并按每个选项组过滤以形成列表 show.This 代码在每个复选框组中也有 'all' 复选框 - 如果是selected 我使用 select 所有 select 或 '*'。

$(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();
   });



});