2

I have a table with multiple rows and columns. I wrote a function that is currently searching through only the first and last columns of my table, however I am not sure why the middle columns are being skipped over. I tried adding another for loop and got an error.

function function2(){
          var input = document.getElementById("myInput");
          var filter = input.value.toUpperCase();
          var table = document.getElementById("table2c");
          var tr = table.getElementsByTagName("tr");
          var td, tdArr, i, j;
        
          for (i = 0; i < tr.length; i++) {
            tdArr = tr[i].getElementsByTagName("td");
            for (j = 0; j < tdArr.length; j++){
              td = tdArr [j];
              if (td) {
              if (td.innerHTML.toUpperCase().indexOf(filter) > -1 ) {
                tr[i].style.display = "";
              } else {
                tr[i].style.display = "none";
              }
            }
          }
        }
       }
This is my table: 
   <table className="table table-bordered" id="table2c">
                      <tbody>
                      <tr>
                      <th> Header Name: </th>
                      <th> Description: </th>
                      <th> Value: </th>
                      </tr>
        
                      <tr>
                      <td> Authorization </td>
                      <td> security token </td>
                      <td> To be supplied  </td>
                      </tr>
        
                      <tr>
                      <td> Content-Type </td>
                      <td> body of the request </td>
                      <td> applicaiton </td>
                      </tr>
        
                      <tr>
                      <td> API-KEY </td>
                      <td>  ID </td>
                      <td> To be supplied </td>
                      </tr>
        
                      <tr>
                      <td> correlation </td>
                      <td> Unique identifier </td>
                      <td> e.g. control number </td>
                      </tr>
        
                      <tr>
                      <td> name </td>
                      <td> system name  </td>
                      <td> One of: </td>
                      </tr>
                      </tbody>
                      </table>

2
  • what is the wanted result? hide all rows without some search result? Commented Jul 12, 2018 at 14:51
  • @NinaScholz yes that is the result, which is functioning right now, but its only searching through the first and last column, I want to be able to search for data in the middle column as well Commented Jul 12, 2018 at 14:58

4 Answers 4

2

add break here if (td.innerHTML.toUpperCase().indexOf(filter) > -1 ) { tr[i].style.display = ""; break; } You need to stop the second loop once youfind a result, otherwise if the element is not found in the third column it will hide the entire row

function function2(){
          var input = document.getElementById("myInput");
          var filter = input.value.toUpperCase();
          var table = document.getElementById("table2c");
          var tr = table.getElementsByTagName("tr");
          var td, tdArr, i, j;
        
          for (i = 0; i < tr.length; i++) {
            tdArr = tr[i].getElementsByTagName("td");
            for (j = 0; j < tdArr.length; j++){
              td = tdArr [j];
              if (td) {
              if (td.innerHTML.toUpperCase().indexOf(filter) > -1 ) {
                tr[i].style.display = "";
                break;
              } else {
                tr[i].style.display = "none";
              }
            }
          }
        }
       }
<input type="text" id="myInput" />
<button onclick="function2()">search</button>
This is my table: 
   <table className="table table-bordered" id="table2c">
                      <tbody>
                      <tr>
                      <th> Header Name: </th>
                      <th> Description: </th>
                      <th> Value: </th>
                      </tr>
        
                      <tr>
                      <td> Authorization </td>
                      <td> security token </td>
                      <td> To be supplied  </td>
                      </tr>
        
                      <tr>
                      <td> Content-Type </td>
                      <td> body of the request </td>
                      <td> applicaiton </td>
                      </tr>
        
                      <tr>
                      <td> API-KEY </td>
                      <td>  ID </td>
                      <td> To be supplied </td>
                      </tr>
        
                      <tr>
                      <td> correlation </td>
                      <td> Unique identifier </td>
                      <td> e.g. control number </td>
                      </tr>
        
                      <tr>
                      <td> name </td>
                      <td> system name  </td>
                      <td> One  </td>
                      </tr>
                      </tbody>
                      </table>

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

2 Comments

thank you, that worked for the middle column but now the last column is no longer included in the search @ramSegev
i fixed my answer
1

Add break; to exist for loop if match found.

    function function2() {
        var input = document.getElementById("myInput");
        var filter = input.value.toUpperCase();
        var table = document.getElementById("table2c");
        var tr = table.getElementsByTagName("tr");
        var td, tdArr, i, j;

        for (i = 0; i < tr.length; i++) {
            tdArr = tr[i].getElementsByTagName("td");
            for (j = 0; j < tdArr.length; j++) {
                td = tdArr[j];
                if (td) {
                    if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
                        tr[i].style.display = "";
                        break;
                    } else {
                        tr[i].style.display = "none";
                    }
                }
            }
        }
    }
