【问题标题】:Filter multiple html tables with JS用JS过滤多个html表格
【发布时间】:2017-08-03 16:23:59
【问题描述】:

我正在处理一个包含多个 Html 大型表格的页面。 为了过滤它们,我找到并修改了这个过滤表格每个单元格的脚本:

<script>
function searchtable() {
  var input, filter, table, tr, td, i;
  input = document.getElementById("myInput");
  filter = input.value.toUpperCase();
  table = document.getElementById("myTable");
  tr = table.getElementsByTagName("tr");
  th = table.getElementsByTagName("th");

  for (i = 1; i < tr.length; i++) {
    if (!tr[i].classList.contains('header')) {
      td = tr[i].getElementsByTagName("td"),
      match = false;
      for (j = 0; j < td.length; j++) {
        if (td[j].innerHTML.toUpperCase().indexOf(filter) > -1) {
          match = true;
          break;
        }
      }
      if (!match) {
        tr[i].style.display = "none";
      } else {
        tr[i].style.display = "";
      }
    }
  }
}
</script>

这里的问题是代码只在页面的第一个表格中有效,而在其他表格中无效。 我宁愿不要为每个表重复脚本个性化。 您对如何个性化脚本以在多个表中查找有什么建议吗?

编辑: 你知道有什么不同的脚本做同样的事情吗?

【问题讨论】:

  • 说实话,这就是我们发明模型的原因。如果您将表中包含的数据包含在对象或数组等内部,则可以使用数组方法对数组进行拟合,然后重新渲染表。但就主题而言,您可以对所有内容进行参数化,因此您的函数接受 'myInput' 和 'myTable' ids:function searchTable( tableId ) {},然后是每个表都有正确 id 的事件。
  • @Shilly 我会尝试研究数组方法。不幸的是我现在做不到。我非常感谢您的建议(数组方法的使用和 id 的使用)。您还有什么建议吗?
  • 您是想学习 javascript 还是需要工作代码?我有一个解决方案,但您将无法再识别其中的代码。
  • @Shilly 实际上现在我需要工作代码,但我总是尝试从我自己(主要是我的错误)和我从社区中找到的帮助中学习。每一个帮助总是被感激的!

标签: javascript html html-table filtering


【解决方案1】:

我已尝试解释我已更改的大部分内容。最后,代码本身有点短,但有点复杂。如果我做了不正确的假设,请告诉我。 (例如,我假设 'header' 类仅附加到包含 <th> elements) &lt;thead&gt; 内的 &lt;tr&gt; 元素

var searchTable = function searchTable(table, input) {
    // Since we bound the input, we can use input.value to get the current words typed into the input.
    var filter = input.value,
      // A table has both a thead and a tbody.
      // By only selecting the tr nodes from the body, we can remove the entire 'check if this is a header tr logic of `tr.classList.contains('header')`
      // Keep in mind that querySelector returns a nodeList, so if we want to use array methods, we need to covnert it into a real array.
      // The original code uses getElementsByTagName, which return a LIVE nodeList, watch out for this difference.
      rows = Array.prototype.slice.call(table.querySelectorAll('tbody tr'));
    rows.forEach(function(row) {
      // Since we don't care in which cell the fitler is contained, we can just check the innerHTML of the entire row.
      // This will only fail if the filter typed into the inputs is either 'tr' or 'td'
      var hide = (row.innerHTML.indexOf(filter) === -1);
      // The alternative is actually checking each cell, but this makes the script take longer:
      // var hide = !Array.prototype.slice.call( row.querySelectorAll('td') ).some(function( cell ) {
      //     return (cell.innerHTML.indexOf( filter ) !== -1);
      // });
      if (hide) row.classList.add('gone');
      else if (row.classList.contains('gone')) row.classList.remove('gone');
    });
  },
  // helper function that we can use to bind the searchTable function to any table and input we want
  // We add an onchange event listener, passing it a bound version of searchTable.
  bindSearch = function bindSearch(tableID, inputID) {
    var input = document.querySelector(inputID),
      table = document.querySelector(tableID);
    if (table && input) input.addEventListener('change', searchTable.bind(null, table, input));
    else alert('Table or input does not exist.');
  };
