表格中的Javascript过滤器按多行

问题描述

我正在尝试制作将基于多个输入进行过滤的过滤器。一种输入将过滤在一列中。

我的JavaScript和代码

function myFunction(column,input) {
  var filter,table,tr,td,i,txtValue;
  filter = input.value.toupperCase();
  table = document.getElementById("myTable");
  tr = table.getElementsByTagName("tr");
  for (i = 0; i < tr.length; i++) {
    td = tr[i].getElementsByTagName("td")[column];
    if (td) {
      txtValue = td.textContent || td.innerText;
      if (txtValue.toupperCase().indexOf(filter) > -1) {
        tr[i].style.display = "";
      } else {
        tr[i].style.display = "none";
      }
    }
  }
}
<div class="row">
<input class="font-15 w-180-px" onkeydown="myFunction(0,this)" type="text">
 <label class="font-18"> Input 1 </label>
<br>

 <input class="font-15 w-180-px" onkeydown="myFunction(1,this)" type="text">
   <label class="font-18"> Input 2 </label>
            <br>

<input class="font-15 w-180-px" onkeydown="myFunction(2,this)" type="text">
<label class="font-18"> Input 3 </label>
            <br>

<input class="font-15 w-180-px" onkeydown="myFunction(3,this)" type="text">
<label class="font-18"> Input 4 </label>
            <br>

<input class="font-15 w-180-px" onkeydown="myFunction(4,this)" type="text">
<label class="font-18"> Input 5 </label>
            <br>

<input class="font-15 w-180-px" onkeydown="myFunction(5,this)" type="text">
<label class="font-18"> Input 6 </label>
            <br>
</div>


<table id="myTable">
  <tr class="header">
    <th style="width:20%;">1</th>
    <th style="width:20%;">2</th>
    <th style="width:20%;">3</th>
    <th style="width:20%;">4</th>
    <th style="width:20%;">5</th>
    <th style="width:20%;">6</th>
  </tr>
  <tr>
    <td>Some 1 - a</td>
    <td>Some 2 - a</td>
    <td>Some 3 - a</td>
    <td>Some 4 - a</td>
    <td>Some 5 - a</td>
    <td>Some 6 - a</td>
  </tr>
  <tr>
    <td>Some 1 - b</td>
    <td>Some 2 - b</td>
    <td>Some 3 - b</td>
    <td>Some 4 - b</td>
    <td>Some 5 - b</td>
    <td>Some 6 - b</td>
  </tr>
  <tr>
    <td>Some 1 - c</td>
    <td>Some 2 - c</td>
    <td>Some 3 - c</td>
    <td>Some 4 - c</td>
    <td>Some 5 - c</td>
    <td>Some 6 - c</td>
  </tr>
  <tr>
    <td>Some 1 - d</td>
    <td>Some 2 - d</td>
    <td>Some 3 - d</td>
    <td>Some 4 - d</td>
    <td>Some 5 - d</td>
    <td>Some 6 - d</td>
  </tr>
</table>

所以基本上-现在我在Input 1中输入值,并对其进行严格过滤table,但是随后我在Input 2中输入值,并且仅对table的第二列进行过滤。我想在Input 1Input 2中输入值,它将过滤其中包含rowInput 1值的Input 2。感谢您的帮助。

顺便说一句。我在使用JQuery时没有问题。

解决方法

function myFunction(column,input) {
            var filter,table,tr,td,i,txtValue;
            filter = input.value.toUpperCase();
            console.log(filter);
            table = document.getElementById("myTable");
            tr = table.getElementsByTagName("tr");
            for (i = 0; i < tr.length; i++) {
                td = tr[i].getElementsByTagName("td")[column];
                if (td) {
                    txtValue = td.textContent || td.innerText;
                    console.log(filter,txtValue.toUpperCase().indexOf(filter));
                    if (txtValue.toUpperCase().indexOf(filter) > -1) {
                        if(tr[i].style.display != "none") // if something has been hidden by previous filter,we don't want to show it
                          tr[i].style.display = "";
                    } else {
                        tr[i].style.display = "none";
                    }
                }
            }
        }
