首页 > 解决方案 > 通过 5 个单独的输入块过滤表

问题描述

我一直在尝试用 javascript 编写一个函数,这样我就可以通过 5 个单独的输入框过滤一个表格,一个用于表格的每个参数。W3schools 有一个解决方案,但它只覆盖了一列;我在这里找到了一堆关于“如何通过多个输入框过滤表格”的其他答案,但它们要么不起作用,要么另一个框会覆盖过滤过程,例如,如果我写了“x ” 在框一和框二中的“y”,表格必须包含td列中包含的每个“y”,即使是没有“x”的那些。有什么解决办法吗?(第六栏没什么可补充的,就是这样)

html

<input type="text" id="inid" onkeyup="search()" placeholder="ID">
<input type="text" id="inplat" onkeyup="search()" placeholder="Platform">
<input type="text" id="inloc" onkeyup="search()" placeholder="Location">
<input type="text" id="incount" onkeyup="search()" placeholder="T-Count">
<input type="text" id="inauthor" onkeyup="search()" placeholder="Author">

<div id="table_div">
        <table id="myTable">
            <tr class="header">
                <th>ID</th>
                <th>Platform</th>
                <th>Location</th>
                <th>T-Count</th>
                <th>Author</th>
                <th></th>
            </tr>
            <tr>
                <td>2-12-8374857-232</td>
                <td>PC</td>
                <td>Chongqing</td>
                <td>4</td>
                <td>Urben</td>
                <td>More Info</td>
            </tr>
            <tr>
                <td>3-23-3939473-324</td>
                <td>PS</td>
                <td>Dubai</td>
                <td>3</td>
                <td>Hichkas</td>
                <td>More Info</td>
            </tr>
            <tr>
                <td>3-43-3245235-432</td>
                <td>Xbox</td>
                <td>Paris</td>
                <td>2</td>
                <td>TheChicken</td>
                <td>More Info</td>
            </tr>
            <tr>
                <td>1-24-2594549-124</td>
                <td>Stadia</td>
                <td>Berlin</td>
                <td>5</td>
                <td>Scat1620</td>
                <td>More Info</td>
            </tr>
        </table>
    </div>

标签: javascripthtmlcssfilterhtml-table

解决方案


这是我给你的建议

它使用了一些增强的 JS 技巧

// do everything inside a block to not conflict with global namespace
{
  "use strict";
  
  // define some magic values
  const formSelector = '[data-filter-table-target]'
  const columnSelector = '[data-column]'
  const rowSelector = ':scope > tbody > tr';
  const filteredClassName = 'filtered';
  
  // define small Helper function that do exactly one thing
  
  // returns an HTML element that matches the selector from the data-filter-table-target argument
  const getTarget = form => document.querySelector(form.dataset.filterTableTarget)
  // get all the first class rows (i.e. not nested inside a table) from this table's body
  const getRows = table => Array.from(table.querySelectorAll(rowSelector))
  // get the values from this form's inputs, which have a data-column argument
  const getFilterValues = form =>  Array.from(form.querySelectorAll(columnSelector)).map(inp => ({'column': inp.dataset.column, 'value': inp.value}));

  // check, if this cells text contains the value
  const checkCellValue = (cell, value) => (new RegExp(value, 'i')).test(cell.textContent)
  
  // get a table row's cell which data-column argument value matches the value argument
  const getCell = (row, value) => row.querySelector(`[data-column="${value.column}"`)
  
  // filter a row, if it does not match the value
  const filterRow = (row, values) => {
    const filtered = values.reduce((carry, value) => {
      if (! checkCellValue(getCell(row, value), value.value)) { return true;}
      return carry
    }, false)
    
    if (filtered) {
      row.classList.add(filteredClassName)
    } else {
      row.classList.remove(filteredClassName)
    }
  }
  
  // check all rows, if they should be filtered
  const filterRows = (rows, values) => {
    rows.forEach(row => filterRow(row, values))
  }
  
  // bahaviour on input
  const onInput = e => {
    // check, if input is called from inside a form which serves as filter
    const form = e.target.closest(formSelector)
    // otherwise return
    if (!form) {return;}
    
    const target = getTarget(form)
    const rows = getRows(target)
    const values = getFilterValues(form)
    
    filterRows(rows, values)
    
  }
  
  // check for the global input event
  document.addEventListener('input', onInput)
}
.filtered {
  display: none;
}
<!-- the data-filter-table-target argument points to the table to be filtered -->
<form data-filter-table-target="#myTable">
  <!-- the data-column arguments point to the table cells with the same argument -->
  <input type="text" id="inid"     placeholder="ID"       data-column="ID">
  <input type="text" id="inplat"   placeholder="Platform" data-column="Platform">
  <input type="text" id="inloc"    placeholder="Location" data-column="Location">
  <input type="text" id="incount"  placeholder="T-Count"  data-column="TCount">
  <input type="text" id="inauthor" placeholder="Author"   data-column="Author">
</form>
<div id="table_div">
  <table id="myTable">
    <thead>
      <tr>
        <th>ID</th>
        <th>Platform</th>
        <th>Location</th>
        <th>T-Count</th>
        <th>Author</th>
        <th></th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td data-column="ID">2-12-8374857-232</td>
        <td data-column="Platform">PC</td>
        <td data-column="Location">Chongqing</td>
        <td data-column="TCount">4</td>
        <td data-column="Author">Urben</td>
        <td>More Info</td>
      </tr>
      <tr>
        <td data-column="ID">3-23-3939473-324</td>
        <td data-column="Platform">PS</td>
        <td data-column="Location">Dubai</td>
        <td data-column="TCount">3</td>
        <td data-column="Author">Hichkas</td>
        <td>More Info</td>
      </tr>
      <tr>
        <td data-column="ID">3-43-3245235-432</td>
        <td data-column="Platform">Xbox</td>
        <td data-column="Location">Paris</td>
        <td data-column="TCount">2</td>
        <td data-column="Author">TheChicken</td>
        <td>More Info</td>
      </tr>
      <tr>
        <td data-column="ID">1-24-2594549-124</td>
        <td data-column="Platform">Stadia</td>
        <td data-column="Location">Berlin</td>
        <td data-column="TCount">5</td>
        <td data-column="Author">Scat1620</td>
        <td>More Info</td>
      </tr>
    </tbody>
  </table>
</div>


推荐阅读