// We can add as many individual inputs / tables as we want by just calling bindSearch with the right ids.
bindSearch('#table1', '#input1');
bindSearch('#table2', '#input2');
.gone {
  display: none;
}
<input type="text" id="input1">
<table id="table1">
  <thead>
    <tr>
      <th>header 1</th>
      <th>header 2</th>
      <th>header 3</th>
      <th>header 4</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Cell 1-1: foo</td>
      <td>Cell 1-2: bar</td>
      <td>Cell 1-3: baz</td>
      <td>Cell 1-4: foo</td>
    </tr>
    <tr>
      <td>Cell 2-1: apples</td>
      <td>Cell 2-2: cherries</td>
      <td>Cell 2-3: bananas</td>
      <td>Cell 2-4: foo</td>
    </tr>
    <tr>
      <td>Cell 3-1: cars</td>
      <td>Cell 3-2: bar</td>
      <td>Cell 3-3: planes</td>
      <td>Cell 3-4: apples</td>
    </tr>
    <tr>
      <td>Cell 4-1: baz</td>
      <td>Cell 4-2: 2017</td>
      <td>Cell 4-3: 2010</td>
      <td>Cell 4-4: 2001</td>
    </tr>
    <tr>
      <td>Cell 5-1: cars</td>
      <td>Cell 5-2: 2017</td>
      <td>Cell 5-3: foo</td>
      <td>Cell 5-4: undefined</td>
    </tr>
  </tbody>
</table>
<br>
<br>
<input type="text" id="input2">
<table id="table2">
  <thead>
    <tr>
      <th>header 1</th>
      <th>header 2</th>
      <th>header 3</th>
      <th>header 4</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Cell 1-1: foo</td>
      <td>Cell 1-2: bar</td>
      <td>Cell 1-3: baz</td>
      <td>Cell 1-4: foo</td>
    </tr>
    <tr>
      <td>Cell 2-1: apples</td>
      <td>Cell 2-2: cherries</td>
      <td>Cell 2-3: bananas</td>
      <td>Cell 2-4: foo</td>
    </tr>
    <tr>
      <td>Cell 3-1: cars</td>
      <td>Cell 3-2: bar</td>
      <td>Cell 3-3: planes</td>
      <td>Cell 3-4: apples</td>
    </tr>
    <tr>
      <td>Cell 4-1: baz</td>
      <td>Cell 4-2: 2017</td>
      <td>Cell 4-3: 2010</td>
      <td>Cell 4-4: 2001</td>
    </tr>
    <tr>
      <td>Cell 5-1: cars</td>
      <td>Cell 5-2: 2017</td>
      <td>Cell 5-3: foo</td>
      <td>Cell 5-4: undefined</td>
    </tr>
  </tbody>
</table>

【讨论】:

  • 非常感谢@Shilly!现在我明白你为什么写这将是一个巨大的变化,但你的解决方案实际上对我有用!我会使用你的脚本,但我也会尝试找出我发布的代码不起作用的原因!再次感谢您的帮助,并感谢所有发布建议以帮助我的人!
  • 我建议将“.toLowerCase()”添加到“var filter = input.value”,这样你就可以得到一个不区分大小写的过滤器。
  • 肯定。只是展示原理。您可以以任何适合您应用的方式更新过滤器逻辑。或者甚至将其作为您绑定的参数,以便您也可以使用不同类型的过滤器。 :) 明确检查每个单元格的代码也在 cmets 中。
【解决方案2】:

html:

    <table id="table2">
      <thead></thead>
      <tbody>
        <tr></tr> <tr></tr>
      </tbody>
  </table>   

js:

var table1 = document.getElementById("table1");
     var table2 = document.getElementById("table2");

 searchtable(table1);
 searchtable(table2);

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

      tr = table.getElementsByTagName("tr");
      th = table.getElementsByTagName("th");

      for (i = 1; i < tr.length; i++) {
        if (!tr[i].classList.contains('header')) {
          td = tr[i].getElementsByTagName("td"),
          match = false;
          for (j = 0; j < td.length; j++) {
            if (td[j].innerHTML.toUpperCase().indexOf(filter) > -1) {
              match = true;
              break;
            }
          }
          if (!match) {
            tr[i].style.display = "none";
          } else {
            tr[i].style.display = "";
          }
        }
      }
    }

【讨论】:

  • 这仅适用于所有表应同时过滤的情况,而不适用于每个表应能够单独过滤的情况。但是,是的,在 OP 中并不是 100% 清楚。
  • 你可以选择你的表并将其元素传递给函数
  • 您好,谢谢@BougarfaouiElhoucine,我已经尝试让您的脚本版本起作用,但它没有工作......当我试图过滤它时,它什么也没做......我已在每个表中添加了 ID,但没有成功...仍然感谢您的帮助!
  • @BougarfaouiElhoucine 你认为我还应该添加多个输入而不是单个 MyInput 吗?另外,我的输入形式是:
  • `onkeyup="searchtable()"' 不要使用它,您必须将表格元素作为参数传递
猜你喜欢
  • 2017-05-19
  • 1970-01-01
  • 2014-06-27
  • 1970-01-01
  • 1970-01-01
  • 2019-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多