每个列上的HTML表搜索单独使用JavaScript

时间:2019-02-05 18:11:04

标签: javascript html

我有一个5列的表格。以下代码将根据所有列过滤数据。我想过滤每一列的数据。例如:如果有10列,那么有10个搜索字段,还有如何使HTML部件动态化,这样,每当添加新列时,我都不必再添加一个搜索文本字段。

<input id="myInput" type="text"  />

<script>
   function filterTable(event) {
    var filter = event.target.value.toUpperCase();
    var rows = document.querySelector("#myTable tbody").rows;

    for (var i = 1; i < rows.length; i++) {
        var Col1 = rows[i].cells[0].textContent.toUpperCase();
        var Col2 = rows[i].cells[1].textContent.toUpperCase();
        var Col3 = rows[i].cells[2].textContent.toUpperCase();
        var Col4 = rows[i].cells[3].textContent.toUpperCase();
        var Col5 = rows[i].cells[4].textContent.toUpperCase();
        if (Col1.indexOf(filter) > -1 || Col2.indexOf(filter) > -1 || Col3.indexOf(filter) > -1
          || Col4.indexOf(filter) > -1 || Col5.indexOf(filter) > -1) {
            rows[i].style.display = "";
        } else {
            rows[i].style.display = "none";
        }      
    }
}

document.querySelector(''#myInput'').addEventListener(''keyup'', filterTable, false);
</script>

我想拥有这种功能:

3 个答案:

答案 0 :(得分:1)

您要做的就是使用for循环迭代.cells数组:

在此示例中,我使用了一个变量来确定是否应显示该行。

function filterTable(event) {
  var filter = event.target.value.toUpperCase();
  var rows = document.querySelector("#myTable tbody").rows;

  for (var i = 1; i < rows.length; i++) {
    // Placeholder to indicate if a row matches the given query.
    var shouldShowRow = false;
    // Loop over all the cells in this row.
    for (var k = 0; k < rows[i].cells.length) {
      // Check to see if this cell in this row matches the query.
      if (rows[i].cells[k].textContent.toUpperCase().indexOf(filter) > -1) {
        // Yes, this cell matches, therefore this entire row matches.
        // Flip the show row boolean to indicate that we need to show.
        shouldShowRow = true;
        // Because this cell matches, we do not need to check any more cells.
        break;
      }
    }
    // Change the display on the row if we need to.
    if (shouldShowRow) {
      rows[i].style.display = "";
    } else rows[i].style.display = "none";
  }
}

答案 1 :(得分:1)

您可以遍历行,然后遍历列。通过Array.from方法,您可以将元素列表转换为数组,以便可以使用Array.prototype.forEach遍历子级。

您需要做的就是为每行将show初始化为true。然后,如果任何DOES NOT列均符合过滤条件,则将show设置为false。遍历所有列后,您将基于show的最终值显示行。

编辑:确保您使用的浏览器支持ES6 +。 MDN网站上有Array.from可用的polyfill。

function filterTable(event) {
  let filter = event.target.value.trim().toLowerCase();
  let rows = document.querySelector('#myTable tbody').rows;
  for (let i = 0; i < rows.length; i++) {
    let row = rows[i], show = false;
    if (filter.length > 0) {
      for (let j = 0; j < row.children.length; j++) {
        let col = row.children[j], text = col.textContent.toLowerCase();
        if (text.indexOf(filter) > -1) {
          show = true;
          continue;
        }
      }
    } else {
      show = true;
    }
    // Avoid using 'row.styledisplay' - https://stackoverflow.com/a/28028656/1762224
    // Avoid using 'row.visibility'   - rows do not collapse
    toggleClass(row, 'hidden-row', !show);
  }
}

function toggleClass(el, className, state) {
  if (el.classList) el.classList.toggle(className, state);
  else {
    var classes = el.className.split(' ');
    var existingIndex = classes.indexOf(className);
    if (state === undefined) {
      if (existingIndex > -1) classes.splice(existingIndex, 1)
      else classes.push(existingIndex);
    } else {
      if (!state) classes.splice(existingIndex, 1)
      else classes.push(existingIndex);
    }
    el.className = classes.join(' ');
  }
}

document.querySelector('#myInput').addEventListener('keyup', filterTable, false);
body {
  padding: 8px;
}
.field label {
  font-weight: bold;
  margin-right: 0.25em;
}
#myTable {
  margin-top: 0.667em;
  width: 100%;
}
#myTable th {
  text-transform: capitalize;
}
.hidden-row {
  display: none;
}
<link href="https://unpkg.com/purecss@1.0.0/build/pure-min.css" rel="stylesheet" />
<div class="field"><label for="myInput">Filter:</label><input id="myInput" type="text" /></div>
<table id="myTable" class="pure-table pure-table-horizontal">
  <thead>
    <tr>
      <th>name</th>
      <th>drink</th>
      <th>pizza</th>
      <th>movie</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Homer</td>
      <td>Squishie</td>
      <td>Magheritta</td>
      <td>The Avengers</td>
    </tr>
    <tr>
      <td>Marge</td>
      <td>Squishie</td>
      <td>Magheritta</td>
      <td>The Avengers</td>
    </tr>
    <tr>
      <td>Bart</td>
      <td>Squishie</td>
      <td>Pepperoni</td>
      <td>Black Dynamite</td>
    </tr>
    <tr>
      <td>Lisa</td>
      <td>Buzz Cola</td>
      <td>Pepperoni</td>
      <td>Iron Man</td>
    </tr>
    <tr>
      <td>Maggie</td>
      <td>Duff Beer</td>
      <td>Magheritta</td>
      <td>The Avengers</td>
    </tr>
    <tr>
      <td>Kent</td>
      <td>Duff Beer</td>
      <td>Hawaiian</td>
      <td>The Avengers</td>
    </tr>
  </tbody>
