使用选择下拉列表过滤 html 表列

时间:2021-04-07 15:42:29

标签: javascript html jquery filter html-table

我正在尝试制作一个表格,该表格可以根据其中的值过滤每一列。我希望每个下拉列表仅与列相关联,因此第一个下拉列表仅查看第一列。我发现 javascript 代码可以完美运行,但前提是 中的每个值都是唯一的。我的表格在每一行/列中大部分都是是/否,我认为我找到的代码无法按照我想要的方式工作的原因是这些值不是唯一的。 OK/NO 的第一列有效,但在指定 yes/no 时查看其他列时会出现问题。如果我从 3 个下拉列表中选择 OK, no, yes 它应该只显示第一行,但它也显示第三行。第一行可以,不,是的,第三行可以,不,不。所以问题是在第三行的第三列中它不是,但在从第三个下拉列表中指定是后它仍然出现。有没有办法让下拉菜单只查看特定列?我仍然是 javascript 的初学者,所以我只是希望看看是否有人可以提供帮助,而我仍然在其他来源中查看它。

这里是html

module.exports = function(){
    if(!process.env.MCSS_API_WRAPPER_TOKEN){
        return null;
    }
    axios.get(`http://${process.env.MCSS_API_WRAPPER_HOST}:${process.env.MCSS_API_WRAPPER_PORT}${routes.api.version}`,
    {
        headers: {
            "Authorization": `Bearer ${process.env.MCSS_API_WRAPPER_TOKEN}`
        }
    })
    .then(function(res) {
        if(res.status == 200){
            return res.data
        }else{
            return res
        }
    }).catch(error => {
        return error
    });
}

这是我在网上找到的javascript代码

<select class="filter">
    <option value="">None</option>
    <option value="a">OK</option>
    <option value="b">NO</option>
</select>
<select class="filter">
    <option value="">None</option>
    <option value="1">no</option>
    <option value="2">yes</option>
    
</select>
<select class="filter">
    <option value="">None</option>
    <option value="3">no</option>
    <option value="4">yes</option>
    
</select>
<table>
    <tbody>
    <tr>
      <th>Status</th>
      <th>Cough</th>
      <th>Fever</th>
    </tr>
        <tr>
            <td>OK</td>
            <td>no</td>
            <td>yes</td>
        </tr>
        <tr>
            <td>NO</td>
            <td>yes</td>
            <td>yes</td>
        </tr>
        <tr>
            <td>OK</td>
            <td>no</td>
            <td>no</td>
        </tr>
        <tr>
            <td>NO</td>
            <td>yes</td>
            <td>no</td>
        </tr>
    </tbody>
</table>

这里是原始 javascript 代码的链接 http://jsfiddle.net/lukaszewczak/2dhE5/52/

1 个答案:

答案 0 :(得分:0)

你可以通过引入一些东西来过滤表格数据:

  1. 跟踪过滤器选择的过滤器状态
  2. 用于识别每个过滤器的数据属性
  3. 确保过滤器的值与数据的文本完全匹配

const
  table = document.querySelector('.filter-table'),
  filterState = {};

const dataFromRow = (row, headers) =>
  Object.fromEntries([...row.querySelectorAll('td')]
    .map((td, index) => [headers[index], td.textContent]));

const matchesCriteria = (rowData, filters) =>
  filters.every(([key, value]) => rowData[key] === value);

const refresh = () => {
  const
    headers = [...table.querySelectorAll('thead th')].map(th => th.textContent),
    filters = Object.entries(filterState),
    showAll = filters.length === 0;
  table.querySelectorAll('tbody tr').forEach(row => {
    const show = showAll || matchesCriteria(dataFromRow(row, headers), filters);
    row.classList.toggle('hidden-row', !show);
  });
};

const handleFilterChange = (e) => {
  const
    field = e.target.dataset.field,
    value = e.target.value;
  if (value) { filterState[field] = value; }
  else { delete filterState[field]; }
  refresh();
};

document.querySelectorAll('.filter').forEach(filter =>
  filter.addEventListener('change', handleFilterChange));
