1

Borrowing code from the post below I am able to filter on 2 columns using the || (Or) operator. However, I'd like to be able to filter using the && (And) operator. I have been unsuccessful in my multiple attempts. I could use some help.

Filtering table multiple columns

function myFunction() {
  var input0, input1, filter0, filter1, table, tr, td, cell, i, j;
  document.getElementById("myInput0").value = 'Female';
  document.getElementById("myInput1").value = 'Engineering';
  input0 = document.getElementById("myInput0");
  input1 = document.getElementById("myInput1");
  filter0 = input0.value.toUpperCase();
  filter1 = input1.value.toUpperCase();
  table = document.getElementById("myTable");
  tr = table.getElementsByTagName("tr");
  for (i = 1; i < tr.length; i++) {
    // Hide the row initially.
  tr[i].style.display = "none";

  td = tr[i].getElementsByTagName("td");
    for (var j = 0; j < td.length; j++) {
      cell = tr[i].getElementsByTagName("td")[j];
      if (cell) {
         if (cell.textContent.toUpperCase().indexOf(filter0)>-1 || 
    cell.textContent.toUpperCase().indexOf(filter1)>-1) {
          tr[i].style.display = "";
          break;
        } 
      }
    }
  }
}
    <body>
    <input type="text" id="myInput0">
    <input type="text" id="myInput1">
    <input type='button' onclick='myFunction()' value='click me' />

    <table id="myTable">
      <thead>
      <tr>
        <th>Firstname</th>
        <th>Lastname</th>
        <th>Gender</th>
        <th>Department</th>
      </tr>
      </thead>
      <tbody>
      <tr>
        <td>John</td>
        <td>Doe</td>
        <td>Male</td>
        <td>Sales</td>
      </tr>
      <tr>
        <td>Mary</td>
        <td>Moe</td>
        <td>Female</td>
        <td>Service</td>
      </tr>
      <tr>
        <td>July</td>
        <td>Dooley</td>
        <td>Female</td>
        <td>Service</td>
      </tr>
      <tr>
        <td>Anja</td>
        <td>Ravendale</td>
        <td>Female</td>
        <td>Engineering</td>
      </tr>
      <tr>
        <td>Thomas</td>
        <td>Dubois</td>
        <td>Male</td>
        <td>Sales</td>
      </tr>
      <tr>
        <td>Deidre</td>
        <td>Masters</td>
        <td>Female</td>
        <td>Sales</td>
      </tr>
      <tr>
        <td>Sean</td>
        <td>Franken</td>
        <td>Male</td>
        <td>Engineering</td>
      </tr>
      </tbody>
    </table>

    </body>

2 Answers 2

0

For each cell, you can check each filter separately, then only change the DOM for rows where all filter conditions are met.

(This example uses a restructured version of your code.)

document.getElementById("myInput0").value = 'Female';
document.getElementById("myInput1").value = 'Engineering';
const
  input0 = document.getElementById("myInput0"),
  input1 = document.getElementById("myInput1"),
  table = document.getElementById("myTable"),
  rows = table.getElementsByTagName("tr");

function myFunction() {
  filter0 = input0.value.toUpperCase(),
  filter1 = input1.value.toUpperCase();
  for (let row of rows) {
    row.classList.add("hidden");
    const cells = row.getElementsByTagName("td");
    let
      filter0met = false,
      filter1met = false;
    for (let cell of cells) {
      if (cell.textContent.toUpperCase().includes(filter0)) {
        filter0met = true;
      }
      if (cell.textContent.toUpperCase().includes(filter1)) {
        filter1met = true;
      }
    }
    if (filter0met && filter1met) {
      row.classList.remove("hidden");
    }
  }
}
.hidden {
  display: none;
}
<body>
  <input type="text" id="myInput0"><input type="text" id="myInput1"><input type='button' onclick='myFunction()' value='click me' />
  <table id="myTable">
    <thead>
      <tr>
        <th>Firstname</th>
        <th>Lastname</th>
        <th>Gender</th>
        <th>Department</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>John</td>
        <td>Doe</td>
        <td>Male</td>
        <td>Sales</td>
      </tr>
      <tr>
        <td>Mary</td>
        <td>Moe</td>
        <td>Female</td>
        <td>Service</td>
      </tr>
      <tr>
        <td>July</td>
        <td>Dooley</td>
        <td>Female</td>
        <td>Service</td>
      </tr>
      <tr>
        <td>Anja</td>
        <td>Ravendale</td>
        <td>Female</td>
        <td>Engineering</td>
      </tr>
      <tr>
        <td>Thomas</td>
        <td>Dubois</td>
        <td>Male</td>
        <td>Sales</td>
      </tr>
      <tr>
        <td>Deidre</td>
        <td>Masters</td>
        <td>Female</td>
        <td>Sales</td>
      </tr>
      <tr>
        <td>Sean</td>
        <td>Franken</td>
        <td>Male</td>
        <td>Engineering</td>
      </tr>
    </tbody>
  </table>

</body>

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you. You made very quick work of the problem. I can see that by running the code snippet on this page. However, I've copied the entire snippet adding the <script></script> tags into Notepad++ and I cannot get it to work. I am sure I'm missing something obvious.
The only things I can think of that you may have overlooked are that 1) the script element should be the last element inside the body (to make sure the HTML has all loaded before the script runs), and 2) the CSS should be in a style element inside the head (or in a properly linked external style sheet).
Awesome, glad to hear it.
I have wrestled with this for a few months, getting sidetracked and finding workarounds but I would really like to get this working for my application. I am a SharePoint admin and that is the environment I want to get this working. I have followed your instructions as closely as possible. In SharePoint I add a script editor to the page and add your code. However, to overcome an error, I use table = document.getElementsByClassName("ms-listviewtable")[0] instead of the querySelector. It stills works fine in Notepad++. SharePoint for some reason strips out the Body and Head tags. Any ideas?
Sorry, no. I have no familiarity with SharePoint. Using getElementsByClassName does sound perfectly reasonable, though.
0

After much trial and error for I was able to put together some JQuery that will dynamically search the first input, and then search those results for the second input. Note, I am using SP2016. While I've included it here in my post, I could not get the call to "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js" to work. I found downloading and storing the file on my SharePoint site worked. For my requirement I wanted to display my list with grouped rows so I'm using a function to collapse the groups on load. The caveat is the groups in listview have to be configured as expanded.

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!DOCTYPE html>
<html>
<head>
<SCRIPT type="text/javascript"src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></SCRIPT>

<script>
           //If rows are not grouped, remove this function
                $(window).load(function () {
                $(".ms-commentcollapse-icon").click();
                });

$(document).ready(function() {
  $("#myInput").on("keyup", function() {
    var value = this.value.toLowerCase();

         //If rows are not grouped, remove this line
         $(".ms-commentexpand-icon").click();

    $('.ms-listviewtable > tbody > tr').addClass('myInputMismatch').filter(function() {
      return this.innerHTML.toLowerCase().indexOf(value) > -1;
}).removeClass('myInputMismatch');
  });
  $("#myInput1").on("keyup", function() {
    var value = this.value.toLowerCase();
    $('.ms-listviewtable > tbody > tr').addClass('myInput1Mismatch').filter(function() {
      return this.innerHTML.toLowerCase().indexOf(value) > -1;
}).removeClass('myInput1Mismatch');
  });
});
</script>
<style>
 .myInputMismatch, .myInput1Mismatch { display: none; }
</style></head>
<input id="myInput" type="text" Placeholder="Search here 1st..."><input id="myInput1" type="text" Placeholder="Search here 2nd...">

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.