<div class="row">
    
    <input class="font-15 w-180-px" onchange="myFunction(0,this)" type="text"><label class="font-18"> Input 1 </label><br>
   <input class="font-15 w-180-px" onchange="myFunction(1,this)" type="text"> <label class="font-18"> Input 2 </label>
                <br>
    

    <input class="font-15 w-180-px" onchange="myFunction(2,this)" type="text"><label class="font-18"> Input 3 </label>
                <br>
</div>

<table id="myTable">
    <tr class="header">
        <th style="width:20%;">1</th>
        <th style="width:20%;">2</th>
        <th style="width:20%;">3</th>
        <th style="width:20%;">4</th>
        <th style="width:20%;">5</th>
        <th style="width:20%;">6</th>
    </tr>
    <tr>
        <td>Some 1 - a</td>
        <td>Some 2 - a</td>
        <td>Some 3 - a</td>
        <td>Some 4 - a</td>
        <td>Some 5 - a</td>
        <td>Some 6 - a</td>
    </tr>
    <tr>
        <td>Some 1 - b</td>
        <td>Some 2 - b</td>
        <td>Some 3 - b</td>
        <td>Some 4 - b</td>
        <td>Some 5 - b</td>
        <td>Some 6 - b</td>
    </tr>
    <tr>
        <td>Some 1 - c</td>
        <td>Some 2 - c</td>
        <td>Some 3 - c</td>
        <td>Some 4 - c</td>
        <td>Some 5 - c</td>
        <td>Some 6 - c</td>
    </tr>
    <tr>
        <td>Some 1 - d</td>
        <td>Some 2 - d</td>
        <td>Some 3 - d</td>
        <td>Some 4 - d</td>
        <td>Some 5 - d</td>
        <td>Some 6 - d</td>
    </tr>
</table>

这是一个幼稚的解决方案-在将显示设置为空字符串之前,请确保以前的过滤器没有隐藏特定的行。不过,您仍然需要“重置”过滤器。

我会采用以下解决方案(当然要重构):

var filters = ["","",""];

function applyNewFilters() {
  console.log(filters);
  var rows = $('#myTable').find('tr');
  for(var i = 1; i < rows.length; i++) {
    var row = $(rows[i]); // we're re-applying all filters anyway
    row.show();
  }
  for(var i = 1; i < rows.length; i++) {
    var row = $(rows[i]);
    for(var f = 0; f < filters.length; f++) {
      //column is going to be equal to f
      var col = $(row.find('td')[f]).text();
      console.log(col);
      if(col.indexOf(filters[f]) < 0) {
        row.hide();
      }
    }
  }
}

