通过表格行进行实时搜索

34

我想使用jQuery实现表格行的实时搜索,"实时"这个词很关键,因为我希望在同一个网站上的文本输入框中输入关键字,并且希望jQuery自动排序(或删除不匹配搜索查询的行)表格行。

这是我的HTML:

<table>
    <tr><th>Unique ID</th><th>Random ID</th></tr>
    <tr><td>214215</td><td>442</td></tr>
    <tr><td>1252512</td><td>556</td></tr>
    <tr><td>2114</td><td>4666</td></tr>
    <tr><td>3245466</td><td>334</td></tr>
    <tr><td>24111</td><td>54364</td></tr>
</table>

如果我想通过唯一ID进行搜索,那么它应该只显示以特定数字开头的唯一ID的行。例如,如果我在搜索输入框中输入'2',则以下行应保留,因为它们以2开头:

<table>
    <tr><th>Unique ID</th><th>Random ID</th></tr>
    <tr><td>214215</td><td>442</td></tr>
    <tr><td>2114</td><td>4666</td></tr>
    <tr><td>24111</td><td>54364</td></tr>
</table>
如果我输入“24”,那么只有一行应该是可见的,因为它从“24”开始:
<table>
    <tr><th>Unique ID</th><th>Random ID</th></tr>
    <tr><td>24111</td><td>54364</td></tr>
</table>

如果你们能给我一些如何做这个的提示,我将不胜感激。

谢谢。


这就是你要找的:https://jsfiddle.net/julmot/buh9h2r8/ - dude
这里有一个很好的例子 - Muhammad Shahzad
21个回答

67
我不确定这个方法有多有效,但它是可行的:
$("#search").on("keyup", function() {
    var value = $(this).val();

    $("table tr").each(function(index) {
        if (index != 0) {

            $row = $(this);

            var id = $row.find("td:first").text();

            if (id.indexOf(value) != 0) {
                $(this).hide();
            }
            else {
                $(this).show();
            }
        }
    });
});​

示例 - 在表格中实现实时搜索


我添加了一些简单的高亮逻辑,你或者未来的用户可能会觉得很方便。

其中一种添加基本高亮的方法是用 em 标签包围匹配到的文本,并使用 CSS 应用黄色背景于匹配到的文本中,例如:(em{ background-color: yellow }),类似于这样:

// removes highlighting by replacing each em tag within the specified elements with it's content
function removeHighlighting(highlightedElements){
    highlightedElements.each(function(){
        var element = $(this);
        element.replaceWith(element.html());
    })
}

// add highlighting by wrapping the matched text into an em tag, replacing the current elements, html value with it
function addHighlighting(element, textToHighlight){
    var text = element.text();
    var highlightedText = '<em>' + textToHighlight + '</em>';
    var newText = text.replace(textToHighlight, highlightedText);
    
    element.html(newText);
}

$("#search").on("keyup", function() {
    var value = $(this).val();
    
    // remove all highlighted text passing all em tags
    removeHighlighting($("table tr em"));

    $("table tr").each(function(index) {
        if (index !== 0) {
            $row = $(this);
            
            var $tdElement = $row.find("td:first");
            var id = $tdElement.text();
            var matchedIndex = id.indexOf(value);
            
            if (matchedIndex != 0) {
                $row.hide();
            }
            else {
                //highlight matching text, passing element and matched text
                addHighlighting($tdElement, value);
                $row.show();
            }
        }
    });
});

演示 - 应用简单的高亮效果



顺便问一下,如果对于“随机ID”搜索也能做到同样的效果吗?在这种情况下,“:first”选择器将无法起作用。 - Sapp
你的意思是输入值是否与任一列匹配? - Nope
是的,我也找到了那些,但是在突出显示元素方面遇到了一些问题... :/ - Sapp
@Sapp:我也有同样的问题。我自己也没能让它工作起来。或许你可以在一个新的问题中询问,附上你在那篇SO帖子和插件中的发现,并展示你无法让它起作用。否则人们会认为它是那篇SO帖子的复制品。 - Nope
2
非常感谢,这是很棒的代码。对我来说运行得很好,除了 "index !== 0" 会让我的第一行 tr 始终出现,无论搜索结果如何(我猜原因是我也有 tbody),我通过将其更改为 "index !== -1" 来修复它。也许已经晚了,但是将您突出显示的文本更改为 "var highlightedText = '<em style='background:yellow'>' + textToHighlight + '</em>';" 将添加黄色背景颜色,如果它对您没有起作用。 - Elnoor
显示剩余4条评论

