jqueryhtml-tabletr

How to filter a <tr> by searching for the value in each <td> containing a class?


When a value is entered into the input, only the row (or rows) containing that value should be displayed, and it works. To do this, each <td> has a <p class="x"> tag, but only the first <td> with that class is taken. Here's an example. The text within the red borders are the only values ​​that work. Ignore class="red"

$("#filter").on("input", function () {
    let value = $(this).val().toLowerCase();
    $("tbody tr").filter(function () {
      $(this).toggle($(this).find(".x").text().toLowerCase().indexOf(value) === 0);
    });
  })
.red {border: 1px solid red;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<input id="filter" type="text" autocomplete="off">
<table>
    <tbody>
      <tr>
        <td>---</td>
        <td>
          <p class="x red">text</p>
        </td>
        <td>
          <span></span>
          <p class="x">card</p>
        </td>
      </tr>
      <tr>
        <td>
          <p class="x red">robot</p>
        </td>
        <td>
          <p class="x">game</p>
        </td>
        <td>
          <p></p>
          <p class="x">box</p>
        </td>
      </tr>
    </tbody>
  </table>

What I'm looking to do is, for example, if I put the word "robot", "game" or "box" in the input (and not just "robot"), all the tr that contain any of those words will show the entire row.

filter entire row


Solution

  • Your code correctly identifies the elements in the row with the call to .find(".x"), but the next chained method .text() only gets the text of the first match.

    Instead you need to iterate all elements that were found and then verify their texts individually:

        $("tbody tr").each(function () {
          $(this).toggle(
            $(this).find(".x").toArray().some(function (item) {
               return $(item).text().toLowerCase().includes(value);
            })
          );
        });
    

    Unrelated, but the following remarks were applied in the above code:

    $("#filter").on("input", function () {
      let value = $(this).val().toLowerCase();
      $("tbody tr").each(function () {
         $(this).toggle(
           $(this).find(".x").toArray().some(function (item) {
              return $(item).text().toLowerCase().includes(value);
           })
         );
      });
    });
    .red {border: 1px solid red;}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <input id="filter" type="text" autocomplete="off">
    <table>
        <tbody>
          <tr>
            <td>---</td>
            <td>
              <p class="x red">text</p>
            </td>
            <td>
              <span></span>
              <p class="x">card</p>
            </td>
          </tr>
          <tr>
            <td>
              <p class="x red">robot</p>
            </td>
            <td>
              <p class="x">game</p>
            </td>
            <td>
              <p></p>
              <p class="x">box</p>
            </td>
          </tr>
        </tbody>
      </table>