Erik
Erik

Reputation: 3

jQuery toggle parent in search

I have a table similar to this:

<input id="mySearch" placeholder="Search..." type="text"/>
<table>
  <th>Main header</th>
  <tbody id="searchable">
    <tr class="parent"><td>Parent</td></tr>
    <tr class="subparent"><td>Subparent one</td></tr>
    <tr class="child"><td>Child one</td></tr>
    <tr class="subparent"><td>Subparent two</td></tr>
    <tr class="child"><td>Child two</td></tr>
  </tbody>
</table>

Then what I want to do is to search through the table and show the elements where the search criteria is matched, and expand their respective subparent ("parent" is never hidden).

If I search for "child two", then both child and subparent for "child two" should be toggled, but neither child or subparent for "child one" should be toggled. A search for "child" should toggle both children and both subparents.

Here's my current script, which sort of works, but it also toggles the subparents whose children does not match the search:

<script src="jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
  $("#mySearch").on("keyup", function() {
    var value = $(this).val().toLowerCase();
    $("#searchable tr").filter(function() {
      $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1).prev('.subparent').toggle();
    });
  });
});
</script>

The structure of the table is as follows:

Main category
`-> Main subcategory (parent)
`--> Specific subcategory (subparent)
`---> Data to search (child)

In larger scale, this translates to:

Main category
`-> Parent 1
`--> Subparent 1
`---> Data 1
`---> Data 2
`---> Data 3
`--> Subparent 2
`---> Data 1
`---> Data 2
`-> Parent 2
`--> Subparent 1
`---> Data 1

Hence, I need to search all data, which are hidden below (sub)parent, and expand the child and subparent for all matches in search.

How can I make this toggle only the subparents where the children match the search?

Upvotes: 0

Views: 119

Answers (1)

Bhushan Kawadkar
Bhushan Kawadkar

Reputation: 28513

You can use below script where on keyup event you need to hide all rows first and then filter child rows for which match found and if match found then show its subparent too.

see below code

$(document).ready(function () {
  $("#mySearch").on("keyup", function() {
    var value = $(this).val().toLowerCase();
    //hide all rows
    $("#searchable tr.subparent, #searchable tr.child").hide();
    //show rows
    $("#searchable tr.child").filter(function() {
      var found = $(this).text().toLowerCase().indexOf(value)!=-1;
      if(found) { // show subparent if child matches
        if($(this).prev().hasClass('subparent')) {
           $(this).prev().show();
        } else {
          $(this).prevUntil('.subparent').last().prev().show();
        }
      }
      return found;
    }).show();
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="mySearch" placeholder="Search..." type="text"/>
<table>
  <th>Main header</th>
  <tbody id="searchable">
    <tr class="parent"><td>Parent</td></tr>
    <tr class="subparent"><td>Subparent one three four</td></tr>
    <tr class="child"><td>Child four</td></tr>
    <tr class="child"><td>Child three</td></tr>
    <tr class="child"><td>Child one</td></tr>
    <tr class="subparent"><td>Subparent two five six</td></tr>
    <tr class="child"><td>Child two</td></tr>
    <tr class="child"><td>Child five</td></tr>
    <tr class="child"><td>Child six</td></tr>
  </tbody>
</table>

Upvotes: 1

Related Questions