$('.filter-input').on('change',function() {
  var $modifiedInput = $(this);
  console.log($modifiedInput.val());
  var column = $modifiedInput.attr('data-col');
    filters[column] = $modifiedInput.val();
    applyNewFilters();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
        
        <input class="font-15 w-180-px filter-input" data-col="0" type="text"><label class="font-18"> Input 1 </label><br>
       <input class="font-15 w-180-px filter-input" data-col="1"  type="text"> <label class="font-18"> Input 2 </label>
                    <br>
        

        <input class="font-15 w-180-px filter-input"  data-col="2" type="text"><label class="font-18"> Input 3 </label>
                    <br>
    </div>

    <table id="myTable">
        <tr class="header">
            <th style="width:20%;">1</th>
            <th style="width:20%;">2</th>
            <th style="width:20%;">3</th>
            <th style="width:20%;">4</th>
            <th style="width:20%;">5</th>
            <th style="width:20%;">6</th>
        </tr>
        <tr>
            <td>Some 1 - a</td>
            <td>Some 2 - b</td>
            <td>Some 3 - a</td>
            <td>Some 4 - a</td>
            <td>Some 5 - a</td>
            <td>Some 6 - a</td>
        </tr>
        <tr>
            <td>Some 1 - b</td>
            <td>Some 2 - b</td>
            <td>Some 3 - b</td>
            <td>Some 4 - b</td>
            <td>Some 5 - b</td>
            <td>Some 6 - b</td>
        </tr>
        <tr>
            <td>Some 1 - c</td>
            <td>Some 2 - c</td>
            <td>Some 3 - c</td>
            <td>Some 4 - c</td>
            <td>Some 5 - c</td>
            <td>Some 6 - c</td>
        </tr>
        <tr>
            <td>Some 1 - d</td>
            <td>Some 2 - d</td>
            <td>Some 3 - d</td>
            <td>Some 4 - d</td>
            <td>Some 5 - d</td>
            <td>Some 6 - d</td>
        </tr>
    </table>

,

尝试如下。使用onkeyup代替onkeydown。使用myFunction而不使用parameter,因为我们需要从所有输入中应用过滤器。

id添加到每个input,并在filters数组中检索其值。添加了注释以解释逻辑。

在下面尝试。

function myFunction() {
  var tr,txtValue;
  table = document.getElementById("myTable");
  tr = table.getElementsByTagName("tr");

  // get all filter values.
  // use isApplyFilter to get whether any input is provided for filter or not.
  let filters = [],isApplyFilter = false;
  for (i = 0; i < 6; i++) {
    filters.push($('#input' + (i + 1)).val().toUpperCase().trim());
    isApplyFilter = isApplyFilter || !!filters[i];
  }

  // loop over all tr except 1st one because it is header.
  for (i = 1; i < tr.length; i++) {

    // if isApplyFilter = false then show all rows
    if (!isApplyFilter) {
      tr[i].style.display = "";
      continue;
    }

    // by default hide row
    tr[i].style.display = "none";

    // loop over all columns and respective filter value
    for (j = 0; j < 6; j++) {
      // get column
      td = tr[i].getElementsByTagName("td")[j];

      // if filter has value then only check for condition
      if (filters[j] && td) {
        txtValue = td.textContent || td.innerText;
        // on satisfied condition show row and break inner loop
        if (txtValue.toUpperCase().indexOf(filters[j]) > -1) {
          tr[i].style.display = "";
          break;
        }
      }
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<div class="row">
  <label class="font-18"> Input 1 </label>
  <br>
  <input id='input1' class="font-15 w-180-px" onkeyup="myFunction()" type="text">

  <label class="font-18"> Input 2 </label>
  <br>
  <input id='input2' class="font-15 w-180-px" onkeyup="myFunction()" type="text">

  <label class="font-18"> Input 3 </label>
  <br>
  <input id='input3' class="font-15 w-180-px" onkeyup="myFunction()" type="text">

  <label class="font-18"> Input 4 </label>
  <br>
  <input id='input4' class="font-15 w-180-px" onkeyup="myFunction()" type="text">

  <label class="font-18"> Input 5 </label>
  <br>
  <input id='input5' class="font-15 w-180-px" onkeyup="myFunction()" type="text">

  <label class="font-18"> Input 6 </label>
  <br>
  <input id='input6' class="font-15 w-180-px" onkeyup="myFunction()" type="text">
</div>

<table id="myTable">
  <tr class="header">
    <th style="width:20%;">1</th>
    <th style="width:20%;">2</th>
    <th style="width:20%;">3</th>
    <th style="width:20%;">4</th>
    <th style="width:20%;">5</th>
    <th style="width:20%;">6</th>
  </tr>
  <tr>
    <td>Some 1 - a</td>
    <td>Some 2 - a</td>
    <td>Some 3 - a</td>
    <td>Some 4 - a</td>
    <td>Some 5 - a</td>
    <td>Some 6 - a</td>
  </tr>
  <tr>
    <td>Some 1 - b</td>
    <td>Some 2 - b</td>
    <td>Some 3 - b</td>
    <td>Some 4 - b</td>
    <td>Some 5 - b</td>
    <td>Some 6 - b</td>
  </tr>
  <tr>
    <td>Some 1 - c</td>
    <td>Some 2 - c</td>
    <td>Some 3 - c</td>
    <td>Some 4 - c</td>
    <td>Some 5 - c</td>
    <td>Some 6 - c</td>
  </tr>
  <tr>
    <td>Some 1 - d</td>
    <td>Some 2 - d</td>
    <td>Some 3 - d</td>
    <td>Some 4 - d</td>
    <td>Some 5 - d</td>
    <td>Some 6 - d</td>
  </tr>
</table>