32

这是一个同时搜索两列的版本。

$("#search").keyup(function () {
    var value = this.value.toLowerCase().trim();

    $("table tr").each(function (index) {
        if (!index) return;
        $(this).find("td").each(function () {
            var id = $(this).text().toLowerCase().trim();
            var not_found = (id.indexOf(value) == -1);
            $(this).closest('tr').toggle(!not_found);
            return not_found;
        });
    });
});

演示:http://jsfiddle.net/rFGWZ/369/


这个非常好用!我已经将它作为实时搜索功能应用于具有4-8列的大型表格中 - 谢谢!对于那些需要仅搜索表格中特定列的人,您可以添加到 .find("td") 并将其变成 .find("td.searchable") - tylerl
我认为这更有用,因为您不仅可以查看一列,而且可以查看整行 :) - Ryan Monreal
在这个答案中,我们可以搜索表中的任何列。我需要这个。谢谢。 - user9437856

17

François Wahl的方法,但更加简短:

$("#search").keyup(function() {
    var value = this.value;

    $("table").find("tr").each(function(index) {
        if (!index) return;
        var id = $(this).find("td").first().text();
        $(this).toggle(id.indexOf(value) !== -1);
    });
});

http://jsfiddle.net/ARTsinn/CgFd9/


1
@François Wahl:耶!忘记了 :first。现在已经添加了! - yckart
1
使用三元运算符? ...:来执行函数并不是它的本意。该运算符是用于赋值语句的,其中每个表达式都是一个没有副作用的简单语句。调用函数是一种副作用。打开您的fiddle并单击“JSLint”按钮以验证代码,您还将看到“第7行第69个字符处的问题:期望出现分配或函数调用,而不是表达式。”有关更多详细信息,请参见文档http://msdn.microsoft.com/en-us/library/be21c7hw(v=vs.94).aspx 。例如,像C#这样的语言将不允许您编译这个。 - Nope
1
@FrançoisWahl:哇,我不知道这个,谢谢……真的很有帮助!但是,顺便问一下,“副作用”是什么?我认为每个浏览器都能理解条件运算符(?),对吗? - yckart
2
副作用即改变状态的一切事物。当使用三元运算符分配值时,所分配的值应该是简单语句。如果进行方法调用,则问题在于您不知道该方法会执行什么操作或调用哪些其他方法。例如,您调用$(this).hide。那个方法调用具有副作用,因为它更改了指定元素的状态,这不是使用分配调用时想要发生的事情。这篇文章在这里很好地解释了它:http://programmers.stackexchange.com/questions/40297/what-is-a-side-effect。 - Nope
1
恭喜您使用jQuery的函数而不是CSS选择器,避免了使用Sizzle。这个版本在小规模上也快得多。(Paul Irish) - Michael J. Calkins
显示剩余2条评论

6
这是一个纯JavaScript版本,支持对所有列进行实时搜索
function search_table(){
  // Declare variables 
  var input, filter, table, tr, td, i;
  input = document.getElementById("search_field_input");
  filter = input.value.toUpperCase();
  table = document.getElementById("table_id");
  tr = table.getElementsByTagName("tr");

  // Loop through all table rows, and hide those who don't match the search query
  for (i = 0; i < tr.length; i++) {
    td = tr[i].getElementsByTagName("td") ; 
    for(j=0 ; j<td.length ; j++)
    {
      let tdata = td[j] ;
      if (tdata) {
        if (tdata.innerHTML.toUpperCase().indexOf(filter) > -1) {
          tr[i].style.display = "";
          break ; 
        } else {
          tr[i].style.display = "none";
        }
      } 
    }
  }
}

4

虽然这个问题已经有一段时间了,但我找到了更快的解决方法。举个例子:我有大约10k条数据需要快速搜索。

下面是我的解决方案:

$('input[name="search"]').on('keyup', function() {

        var input, filter, tr, td, i;

        input  = $(this);
        filter = input.val().toUpperCase();
        tr     = $("table tr");

        for (i = 0; i < tr.length; i++) {
            td = tr[i].getElementsByTagName("td")[0]; // <-- change number if you want other column to search
            if (td) {
                if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
                    tr[i].style.display = "";
                } else {
                    tr[i].style.display = "none";
                }
            }
        }
    })

希望能对某些人有所帮助。