.filter-table {
  border-collapse: collapse;
}

.filter-table {
  border: thin solid grey;
}

.filter-table thead {
  border-bottom: thin solid grey;
}

.filter-table th, .filter-table td {
  padding: 0.25em 0.5em;
}

.filter-table th {
  background: #CCC;
}

.filter-table tbody tr:nth-child(even) {
  background: #EEE;
}

.hidden-row {
  display: none;
}
<select class="filter" data-field="Status">
  <option value="">None</option>
  <option value="OK">OK</option>
  <option value="NO">NO</option>
</select>
<select class="filter" data-field="Cough">
  <option value="">None</option>
  <option value="No">No</option>
  <option value="Yes">Yes</option>
</select>
<select class="filter" data-field="Fever">
  <option value="">None</option>
  <option value="No">No</option>
  <option value="Yes">Yes</option>
</select>
<hr />
<table class="filter-table">
  <thead>
    <tr><th>Status</th><th>Cough</th><th>Fever</th></tr>
  </thead>
  <tbody>
    <tr><td>OK</td><td>No</td><td>Yes</td></tr>
    <tr><td>NO</td><td>Yes</td><td>Yes</td></tr>
    <tr><td>OK</td><td>No</td><td>No</td></tr>
    <tr><td>NO</td><td>Yes</td><td>No</td></tr>
  </tbody>
</table>


如果您希望过滤器位于标题中,您可以将 <select> 元素移动到 <th> 内另一个 <tr> 内的 <thead> 中。

const
  table = document.querySelector('.filter-table'),
  filterState = {};

const dataFromRow = (row, headers) =>
  Object.fromEntries([...row.querySelectorAll('td')]
    .map((td, index) => [headers[index], td.textContent]));

const matchesCriteria = (rowData, filters) =>
  filters.every(([key, value]) => rowData[key] === value);

const refresh = () => {
  const
    headers = [...table.querySelectorAll('thead th')].map(th => th.textContent),
    filters = Object.entries(filterState),
    showAll = filters.length === 0;
  table.querySelectorAll('tbody tr').forEach(row => {
    const show = showAll || matchesCriteria(dataFromRow(row, headers), filters);
    row.classList.toggle('hidden-row', !show);
  });
};

const handleFilterChange = (e) => {
  const
    field = e.target.dataset.field,
    value = e.target.value;
  if (value) {
    filterState[field] = value;
  } else {
    delete filterState[field];
  }
  refresh();
};

document.querySelectorAll('.filter').forEach(filter =>
  filter.addEventListener('change', handleFilterChange));
.filter-table {
  border-collapse: collapse;
}

.filter-table {
  border: thin solid grey;
}

.filter-table thead {
  border-bottom: thin solid grey;
}

.filter-table th,
.filter-table td {
  padding: 0.25em 0.5em;
}

.filter-table th {
  background: #CCC;
}

.filter-table tbody tr:nth-child(even) {
  background: #EEE;
}

.hidden-row {
  display: none;
}
<table class="filter-table">
  <thead>
    <tr>
      <th>Status</th>
      <th>Cough</th>
      <th>Fever</th>
    </tr>
    <tr>
      <th>
        <select class="filter" data-field="Status">
          <option value="">None</option>
          <option value="OK">OK</option>
          <option value="NO">NO</option>
        </select>
      </th>
      <th>
        <select class="filter" data-field="Cough">
          <option value="">None</option>
          <option value="No">No</option>
          <option value="Yes">Yes</option>
        </select>
      </th>
      <th>
        <select class="filter" data-field="Fever">
          <option value="">None</option>
          <option value="No">No</option>
          <option value="Yes">Yes</option>
        </select>
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>OK</td>
      <td>No</td>
      <td>Yes</td>
    </tr>
    <tr>
      <td>NO</td>
      <td>Yes</td>
      <td>Yes</td>
    </tr>
    <tr>
      <td>OK</td>
      <td>No</td>
      <td>No</td>
    </tr>
    <tr>
      <td>NO</td>
      <td>Yes</td>
      <td>No</td>
    </tr>
  </tbody>
</table>