</table>


搜索字段示例

populateTable(document.getElementById('simpsons'), getData());

function dataFields(data) {
  return data.reduce((r, x) => Object.keys(x).reduce((s, k) => s.indexOf(k) === -1 ? s.concat(k) : s, r), []);
}

/* Can be useful if working with raw JSON data */
function searchCriteria(fields) {
  return Array.from(fields).reduce((o, field) => {
    return Object.assign(o, { [field.getAttribute('placeholder')] : field.value });
  }, {});
}

function onFilter(e) {
  let table = e.target.parentElement.parentElement.parentElement.parentElement;
  let fields = table.querySelectorAll('thead tr th input');
  let criteria = searchCriteria(fields); // Unused, but useful if filtering bindable data
  let searchText = Array.from(fields).map(field => field.value.trim());
  Array.from(table.querySelectorAll('tbody tr')).forEach(row => {
    let hideRow = false;
    Array.from(row.children).forEach((col, index) => {
      var value = col.innerHTML.trim().toLowerCase();
      var search = searchText[index].toLowerCase();
      if (search.length > 0) {
        if (!value.startsWith(search)) { /* or value.indexOf(search) === -1 */
          hideRow = true;
          return;
        }
      }
    });
    row.classList.toggle('hidden-row', hideRow);
  });
}

function populateTable(table, data) {
  let fields = dataFields(data);
  let thead = document.createElement('THEAD');
  let tr = document.createElement('TR');
  fields.forEach(field => {
    let th = document.createElement('TH');
    th.innerHTML = field;
    tr.appendChild(th);
  });
  thead.appendChild(tr);
  let tbody = document.createElement('TBODY');
  tr = document.createElement('TR');
  fields.forEach(field => {
    let th = document.createElement('TH');
    let input = document.createElement('INPUT');
    input.setAttribute('placeholder', field);
    input.addEventListener('keyup', onFilter);
    th.append(input);
    tr.appendChild(th);
  });
  thead.appendChild(tr);
  data.forEach(record => {
    let tr = document.createElement('TR');
    fields.forEach(field => {
      let td = document.createElement('TD');
      td.innerHTML = record[field];
      tr.appendChild(td);
    });
    tbody.append(tr);
  });
  table.appendChild(thead);
  table.appendChild(tbody);
}

function getData() {
  return [{
    "name": "Homer",
    "drink": "Squishie",
    "pizza": "Magheritta",
    "movie": "The Avengers"
  }, {
    "name": "Marge",
    "drink": "Squishie",
    "pizza": "Magheritta",
    "movie": "The Avengers"
  }, {
    "name": "Bart",
    "drink": "Squishie",
    "pizza": "Pepperoni",
    "movie": "Black Dynamite"
  }, {
    "name": "Lisa",
    "drink": "Buzz Cola",
    "pizza": "Pepperoni",
    "movie": "Iron Man"
  }, {
    "name": "Maggie",
    "drink": "Duff Beer",
    "pizza": "Magheritta",
    "movie": "The Avengers"
  }, {
    "name": "Kent",
    "drink": "Duff Beer",
    "pizza": "Hawaiian",
    "movie": "The Avengers"
  }];
}
table {
  border-collapse: collapse;
  width: 100%;
}
table thead tr th {
  text-transform: capitalize;
}
table thead tr:last-child {
  background: #eaeaea;
  border-bottom: 4px double #cbcbcb;
}
table thead tr th input {
  width: 100%;
}
table tbody tr:nth-child(even) {
  background-color: #f2f2f2;
}
table tbody tr.hidden-row {
  display: none;
}
<link href="https://unpkg.com/purecss@1.0.0/build/pure-min.css" rel="stylesheet" />
<table id="simpsons" class="pure-table pure-table-horizontal"></table>


浏览器兼容性

function onFilter(e) {
  var table = e.target.parentElement.parentElement.parentElement.parentElement;
  console.log(table);
  var fields = table.querySelectorAll('thead tr th input');
  console.log(fields);
  var searchText = Array.from(fields).map(function (field) {
    return field.value.trim();
  });
  console.log(searchText);
  Array.from(table.querySelectorAll('tbody tr')).forEach(function (row) {
    var hideRow = false;
    Array.from(row.children).forEach(function (col, index) {
      var value = col.innerHTML.trim().toLowerCase();
      console.log(value);
      var search = searchText[index].toLowerCase();
      console.log(search);
      if (search.length > 0) {
        if (value.indexOf(search) === -1) {
          hideRow = true;
          return;
        }
      }
    });
    row.classList.toggle('hidden-row', hideRow);
  });
}

答案 2 :(得分:0)

您可以使用数组。 首先将col映射到数组colArr,然后使用匹配的内容将filter的内容与cols的内容进行匹配。

for (var i = 1; i < rows.length; i++) {
  let colArr = new Array(5).fill(0).map((e,index)=> rows[i].cells[index].textContent.toUpperCase();) 
     if (colArr.some(e=> e.indexOf(filter) > -1 ) {
         rows[i].style.display = "";
        } else {
          rows[i].style.display = "none";
        }
    }) 
}