jQuery-选择多个复选框以过滤结果

时间:2018-12-25 15:56:48

标签: jquery filter filtering

我正在尝试通过选择多个过滤器来过滤用户。

问题是,我正在使用第三方软件,该软件在多个表中显示我的用户列表。因此,每个用户确实具有唯一的ID,但每个用户也位于多个表中,因此我试图通过它们进行过滤。

因此,例如,如果选中颜色蓝色和项目,则它应仅显示同时具有这两个类的用户。

我正尝试使用 $(this).val()来获取复选框值的名称,并在每个用户中将其作为类进行搜索,因此,如果这两个类(或更多)与每个用户匹配,则应在 showUsers 结果栏中显示他们。

我有安装示例,但尝试失败: JSFiddle

HTML

<!-- FILTERS -->

<h3>Filter items</h3>
<div class="filter-list-one">
  <input type="checkbox" value="Wood">Wood<br>
  <input type="checkbox" value="Bucket">Bucket<br>
  <input type="checkbox" value="Hammer">Hammer<br>
</div>

<h3>Filter colors</h3>
<div class="filter-list-two">
  <input type="checkbox" value="Red">Red<br>
  <input type="checkbox" value="Purple">Purple<br>
  <input type="checkbox" value="Blue">Blue<br>
</div>

<!-- FILTERS END -->

<!-- SEARCHING THROUGH -->

<h3>Results</h3>
<div class="objects">
  <p id="user1" class="user">
    <span>wood</span>
    <span class="bucket">bucket</span>
    <span>hammer</span>
  </p>
  <p id="user2" class="user">
    <span>wood</span>
    <span class="bucket">bucket</span>
    <span class="bucket">hammer</span>
  </p>
  <p id="user3" class="user">
    <span class="bucket"n>wood</span>
    <span class="bucket">bucket</span>
    <span>hammer</span>
  </p>
</div>

<div class="colors">
  <p id="user1">
    <span>red</span>
    <span class="purple">purple</span>
    <span>blue</span>
  </p>
  <p id="user2">
    <span class="purple">red</span>
    <span>purple</span>
    <span>blue</span>
  </p>
  <p id="user3">
    <span>red</span>
    <span class="purple">purple</span>
    <span class="purple">blue</span>
  </p>
</div>

<div class="showUsers">
  <div id="user1" class="filtered">I'm here and I have those things</div>
  <div id="user2" class="filtered">I'm here and I have those things</div>
  <div id="user3" class="filtered">I'm here and I have those things</div>
</div>

<!-- SEARCHING THROUGH NED -->

CSS

div {
  margin-bottom: 20px;
}

h3 {
  margin: 5px 0;
}

p {
  margin: 0 5px;
}

.colors p,
.user,
.filtered {
  display: none;
}

jQuery

$(".filter-list-one :checkbox, .filter-list-two :checkbox").change(function() {

  if ( ($(".items" + $(this).val())[0]) && ($(".colors" + $(this).val())[0]) ) {

    var showUser = $(this).closest(".user").attr("id");
    $(".showUsers").find("#" + horaInicial).css("display, block");

}

});

2 个答案:

答案 0 :(得分:1)

我想我得到了您在这里尝试做的事情...

但是您错过了脚本必须执行的许多方面,以便根据您希望使用的数据(页面中的元素)“过滤”某些结果。

首先,id 必须唯一。您不能多次使用id="user1。因此,我将其更改为data-属性。

然后,在每个更改事件中,$(this).val()是仅的已更改元素的值。您必须存储以前检查过的内容...,并确保已检查过!当用户取消选中change事件时,可能会触发该事件!

因此,这里有一个显示逻辑步骤的示例...可能需要较短的代码才能达到相同的结果,但是由于您的标记有点混乱,因此我没有尝试对其进行完美优化。

它仍然是越野车...但是我认为这是一个很好的起点。祝你好运!

console.clear();
var checked = [];


$(".filter-list-one :checkbox, .filter-list-two :checkbox").change(function() {

  $(".filtered").hide();

  var possible = [];
  var confirmed = [];

  if($(this).is(":checked")){

    checked.push($(this).val());
    console.log(checked);

    checked.forEach(function(value,index){
      var target = checked[index].toLowerCase();

      $(".objects .user").each(function(){
        if( $(this).find("."+target).length>0 ){
          possible.push($(this).data("user"));
        }
      });

      $(".colors .user").each(function(){
        if( $(this).find("."+target).length>0 && $.inArray($(this).data("user"),possible)!=-1 ){
          confirmed.push($(this).data("user"));
        }
      });
    });

    console.log("possible: "+possible);
    console.log("confirmed: "+confirmed)


    confirmed.forEach(function(value,index){
      $(".filtered[data-user='"+value+"']").show();
    });
    
  }else{ // If unchecking...
    console.log("unchecking "+$(this).val());
    
    if($.inArray($(this).val(),checked)!=-1){
      checked.splice($.inArray($(this).val()),1);
      console.log(checked)
    }
      
  }
});
div {
  margin-bottom: 20px;
}

h3 {
  margin: 5px 0;
}

p {
  margin: 0 5px;
}