4
我使用了yckart的答案,并进行了以下修改:
  • 增加了空格以提高可读性
  • 搜索时不区分大小写
  • 修复了比较中存在的错误,通过添加.trim()来解决

(如果您将脚本放在页面底部的jQuery包含下方,则不需要使用document ready)

jQuery:

 <script>
    $(".card-table-search").keyup(function() {
        var value = this.value.toLowerCase().trim();

        $(".card-table").find("tr").each(function(index) {
            var id = $(this).find("td").first().text().toLowerCase().trim();
            $(this).toggle(id.indexOf(value) !== -1);
        });
    });
 </script>

如果您想扩展此功能,可以使其迭代每个“td”并进行此比较。


2
在我的情况下,这个是最好的选择。 这里有更多相关信息。
<script>
$(document).ready(function(){
  $("#myInput").on("keyup", function() {
    var value = $(this).val().toLowerCase();
    $("#myTable tr").filter(function() {
      $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
    });
  });
});
</script>

2
以下是您可以使用的JS函数,根据指定的列过滤行,请查看searchColumn数组。它来自于w3school并稍作修改,以在给定的列上搜索和过滤。
HTML结构:
<input style="float: right" type="text" id="myInput" onkeyup="myFunction()" placeholder="Search" title="Type in a name">

     <table id ="myTable">
       <thead class="head">
        <tr>
        <th>COL 1</th>
        <th>CoL 2</th>
        <th>COL 3</th>
        <th>COL 4</th>
        <th>COL 5</th>
        <th>COL 6</th>      
        </tr>
    </thead>    
  <tbody>

    <tr>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
     </tr>

    </tbody>
</tbody>

  function myFunction() {
    var input, filter, table, tr, td, i;
    input = document.getElementById("myInput");
    filter = input.value.toUpperCase();
    table = document.getElementById("myTable");
    tr = table.getElementsByTagName("tr");

     var searchColumn=[0,1,3,4]

    for (i = 0; i < tr.length; i++) {

      if($(tr[i]).parent().attr('class')=='head')
        {
            continue;
         }

    var found = false;
      for(var k=0;k<searchColumn.length;k++){

        td = tr[i].getElementsByTagName("td")[searchColumn[k]];

        if (td) {
          if (td.innerHTML.toUpperCase().indexOf(filter) > -1 ) {
            found=true;    
          } 
        }
    }
    if(found==true)  {
        tr[i].style.display = "";
    } 
    else{
        tr[i].style.display = "none";
    }
}
}

1
我使用之前的答案并将它们结合起来创建了以下内容:

通过隐藏行和高亮显示,搜索任何列

用于高亮显示找到的文本的CSS:

em {
   background-color: yellow
}

Js:

function removeHighlighting(highlightedElements) {
   highlightedElements.each(function() {
      var element = $(this);
      element.replaceWith(element.html());
   })
}

function addHighlighting(element, textToHighlight) {
   var text = element.text();
   var highlightedText = '<em>' + textToHighlight + '</em>';
   var newText = text.replace(textToHighlight, highlightedText);

   element.html(newText);
}

$("#search").keyup(function() {
   var value = this.value.toLowerCase().trim();

   removeHighlighting($("table tr em"));

   $("table tr").each(function(index) {
      if (!index) return;
      $(this).find("td").each(function() {
         var id = $(this).text().toLowerCase().trim();
         var matchedIndex = id.indexOf(value);
         if (matchedIndex === 0) {
            addHighlighting($(this), value);
         }
         var not_found = (matchedIndex == -1);
         $(this).closest('tr').toggle(!not_found);
         return not_found;
      });
   });
});

演示 这里


1

使用yckart的回答,我成功搜索了整个表格——所有的td。

$("#search").keyup(function() {
    var value = this.value;

    $("table").find("tr").each(function(index) {
        if (index === 0) return;

        var if_td_has = false; //boolean value to track if td had the entered key
        $(this).find('td').each(function () {
            if_td_has = if_td_has || $(this).text().indexOf(value) !== -1; //Check if td's text matches key and then use OR to check it for all td's
        });

        $(this).toggle(if_td_has);

    });
});

嗨,这对我很有效..但是如果我想让它不区分大小写怎么办?也就是说,如果我输入“M”或“m”,它会搜索所有的“m”,而不考虑大小写。谢谢! - catandmouse
你是一颗星 :) - Sohair Ahmad
1
很高兴,它帮助了 @SohairAhmad :) - Elnoor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接