<input type="text" id="myInput" /> <input type="button" id="search" value="Search" onclick="function2()" />
<table className="table table-bordered" id="table2c">
<tbody>
    <tr>
        <th> Header Name: </th>
        <th> Description: </th>
        <th> Value: </th>
    </tr>

    <tr>
        <td> Authorization </td>
        <td> HMAC security token </td>
        <td> To be supplied by APIGEE </td>
    </tr>

    <tr>
        <td> Content-Type </td>
        <td> Media type of the body of the request </td>
        <td> applicaiton/xml </td>
    </tr>

    <tr>
        <td> X-AMEX-API-KEY </td>
        <td> HMAC ID </td>
        <td> To be supplied by APIGEE </td>
    </tr>

    <tr>
        <td> correlation_id </td>
        <td> Unique identifier to track the consumer request </td>
        <td> e.g. Process control number </td>
    </tr>

    <tr>
        <td> originator_name </td>
        <td> Originating consumer system name  </td>
        <td> One of: GCAP, GDE </td>
    </tr>
</tbody>
</table>

Comments

1

You could loop from the second row, because a find would vanish the table head. Then you could switch off all rows in advance and remove 'none' if a found value is in the row. Break then as well.

function function2() {
  var input = document.getElementById("myInput"),
      filter = input.value.toUpperCase(),
      table = document.getElementById("table2c"),
      tr = table.getElementsByTagName("tr"),
      td, tdArr, i, j;

  for (i = 1; i < tr.length; i++) {
    tr[i].style.display = "none";
    tdArr = tr[i].getElementsByTagName("td");
    for (j = 0; j < tdArr.length; j++) {
      td = tdArr[j];
      if (td && td.innerHTML.toUpperCase().indexOf(filter) > -1) {
          tr[i].style.display = "";
          break;
      }
    }
  }
}
<input id="myInput" type="text" onchange="function2()">
<table className="table table-bordered" id="table2c">
  <tbody>
    <tr><th> Header Name: </th><th> Description: </th><th> Value: </th></tr>
    <tr><td> Authorization </td><td> HMAC security token </td><td> To be supplied by APIGEE </td></tr>
    <tr><td> Content-Type </td><td> Media type of the body of the request </td><td> applicaiton/xml </td></tr>
    <tr><td> X-AMEX-API-KEY </td><td> HMAC ID </td><td> To be supplied by APIGEE </td></tr>
    <tr><td> correlation_id </td><td> Unique identifier to track the consumer request </td><td> e.g. Process control number </td></tr>
    <tr><td> originator_name </td><td> Originating consumer system name </td><td> One of: GCAP, GDE </td></tr>
  </tbody>
</table>

Comments

0

Just for reference, here's an implementation using a functionnal approach with some ES6 features (arrow functions, spread syntax and the .reduce method):

const filter = () => {

  const input = document.querySelector('#myInput');
  const filter = input.value.toUpperCase();
  
  const table = document.querySelector('#table2c');
  const trs = table.querySelectorAll('tr:not(:first-child)');
  
  // loop through all <tr> except the first one (header)
  trs.forEach(tr => {
  
    // reduce all the row's content (header, description and value) to a single string)
    const content = [...tr.children].reduce((content, td) => content + ' ' + td.textContent, '')
    
    // search if the filter is in content
    if(content.toUpperCase().includes(filter)) {
    
      tr.style.display = "";
    
    } else {

      tr.style.display = "none";
    
    }

  });

}

// add an event listener to the input element
document.querySelector('#myInput').addEventListener('keyup', filter);
<input id="myInput" />

<table className="table table-bordered" id="table2c">
  <tbody>
    <tr>
      <th> Header Name: </th>
      <th> Description: </th>
      <th> Value: </th>
    </tr>

    <tr>
      <td> Authorization </td>
      <td> HMAC security token </td>
      <td> To be supplied by APIGEE </td>
    </tr>

    <tr>
      <td> Content-Type </td>
      <td> Media type of the body of the request </td>
      <td> applicaiton/xml </td>
    </tr>

    <tr>
      <td> X-AMEX-API-KEY </td>
      <td> HMAC ID </td>
      <td> To be supplied by APIGEE </td>
    </tr>

    <tr>
      <td> correlation_id </td>
      <td> Unique identifier to track the consumer request </td>
      <td> e.g. Process control number </td>
    </tr>

    <tr>
      <td> originator_name </td>
      <td> Originating consumer system name </td>
      <td> One of: GCAP, GDE </td>
    </tr>
  </tbody>
</table>

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.