【问题标题】:Show data only when it matches a search仅在匹配搜索时显示数据
【发布时间】:2021-12-29 16:46:54
【问题描述】:

我有一个按预期缩小数据范围的过滤器搜索。我想实现默认隐藏所有数据的功能,并且仅在匹配搜索时显示结果。目前,如果没有键入任何内容,则会显示所有内容。一旦添加了所有数据,列表将非常长,因此请求。非常感谢。

$(document).ready(function(){
    $("#search-box").on("keyup", function() {
      var value = $(this).val().toLowerCase();
      var filter = $('#search-filter').val().toLowerCase();
      if(filter == "listitem") {
        $(".listitem").filter(function() {
          $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
        });
      } else {
        $(".td-"+filter).filter(function() {
          $(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1)
        });
      }
    });
    $('#search-filter').on("change",function(){
      var value = $("#search-box").val().toLowerCase();
      var filter = $(this).val().toLowerCase();
      if(filter == "listitem") {
        $(".listitem").filter(function() {
          $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
        });
      } else {
        $(".td-"+filter).filter(function() {
          $(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1)
        });
      }
    });
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div class="input-group">
    <div class="input-group-append">
      <select id="search-filter" name="search-filter">
        <!--<option value="listitem">All</option>-->
        <option value="" disabled selected>Search by</option>
        <option value="name">Name</option>
        <option value="surname">Surname</option>
      </select>
    </div>
    <input id="search-box" type="text" name="search" placeholder="Type here..." required="required"/>
  </div>
  <table>
    <thead> 
      <tr>
        <th>Name</th>
        <th>Surname</th>
      </tr>
    </thead>
    <tbody>
      <tr class="listitem">
        <td class="td-name">Jane</td>
        <td class="td-surname">Doe</td>
      </tr>
      <tr class="listitem">
        <td class="td-name">Dela</td>
        <td class="td-surname">Cruz</td>
      </tr>
    </tbody>
  </table>
</div>

【问题讨论】:

  • 你为什么使用.filter()?您应该使用.each() 循环遍历集合中的所有元素。
  • 如果搜索框为空,只需隐藏所有项目并跳过根据搜索字段切换的循环。
  • @Barmar 这看起来怎么样?我不知道如何编码。谢谢

标签: html jquery


【解决方案1】:

首先隐藏一切。然后使用if语句测试搜索值是否不为空,并显示匹配的元素。

我还将过滤代码提取到一个命名函数中,因此我们不必在两个事件侦听器中重复它。

.filter() 不应该用于对每个元素执行操作,应该使用.each() 来完成。但是在这种情况下,您可以使用它返回一个新集合,该集合只是匹配的元素,然后您可以将它们一起显示。

function filter_items(value, filter) {
  $(".listitem, thead").hide();
  if (value != '') {
    if (filter == "listitem") {
      $(".listitem").filter(function() {
        return $(this).text().toLowerCase().includes(value)
      }).show();
    } else {
      $(".td-" + filter).filter(function() {
        return $(this).text().toLowerCase().includes(value)
      }).closest(".listitem").show();
    }
    if ($(".listitem:visible").length > 0) {
      $("thead").show();
    }
  }
}

$(document).ready(function() {
  $("#search-box").on("keyup", function() {
    var value = $(this).val().toLowerCase();
    var filter = $('#search-filter').val().toLowerCase();
    filter_items(value, filter);
  });
  $('#search-filter').on("change", function() {
    var value = $("#search-box").val().toLowerCase();
    var filter = $(this).val().toLowerCase();
    filter_items(value, filter);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div class="input-group">
    <div class="input-group-append">
      <select id="search-filter" name="search-filter">
        <!--<option value="listitem">All</option>-->
        <option value="" disabled selected>Search by</option>
        <option value="name">Name</option>
        <option value="surname">Surname</option>
      </select>
    </div>
    <input id="search-box" type="text" name="search" placeholder="Type here..." required="required" />
  </div>
  <table>
    <thead>
      <tr>
        <th>Name</th>
        <th>Surname</th>
      </tr>
    </thead>
    <tbody>
      <tr class="listitem">
        <td class="td-name">Jane</td>
        <td class="td-surname">Doe</td>
      </tr>
      <tr class="listitem">
        <td class="td-name">Dela</td>
        <td class="td-surname">Cruz</td>
      </tr>
    </tbody>
  </table>
</div>

【讨论】:

  • 如果没有结果,是否也可以让 &lt;th&gt; 标题消失?虽然可能很困难
  • 我已经设法使用类显示/隐藏带有结果的&lt;th&gt;,但我做错了,因为它也在搜索时考虑了标题的文本。在搜索中不应考虑它们。请问有什么帮助吗?非常感谢
  • 隐藏所有列表项时隐藏thead。然后过滤后,做if ($(".listitem:visible").length &gt; 0) { $("thead").show; }
  • “过滤后”在哪里?对不起,我不擅长这个。谢谢
  • if (value != '') 中的代码进行过滤。所以把它放在if 块的末尾。
猜你喜欢
  • 2015-06-13
  • 1970-01-01
  • 1970-01-01
  • 2017-05-10
  • 1970-01-01
  • 1970-01-01
  • 2020-05-15
  • 2016-10-16
  • 1970-01-01
相关资源
最近更新 更多