Совместная корректная работа фильтрации на CSS и поиска на jQuery в HTML-таблице?

Рейтинг: 1Ответов: 1Опубликовано: 14.04.2023

Если воспользоваться поиском, находясь в любой категории (A,B,C,F,G), фильтрация перестаёт работать.

<!DOCTYPE html>
<html lang="en">

<style>
  table {
    width: 100%;
    border-collapse: collapse;
  }
  
  td,
  th {
    padding: 3px;
    border: 1px solid black;
  }
  
  input[type="radio"] {
    position: absolute;
    left: -9999px;
  }
  
  .filters {
    text-align: center;
    margin-bottom: 2rem;
  }
  
  .filters * {
    display: inline-block;
  }
  
  .filters label {
    padding: 0.5rem 1rem;
    margin-bottom: 0.25rem;
    border-radius: 2rem;
    min-width: 50px;
    line-height: normal;
    cursor: pointer;
    transition: all 0.1s;
  }
  
  .filters label:hover {
    background: green;
    color: white;
  }
  
  [value="All"]:checked~.filters [for="All"],
  [value="a"]:checked~.filters [for="a"],
  [value="b"]:checked~.filters [for="b"],
  [value="c"]:checked~.filters [for="c"],
  [value="f"]:checked~.filters [for="f"],
  [value="g"]:checked~.filters [for="g"] {
    background: green;
    color: white;
  }
  
  [value="All"]:checked~.bodyTable [data-category] {
    display: table;
  }
  
  [value="a"]:checked~.responsive-table .bodyTable .cat:not([data-category~="a"]),
  [value="b"]:checked~.responsive-table .bodyTable .cat:not([data-category~="b"]),
  [value="c"]:checked~.responsive-table .bodyTable .cat:not([data-category~="c"]),
  [value="f"]:checked~.responsive-table .bodyTable .cat:not([data-category~="f"]),
  [value="g"]:checked~.responsive-table .bodyTable .cat:not([data-category~="g"]) {
    display: none;
  }
</style>

<body>


  <form>
    <label for="searchname">ПОИСК</label>
    <input type="text" placeholder="Найти..." id="searchname" name="searchname">
  </form>


  <input type="radio" id="All" name="categories" value="All" checked>
  <input type="radio" id="a" name="categories" value="a">
  <input type="radio" id="b" name="categories" value="b">
  <input type="radio" id="c" name="categories" value="c">
  <input type="radio" id="f" name="categories" value="f">
  <input type="radio" id="g" name="categories" value="g">

  <ol class="filters">
    <li><label for="All">All</label></li>
    <li><label for="a">A</label></li>
    <li><label for="b">B</label></li>
    <li><label for="c">C</label></li>
    <li><label for="f">F</label></li>
    <li><label for="g">G</label></li>
  </ol>

  <table class="responsive-table">
    <tbody class="bodyTable">
      <tr class="cat" data-category="a">
        <th>Albania</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="a">
        <th>Andorra</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="b">
        <th>Belarus</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="b">
        <th>Belgium</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="c">
        <th>Croatia</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="c">
        <th>Czechia</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="f">
        <th>Finland</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="f">
        <th>France</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="g">
        <th>Germany</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="g">
        <th>Greece</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>

    </tbody>
  </table>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

  <script>
    $("#searchname").keyup(function() {
      _this = this;
      let count = 0;
      $.each($('table tbody tr.cat').find('th'), function() {
        if ($(this).text().toLowerCase().indexOf($(_this).val().toLowerCase()) === -1) {
          $(this).parent().hide();
        } else {
          count = count + 1;
          $(this).parent().show();
        }
      });
      if (count == 0 && !$('#table tbody').find('tr.no_result').length) {
        $('table tbody').append('<tr class="no_result"><td colspan="3" style="color: #900; font-weight: 700; font-size: 15px; padding: 10px 5px; text-align: center">Ничего не найдено!</td></tr>');
      } else if (count > 0) {
        $('tr.no_result').remove();
      }
    });
  </script>

</body>

</html>

Ответы

▲ 2Принят

При использовании jQuery, такие методы, как hide() и show(), добавляют атрибут style к элементу. Стили заданные в теге <style> или внешнем CSS-файле "перебиваются" inline-стилями, так как последние имеют больший приоритет.

