【问题标题】:Filtering multiple classes with checkboxes使用复选框过滤多个类
【发布时间】:2019-12-21 23:35:44
【问题描述】:

我创建了一个多复选框过滤器,其中有 2 个过滤器选项:性别和状态

我想要实现的是:

过滤至少具有一种状态类别的元素,但一旦检查了 GENDER,就隐藏不属于该性别的元素

例如,我通过站立和行走进行过滤(这显示所有女性和男性站立和行走),但是一旦我选中 MALE,这必须隐藏所有女性,所以它会显示所有男性站立和行走走路。

function run() {
    $(".item").hide();
    const checked = $(":checked");
    var gender = $("[name='gender']:checked").val();
    var state = $("[name='state']:checked").val();
    
    if (checked.length === 0) {
        return $(".item").show();
    }
    checked.each(function() {
        //$(".item." + this.id).show(); //Works, but it doesn't hide the non checked gender
        return $(this).hasClass(gender) || $(".item." + this.state);
    }).show();
};  
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>
<div id="gender">
  <input type="radio" id="male" name="gender" onclick="run()" /> Male
  <input type="radio" id="female" name="gender" onclick="run()" /> Female
</div>
<div id="state">
  <input type="checkbox" id="walking" name="state" onclick="run()" /> Walking
  <input type="checkbox" id="standing" name="state" onclick="run()" /> Standing
</div>

<br/>
<div class="item male walking" >male walking</div>
<div class="item male standing walking">male standing and walking</div>
<div class="item standing female walking">female standing and walking</div>
<div class="item female walking">female walking</div>

【问题讨论】:

  • 如果你勾选了男性,male+female standing 应该显示吗?
  • 好的,然后看下面的答案
  • 我想如果检查男性和女性,是否应该只显示男性和女性而不是 OR
  • 如果男性和女性都勾选了,是显示男性+女性的项目,还是显示男性或女性的项目?
  • @Mika 然后but as soon as I check MALE, this has to hide all females, so it'll show all male standing and walking. 不会发生

标签: javascript jquery filter


【解决方案1】:

您可以这样做:收集选中的项目,并为每个项目在 DOM 中查询它们的名称并显示它们。

请注意,这是相当低效的,因为您要多次查询 DOM 以获得相同的元素。理想情况下,您应该保存元素集合,并在需要时调用显示/隐藏它们。

另外,请注意,我添加了标签以改善输入元素的用户体验。现在您可以单击标签本身来检查输入。


编辑:如果输入应该是互斥的,那么单选按钮更合适。我已将 UI 更改为使用单选按钮并添加了一个框来重置按钮(不要过滤性别)。我不确定男性+女性应该如何工作。目前,它不包括在任何性别中。

function run() {
  $(".item").hide();
  let opposingGender = '';
  $(":checked").each(function() {
    let selector = '.' + this.value;
    if (this.name === 'gender') {
      opposingGender = ':not(.' + (this.value === 'male' ? 'female' : 'male') +')';
    }
    selector += opposingGender;
    $(selector).show();
  });
};

function unselect() {
  $('[name=gender]').prop('checked', false);
  run();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>
<div id="gender">
  <input type="radio" id="male" value="male" name="gender" onclick="run()" /> <label for="male">Male</label>
  <input type="radio" id="female" value="female" name="gender" onclick="run()" /> <label for="female">Female</label>
  <button onclick="unselect()">Unselect</button>
</div>
<div id="state">
  <input type="checkbox" id="walking" value="walking" name="state" onclick="run()" /> <label for="walking">Walking</label>
  <input type="checkbox" id="standing" value="standing" name="state" onclick="run()" /> <label for="standing">Standing</label>
</div>

<br/>
<div class="item male walking" >male walking</div>
<div class="item male standing walking">male standing and walking</div>
<div class="item standing female walking">female standing and walking</div>
<div class="item female walking">female walking</div>
<div class="item male female standing">male+female standing</div>

【讨论】:

  • 谢谢!但是一旦检查了性别,它应该隐藏另一个性别。因此,如果选中男性,则应隐藏女性。 STATE 不会发生这种情况,他们可以拥有一个或两个类别
【解决方案2】:

逻辑已更新为使用单选按钮而不是选择来显示男性或女性。所有内联点击处理程序已被删除并更新为使用更改处理程序

var genderSelector = "";
var stateSelector = "";

var filter = function() {
  var selector = stateSelector + genderSelector;

  if (selector) {
    $(".item").hide();
    $(stateSelector + genderSelector).show();
    //console.log(stateSelector + genderSelector);
  } else {
    $(".item").show();
  }
};

$("#gender input").change(function() {
  genderSelector = this.value == "male" ? ".male:not(.female)" : ".female:not(.male)";
  filter();
});

$("#state input").change(function() {
  if ($(this).is(":checked")) {
    stateSelector = stateSelector + "." + this.id;
  } else {
    stateSelector = stateSelector.replace("." + this.id, "");
  }
  filter();
});


// this runs on load so the initial view will be pdated
genderSelector = $("#gender :checked").val() == "male" ? ".male:not(.female)" : ".female:not(.male)";
filter();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>
<div id="gender">
  <input type="radio" id="male" value="male" name="gender" checked /> Male
  <input type="radio" id="female" value="female" name="gender" /> Female
</div>
<div id="state">
  <input type="checkbox" id="walking" name="state" /> Walking
  <input type="checkbox" id="standing" name="state" /> Standing
</div>

<br/>
<div class="item male walking">male walking</div>
<div class="item male standing walking">male standing and walking</div>
<div class="item standing female walking">female standing and walking</div>
<div class="item female walking">female walking</div>
<div class="item male female standing">male+female standing</div>

【讨论】:

  • 谢谢,但如果选中站立和行走,它应该显示选中两个类别之一或两者的所有项目。在这种情况下,它应该显示所有项目,因为它们都至少具有这些类别之一
  • @Mika 我认为您需要澄清过滤逻辑,并显示哪些 2 项是 AND 关系,哪些是 OR。我问你是否检查了男性,是否应该显示男性+女性的站立,你说是,但在问题本身中你说如果检查男性而女性不应该显示,这些有冲突吗?
  • @mika 如果它们都是 OR,那么当您检查男性项目时,女性项目也会显示,这与您对 but as soon as I check MALE, this has to hide all females, so it'll show all male standing and walking. 的要求直接冲突 male+female standing 将在男性 OR 女性 OR 站立时显示被检查
  • 你是对的,很抱歉造成误解。所以勾选male的时候,male+female应该隐藏起来。状态为 AND,性别为 OR
  • 我仍然认为您的过滤逻辑有问题,如果单击男性时男性+女性隐藏,那么同样的逻辑将遵循当单击女性时男性应该被隐藏,现在如果男性和女性都被点击?按照前面的逻辑,那么两者都应该被隐藏,但应该显示男性 + 女性项目
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-20
  • 2019-05-05
  • 1970-01-01
  • 2014-05-12
  • 1970-01-01
  • 2014-09-17
  • 2016-10-26
相关资源
最近更新 更多