How to hide thead when all tbody tr are hidden?

Asked

Viewed 91 times

1

Good evening, I am trying to make a search bar that Filtre by cells between various tables, and I would like this search hide the <thead> of the tables that do not possess results corresponding to the search, that is, when the user searches Leg, the table containing Locations and Countries as well as the table containing Cars and Motorcycle Manufacturers, for not having in any <tr> the text Leg, must have the <thead> hidden, or even the whole <table> occult.

//pesquisa
    $(document).ready(function () {
        $("#searchInput").on("keyup", function () {
            var value = $(this).val().toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g,
                "");
            $("tbody tr").filter(function () {
                $(this).toggle($(this).text().toLowerCase().normalize('NFD').replace(
                    /[\u0300-\u036f]/g, "").indexOf(value) > -1)

            });

            $("thead").each(function () {
                let trVisiveis = $(this).parent().find('tbody tr').not(':hidden');
                trVisiveis.length > 0 ? $(this).show() : $(this).hide();
            })
        });
    });
// oculta todos menos o DIV selecionado no selector
    $('#select_box').change(function () {
        var select = $(this).find(':selected').text();
        $("div").hide();
        $('#' + select).show();

    }).change();
table {
         font-family: arial, sans-serif;
         border-collapse: collapse;
         width: 100%;
         }
         td, th {
         border: 1px solid #dddddd;
         text-align: left;
         padding: 8px;
         }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="searchInput" placeholder="Digite para filtrar...">
<br />
<br/>
<select id="select_box">
<option>tabelas-1</option>
<option>tabelas-2</option>
</select>
<br />
<br />
<div id="tabelas-1">
<table>
<thead>
  <tr>
    <th>Corpo</th>
    <th>Cores</th>
  </tr>
</thead>
<tbody>
  <tr>
    <td>Cabeca</td>
    <td>Azul</td>
  </tr>
  <tr>
    <td>Braco</td>
    <td>Vermelho</td>
  </tr>
  <tr>
    <td>Perna</td>
    <td>Amarelo</td>
  </tr>
</tbody>
  </table>
  <br/>
  <table>
<thead>
  <tr>
    <th>Carros</th>
    <th>Fabricantes de Motocicletas</th>
  </tr>
</thead>
<tbody>
  <tr>
    <td>Porshe</td>
    <td>Harley</td>
  </tr>
  <tr>
    <td>Mustang</td>
    <td>Yamaha</td>
  </tr>
  <tr>
    <td>Camaro</td>
    <td>Honda</td>
  </tr>
</tbody>
  </table>
  <br/>
  <table>
<thead>
  <tr>
    <th>Locais</th>
    <th>Paises</th>
  </tr>
</thead>
<tbody>
  <tr>
    <td>Aqui</td>
    <td>Quenia</td>
  </tr>
  <tr>
    <td>Ali</td>
    <td>Alemanha</td>
  </tr>
  <tr>
    <td>Acola</td>
    <td>India</td>
  </tr>
</tbody>
  </table>
</div>
<div id="tabelas-2">
<table>
    <thead>
        <tr>
          <th>Display</th>
          <th>Datas comemorativas</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Amoled</td>
          <td>Natal</td>
        </tr>
        <tr>
          <td>LCD</td>
          <td>Páscoa</td>
        </tr>
        <tr>
          <td>OLED</td>
          <td>Ação de graças</td>
        </tr>
      </tbody>
</table>
<br/>
<table>
    <thead>
        <tr>
          <th>Linhas de celulares</th>
          <th>Sistemas Operacionais</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Redmi</td>
          <td>Ubuntu</td>
        </tr>
        <tr>
          <td>Galaxy S</td>
          <td>Mint</td>
        </tr>
        <tr>
          <td>iPhone</td>
          <td>Fedora</td>
        </tr>
      </tbody>
</table>
</div>

Would anyone have any idea how to achieve this? Thank you.

PS: A few attempts, unsuccessful, from the post

Suggestion from Seethec

function hide() {

$('tbody').each(function(){  
  if($(this).not("tr:hidden").length=1)
    {      
      $(this).parent().find("thead").hide();
    }
});
  
  
}

Suggestion from Muse

$('tbody').each(function(){
    if ($(this).has("> tr:visible").length === 0){
        $(this).closest('table').hide();
    }
});

Suggestion from happening

$("#filter").change(function () {// Select changes and filters rows of the different tables.
    var class_to_filter = "." + $(this).val();// I'm accessing rows by class in order to close them, you may access them using some other method.

    $.each($(class_to_filter), function (i, item) {// For each one of them, close and check if you have to close thead as well.
        var $tr = $(item).closest('tr'),
            $tbody = $tr.closest('tbody'),
            $thead = $tbody.siblings('thead'),
            numOfVisibleRows;

        $tr.hide();// Hide row.
        numOfVisibleRows = $('tr:visible', $tbody).length;// Number of sibling rows visible.

        if (!numOfVisibleRows) {// if 0, hide thead.
            $thead.hide();
        }
    });
});

2 answers

1

Do the following:

After running your script to hide columns that do not enter your filter, run another script that will compute if there are any columns visible to that thead.

How to do this?

Search for all the elements that are thead on your page:

$("thead")

Then run a script for each of them through the function each:

$("thead").each(function (){});

Inside the function that will rotate for each thead, to reach their lines of tbody, you need to take the tbody context and use the function parent:

$(this).parent()

That way, we end up getting the table related to that thead. Now let’s look for the lines of tbody, as follows:

$(this).parent().find('tbody tr')

Make a filter that will delete lines that are hidden through the function not:

$(this).parent().find('tbody tr').not(':hidden')

After all, just see how many elements this query returned... and apply its logic to show or not to thead.

An example of this implementation would look like this:

$("thead").each(function (){ 
    let trVisiveis = $(this).parent().find('tbody tr').not(':hidden');
    trVisiveis.length > 0 ? $(this).show() : $(this).hide(); 
})

And your script would look like this:

$(document).ready(function() {
  $("#searchInput").on("keyup", function() {
    var value = $(this).val().toLowerCase();
    $("tbody tr").filter(function() {
      $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)

    });
    
    $("thead").each(function (){ 
        let trVisiveis = $(this).parent().find('tbody tr').not(':hidden');
        trVisiveis.length > 0 ? $(this).show() : $(this).hide(); 
    })
  });
});
  • Good evening, @Bruno Warmling, I updated the posting code to include a <selector>, and during the search, when I type "ca", for example, it filters the lines containing "Cabeca" and "Camaro", but when I change the <selector>, for tables-2, it finds the line containing "Thanksgiving", but does not show the <thead>, and if within 'tables-2', I clear the search bar, and return to 'tables-1' it shows no <thead>. Would you have any idea how to get around this situation?

  • Dude, changing your question doesn’t help anything... my willingness to answer if it ends here.

  • I’m sorry, and thank you.

0


You can change your script like this:

The method parents() is used to select the parent element table to hide, and the element tbody to check if you have the content searched.

$(document).ready(function() {
      $("#searchInput").on("keyup", function() {
        var value = $(this).val().toLowerCase();
        $("tbody tr").filter(function() {
          $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
          // Utilizando parents e selecionando tbody para verificar se tem o texto do input
           $(this).parents("table").toggle($(this).parents("tbody").text().toLowerCase().indexOf(value) > -1)

        });

      });

    });

Browser other questions tagged

You are not signed in. Login or sign up in order to post.