【问题标题】:jQuery - multiple checkbox select to filter resultsjQuery - 多个复选框选择以过滤结果
【发布时间】:2018-12-26 08:37:36
【问题描述】:

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

问题是,我正在使用第三方软件,它在多个表格中显示我的用户列表。所以每个用户都有唯一的 ID,但每个用户都在几个表中,所以我试图过滤它们。

因此,例如,如果您选中颜色 Blue 和项目 Bucket,它应该只显示同时拥有这两个类的用户。

我正在尝试使用 $(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");

}

});

【问题讨论】:

  • if 语句是什么意思?你对这个($(".items" + $(this).val())[0]) 有什么期待?
  • 我正在尝试获取选中项的值并将其作为颜色和对象容器中的类进行搜索。
  • 但是没有以.items开头的课程?!

标签: jquery filter filtering


【解决方案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>

【讨论】:

  • 一件事,我也可以显示只选中一个过滤器的用户吗?
  • 当然!如果您想显示与至少一个过滤器匹配的任何内容,请将以下行: if ( filtersMatched == filterCount) 更改为 if ( filtersMatched > 0 )
  • 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊好像用OR过滤了,但是应该用AND过滤我的意思是,如果你选择蓝色,它应该显示所有拥有蓝色的用户(在这个例子中,只有 User1),但如果你选择蓝色和木头,它仍然应该只显示 User1,如果你也添加紫色, 将没有用户可以显示(因为没有用户拥有所有三个词)。顺便说一句,我能以某种方式寄给你 20 美元之类的东西吗?这是一个非常棒的脚本,你真的帮了很多忙:)
  • 看起来对我来说它的工作方式完全一样......?也许我误解了……上面的代码有效地使用了 AND 来确保所有过滤器元素都匹配。如果您想使用 OR,那么您可以替换我提到的行(我现在也将其添加到脚本中)。不用担心付款...我从这个网站的社区中受益匪浅。
  • 实际上你是对的,它完全按照它应该的方式工作。非常感谢你!
【解决方案2】:

我想我明白了你在这里尝试做的事情......

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

首先,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 -->

【讨论】:

  • 感谢您的解决方案!我现在才意识到我真的是多么过分......我以为我错过了每个函数和正确的 and or 语句,但这完全是另外一回事......
猜你喜欢
  • 1970-01-01
  • 2021-06-08
  • 2020-04-06
  • 2014-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-12
相关资源
最近更新 更多