Для того, чтобы избежать такого поведения, следует отказаться от использования методов указанных выше, и управлять видимостью элемента с помощью добавления/удаления класса со свойством display: none:

<!DOCTYPE html>
<html lang="en">

<style>
  table {
    width: 100%;
    border-collapse: collapse;
  }
  
  td,
  th {
    padding: 3px;
    border: 1px solid black;
  }
  
  input[type="radio"] {
    position: absolute;
    left: -9999px;
  }
  
  .filters {
    text-align: center;
    margin-bottom: 2rem;
  }
  
  .filters * {
    display: inline-block;
  }
  
  .filters label {
    padding: 0.5rem 1rem;
    margin-bottom: 0.25rem;
    border-radius: 2rem;
    min-width: 50px;
    line-height: normal;
    cursor: pointer;
    transition: all 0.1s;
  }
  
  .filters label:hover {
    background: green;
    color: white;
  }
  
  [value="All"]:checked~.filters [for="All"],
  [value="a"]:checked~.filters [for="a"],
  [value="b"]:checked~.filters [for="b"],
  [value="c"]:checked~.filters [for="c"],
  [value="f"]:checked~.filters [for="f"],
  [value="g"]:checked~.filters [for="g"] {
    background: green;
    color: white;
  }
  
  [value="All"]:checked~.bodyTable [data-category] {
    display: table;
  }
  
  [value="a"]:checked~.responsive-table .bodyTable .cat:not([data-category~="a"]),
  [value="b"]:checked~.responsive-table .bodyTable .cat:not([data-category~="b"]),
  [value="c"]:checked~.responsive-table .bodyTable .cat:not([data-category~="c"]),
  [value="f"]:checked~.responsive-table .bodyTable .cat:not([data-category~="f"]),
  [value="g"]:checked~.responsive-table .bodyTable .cat:not([data-category~="g"]) {
    display: none;
  }
  
  /* Класс для скрытия элемента */
  .hidden {
    display: none;
  }
</style>

<body>


  <form>
    <label for="searchname">ПОИСК</label>
    <input type="text" placeholder="Найти..." id="searchname" name="searchname">
  </form>


  <input type="radio" id="All" name="categories" value="All" checked>
  <input type="radio" id="a" name="categories" value="a">
  <input type="radio" id="b" name="categories" value="b">
  <input type="radio" id="c" name="categories" value="c">
  <input type="radio" id="f" name="categories" value="f">
  <input type="radio" id="g" name="categories" value="g">

  <ol class="filters">
    <li><label for="All">All</label></li>
    <li><label for="a">A</label></li>
    <li><label for="b">B</label></li>
    <li><label for="c">C</label></li>
    <li><label for="f">F</label></li>
    <li><label for="g">G</label></li>
  </ol>

  <table class="responsive-table">
    <tbody class="bodyTable">
      <tr class="cat" data-category="a">
        <th>Albania</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="a">
        <th>Andorra</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="b">
        <th>Belarus</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="b">
        <th>Belgium</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="c">
        <th>Croatia</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="c">
        <th>Czechia</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="f">
        <th>Finland</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="f">
        <th>France</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="g">
        <th>Germany</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>
      <tr class="cat" data-category="g">
        <th>Greece</th>
        <td>...........................</td>
        <td>...........................</td>
      </tr>

    </tbody>
  </table>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

  <script>
    $("#searchname").keyup(function() {
      _this = this;
      let count = 0;
      $.each($('table tbody tr.cat').find('th'), function() {
        if ($(this).text().toLowerCase().indexOf($(_this).val().toLowerCase()) === -1) {
          $(this).parent().addClass('hidden'); // Скрываем элемент, добавляя класс
        } else {
          count = count + 1;
          $(this).parent().removeClass('hidden'); // Отменяем скрытие элемента, удаляя класс
        }
      });
      if (count == 0 && !$('#table tbody').find('tr.no_result').length) {
        $('table tbody').append('<tr class="no_result"><td colspan="3" style="color: #900; font-weight: 700; font-size: 15px; padding: 10px 5px; text-align: center">Ничего не найдено!</td></tr>');
      } else if (count > 0) {
        $('tr.no_result').remove();
      }
    });
  </script>

</body>

</html>