如何使用复选框过滤多个列表项?

时间:2016-11-05 17:05:44

标签: javascript html css checkbox filter

如何创建2个复选框,显示(即)1。食物和2.音乐家......

其中
1)如果同时选中了两个复选框,则显示食物和音乐家;
2)如果检查食物并且音乐家未经检查,该元素仍然可见,因为它包含食物,它还包含音乐家的信息;
3)如果检查音乐家且食物未经检查,它仍然可见,因为它包含音乐家,它还包含食物; 4)如果食物和音乐家都未经检查,则li项目会消失。

我的HTML是:

<html>
<head>
</head>
<body>

<ul class="filterSection">
<li>
<input checked="true" type="checkbox" value="Food"/>
<label>Food</label>
</li>
<li>
<input checked="true" type="checkbox" value="Musician"/>
<label>Musician</label>
</li>
</ul>

<ul id="itemsToFilter">
<li data-type="Food">Food</li>
<li data-type="Musician">Musician</li>
<li data-type="Food Musician">Food & Musician</li>
<ul>

</body>
</html>

以下javascript代码(集成在两个列表下方):

<script>
// get all of our list items
var itemsToFilter = document.querySelectorAll("#itemsToFilter li");
  
//setup click event handlers on our checkboxes
var checkBoxes = document.querySelectorAll(".filterSection li input");
  
for (var i = 0; i < checkBoxes.length; i++) {
    checkBoxes[i].addEventListener("click", filterItems, false);
    checkBoxes[i].checked = true;
}
  
// the event handler!
function filterItems(e) {
    var clickedItem = e.target;
      
    if (clickedItem.checked == true) {
        hideOrShowItems(clickedItem.value, "hideItem", "showItem");
    } else if (clickedItem.checked == false) {
        hideOrShowItems(clickedItem.value, "showItem", "hideItem");
    } else {
        // deal with the indeterminate state if needed
    }
}
  
// add or remove classes to show or hide our content
function hideOrShowItems(itemType, classToRemove, classToAdd) {
    for (var i = 0; i < itemsToFilter.length; i++) {
        var currentItem = itemsToFilter[i];
          
        if (currentItem.getAttribute("data-type") == itemType) {
            removeClass(currentItem, classToRemove);
            addClass(currentItem, classToAdd);
        }
    }
}
  
//
// Helper functions for adding and removing class values
//
function addClass(element, classToAdd) {
    var currentClassValue = element.className;
        
    if (currentClassValue.indexOf(classToAdd) == -1) {
        if ((currentClassValue == null) || (currentClassValue === "")) {
            element.className = classToAdd;
        } else {
            element.className += " " + classToAdd;
        }
    }
}
        
function removeClass(element, classToRemove) {
    var currentClassValue = element.className;
  
    if (currentClassValue == classToRemove) {
        element.className = "";
        return;
    }
  
    var classValues = currentClassValue.split(" ");
    var filteredList = [];
  
    for (var i = 0 ; i < classValues.length; i++) {
        if (classToRemove != classValues[i]) {
            filteredList.push(classValues[i]);
        }
    }
  
    element.className = filteredList.join(" ");
}
</script>

我发现在css中你可以做到以下几点:

#itemsToFilter li[data-type*=Food] {background-color: green;}
#itemsToFilter li[data-type*=Musician] {background-color: yellow;}

(星号会导致识别一个或多个数据类型属性)

没有问题,所以我对javascript-part:

感兴趣

其中
1)如果同时选中了两个复选框,则显示食物和音乐家;
2)如果检查食物并且音乐家未经检查,该元素仍然可见,因为它包含食物,它还包含音乐家的信息;
3)如果检查音乐家且食物未经检查,它仍然可见,因为它包含音乐家,它还包含食物; 4)如果食物和音乐家都未经检查,则li项目会消失。

我想要这个,而不必创建一个名为'Food Musician'的新复选框。可以通过添加

来完成
#itemsToFilter li[data-type*='Food Musician'] {background:pink;}

所以只能使用“食物”和“音乐家”复选框。

http://test.kompagniekistemaker.nl

上查看或关注此示例