.colors p,
.user,
.filtered {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- FILTERS -->

<h3>Filter items</h3>
<div class="filter-list-one">
  <input type="checkbox" value="Wood">Wood<br>
  <input type="checkbox" value="Bucket">Bucket<br>
  <input type="checkbox" value="Hammer">Hammer<br>
</div>

<h3>Filter colors</h3>
<div class="filter-list-two">
  <input type="checkbox" value="Red">Red<br>
  <input type="checkbox" value="Purple">Purple<br>
  <input type="checkbox" value="Blue">Blue<br>
</div>

<!-- FILTERS END -->

<!-- SEARCHING THROUGH -->

<h3>Results</h3>
<div class="objects">
  <p data-user="user1" class="user">
    <span class="wood">wood</span>
  </p>
  <p data-user="user2" class="user">
    <span class="bucket">bucket</span>
  </p>
  <p data-user="user3" class="user">
    <span class="hammer">hammer</span>
  </p>
</div>

<div class="colors">
  <p data-user="user1" class="user">
    <span class="red">red</span>
  </p>
  <p data-user="user2" class="user">
    <span class="purple">purple</span>
  </p>
  <p data-user="user3" class="user">
    <span class="blue">blue</span>
  </p>
</div>

<div class="showUsers">
  <div data-user="user1" class="filtered">I'm USER #1 and I have those things</div>
  <div data-user="user2" class="filtered">I'm USER #2 and I have those things</div>
  <div data-user="user3" class="filtered">I'm USER #3 and I have those things</div>
</div>

<!-- SEARCHING THROUGH NED -->

答案 1 :(得分:1)

以下是用户单击任何复选框后运行的一些代码。它会收集检查过的过滤器,然后循环浏览每个用户索引,并确保在将所有过滤器添加到底部的列表之前将所有过滤器匹配。

您不应有多个具有相同id的元素,我已将用户索引移到它自己的参数中,并将过滤器选项包装在具有filter-group属性的div中。这样,我们可以确保用户不仅匹配正确的术语,而且匹配正确的上下文。

此技术将使您可以根据需要添加任意数量的不同过滤器组,而无需更改代码。该代码无法处理过滤器组(即嵌套)中的过滤器组。


演示

// Add change event to all checkboxes
$(document).on('change', '[filter-group] input[type="checkbox"]', function() {

  // Clear users
  $("#showUsers").html("");

  // Prepare array for filter terms
  var filterTerms = [];
  var filterGroup = [];

  // Cycle through each checked checkbox
  $("[filter-group] input[type='checkbox']:checked").each(function() {

    // Push value into filter array
    filterTerms.push($(this).val().toUpperCase());

    // Push filter group into array
    filterGroup.push($(this).closest("[filter-group]").attr("filter-group"));

  });

  // Cycle through each user
  $("*[user]").each(function() {

    // Get user index, number of filters being applied and setup variable for the number of matched terms
    var userIndex = $(this).attr("user");
    var filterCount = filterTerms.length;
    var filtersMatched = 0;

    // Exit early if the user has already been matched
    if ($("#showUsers *[user='" + userIndex +"']").length > 0) {
      return;
    }

    // Cycle through filter array
    for (var i = 0; i < filterCount; i++) {

      // Cycle through each element tagged with user index
       $("[user='" + userIndex + "']").each(function() {
        
        // Get search term
        var textToSearch = $(this).text().toUpperCase();

        // Check if term found
        if (textToSearch.indexOf(filterTerms[i]) > -1) {
          filtersMatched = filtersMatched + 1;
          return;
        }
        
      });

    }


    // If the number of matched terms equals the number of terms
    // Replace with the following line if you want ANY filter to be matched
    // if ( filtersMatched > 0) {
    if ( filtersMatched == filterCount) {
    
      // Append user to list
      $("#showUsers").append("<li user='" + userIndex + "'>User " + userIndex + "</li>");

    }

  });


});
div {
  margin-bottom: 20px;
}

h3 {
  margin: 5px 0;
}

p {
  margin: 0 5px;
}

.colors p,
.user,
.filtered {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- FILTERS -->

<h3>Filter items</h3>
<div class="filter-list filter-list-one" filter-group="object">
  <input type="checkbox" value="Wood">Wood<br>
  <input type="checkbox" value="Bucket">Bucket<br>
  <input type="checkbox" value="Hammer">Hammer<br>
</div>

<h3>Filter colors</h3>
<div class="filter-list filter-list-two" filter-group="color">
  <input type="checkbox" value="Red">Red<br>
  <input type="checkbox" value="Purple">Purple<br>
  <input type="checkbox" value="Blue">Blue<br>
</div>

<!-- FILTERS END -->

<!-- SEARCHING THROUGH -->

<h3>Results</h3>
<div filter-group="objects">
  <p user="1">
    <span>wood</span>
    <span class="bucket">bucket</span>
    <span>hammer</span>
  </p>
  <p user="2">
    <span>wood</span>
    <span class="bucket">bucket</span>
    <span class="bucket">hammer</span>
  </p>
  <p user="3">
    <span class="bucket" n>wood</span>
    <span class="bucket">bucket</span>
    <span>hammer</span>
  </p>
</div>

<div filter-group="colors">
  <p user="1">
    <span>red</span>
    <span>blue</span>
  </p>
  <p user="2">
    <span class="purple">red</span>
    <span>purple</span>
  </p>
  <p user="3">
    <span>red</span>
    <span class="purple">purple</span>
  </p>
</div>

<ul id="showUsers">
</ul>