我从Kirupa读到这篇文章后提出了我的问题:
https://www.kirupa.com/html5/filtering_items_in_a_list.htm

我也找到了这个例子,这就是我想要的东西:
Filter by multiple data attribute elements

赢得答案会得到一块巧克力 非常感谢提前!

2 个答案:

答案 0 :(得分:0)

尝试像这样修改if语句:

if (currentItem.getAttribute("data-type").indexOf(itemType) !== -1)

我很确定你知道它在做什么。它会在您的数据属性中搜索子字符串。如果找到,则indexOf()返回子字符串的第一个字符的位置;如果未找到子字符串,则返回-1。它能解决你的问题吗?

答案 1 :(得分:0)

一位朋友使用这段javascript解决了这个问题。每件作品都单独解释。

简而言之: 如果我在ul中创建一个复选框,其中一个'.filterSection'类与另一个包含一个类为'.itemsToFilter'的li元素的ul相对应,则会发生以下情况:

  1. 如果未选中任何复选框,则会显示该特定ul的所有内容
  2. 如果选中了一个或多个复选框,则会显示相应复选框的内容
  3. 如果你只想在你的ul中使用一个li元素,你可以使用display:none;添加一个'invisible'额外的li元素。 css中的属性,让它在html中被'checked =“true”'。这样,在列表中看起来总是有一个看似元素的已检查元素,导致单个可见li元素的行为与两个或多个li元素列表中的li元素相同。如果你不这样做,你的一个li元素将始终可见,因为当它未被选中时,它将显示所有内容(上面的规则1)。

    var section; var items;

    的init();

    //初始化功能 function init(){     //获取复选框部分和要过滤的项目     sections = query('。filterSection');     items = query('。itemsToFilter li');

    // Create a section for every group of checkboxes
    for (var i = 0; i < sections.length; i++) {
        sections[i] = query('input', sections[i]);
    
        // Loop over the checkboxes in a section
        for (var j = 0; j < sections[i].length; j++) {
    
            // Add event listener (filter on change)
            sections[i][j].addEventListener('change', filter);
        }
    }
    

    }

    //单击或取消选中复选框时调用的函数 function filter(){     //获取所选复选框     var selection = getSelection();

    // Loop over all items
    for (var i = 0; i < items.length; i++) {
        // Initially, every item will be shown
        var show = true;
    
        // Get the tags associated with the item
        var tags = items[i].dataset.type.split(',');
    
        // Loop over each tag section
        for (var j = 0; j < selection.length; j++) {
    
            // If the section has no checked boxes, it will be ignored
            if (selection[j].length == 0) continue;
    
            // Hide the item, unless we tell it to be shown later
            var allow = false;
    
            // Loop over the associated tags
            for (var k = 0; k < tags.length; k++) {
    
                // If the tag is also one that has been selected, allow the item to be shown
                if (selection[j].indexOf(tags[k]) > -1) {
                    allow = true;
                }
            }
    
            // If one of the tags was disallowed, hide the item. Do not keep checking as this is unnecessary
            if (!allow) {
                show = false;
                break;
            }
        }
    
        // Add the appropriate class
        if (!show) items[i].classList.add('hideItem');
        else items[i].classList.remove('hideItem');
    }
    

    }

    //获取所选复选框的功能 function getSelection(){     //在这里,我们将跟踪复选框     var selection = [];

    // Loop over each section
    for (var i = 0; i < sections.length; i++) {
        // Initialize an empty selection list per section
        selection[i] = [];
    
        // Loop over the checkboxes in this section
        for (var j = 0; j < sections[i].length; j++) {
    
            // Get the checkbox
            var checkbox = sections[i][j];
    
            // If the checkbox is checked, add it to the selection list
            if (checkbox.checked) selection[i].push(checkbox.value);
        }
    }
    
    return selection;
    

    }

    //用于查询DOM和返回元素的实用程序函数 函数查询(q,容器){     //如果没有给出容器,则恢复为整个文档     container = container ||文件;

    // Query the container
    var results = container.querySelectorAll(q);
    
    // Return the results as an array
    return Array.prototype.slice.call(results);
    

    }