Фильтрация флажков и таблиц с использованием Javascript

Я работал с html-таблицей, в которой мне нужно отфильтровать две вещи. Во-первых, есть таблица с данными, и когда мы нажимаем на заголовок столбца, отображается сетка фильтров, в которой мы видим текстовое поле, а под ним есть флажки. Я ищу решение, например, когда мы печатаем в текстовом поле, флажки будут фильтроваться по вводу текста, и после этого нажмите кнопку «ОК», таблица будет отфильтрована.

Вот что происходит: когда я набираю любую букву в текстовое поле, отображаются флажки со значением, содержащим эту букву, и после этого я нажимаю кнопку «ОК», отмеченные элементы будут отображаться в сетке ниже.

Теперь ничего не происходит. Когда мы щелкнем по столбцу заголовка, отобразится небольшая сетка фильтра, как показано на изображении ниже. При вводе любого символа в текстовое поле флажки, содержащие значение текста текстового поля, будут отображаться, другие флажки будут скрыты.

После этого, если мы установим какие-либо флажки, приведенная ниже большая сетка таблицы будет отфильтрована, как фильтр Excel. Я хочу иметь эти две функции в этом решении.

Код похож на показанный ниже

$(document).ready(function() {
  $("table th").click(function() {
    showFilterOption(this);
  });
});

var arrayMap = {};

function showFilterOption(tdObject) {
  var filterGrid = $(tdObject).find(".filter");
  if (filterGrid.is(":visible")) {
    filterGrid.hide();
    return;
  }
  $(".filter").hide();

  var index = 0;
  filterGrid.empty();
  var allSelected = true;

  filterGrid.append('<div><input id = "searchtext" type = "text" placeholder = "Search" style = "width: 70% !important"></div>');

  filterGrid.append('<div><input id = "all" type = "checkbox" style = "width: 10% !important" checked>All</div>');

  var $rows = $(tdObject).parents("table").find("tr");
  var values = [];

  $rows.each(function(ind, ele) {
    if (ind > 0) {
      var currentTd = $(ele).children()[$(tdObject).attr("index")];
      if (!values.includes(currentTd.innerHTML)) {
        values.push(currentTd.innerHTML);
        var div = document.createElement("div");
        div.classList.add("grid-item");
        var str = $(ele).is(":visible") ? "checked" : "";
        if ($(ele).is(":hidden")) {
          allSelected = false;
        }
        div.innerHTML = '<br><input type = "checkbox" ' + str + " >" + currentTd.innerHTML;
        filterGrid.append(div);
        arrayMap[index] = ele;
        index++;
      }
    }
  });

  if (!allSelected) {
    filterGrid.find("#all").removeAttr("checked");
  }

  filterGrid.append('<div style = "text-align: center"><input id = "close" type = "button" value = "Close" style = "width: 40%"/><input id = "ok" type = "button" value = "Ok" style = "width: 40%"/></div>');
  filterGrid.show();

  var $stxt = filterGrid.find("input[type='text']");
  var $closeBtn = filterGrid.find("#close");
  var $okBtn = filterGrid.find("#ok");
  var $checkElems = filterGrid.find("input[type='checkbox']");
  var $gridItems = filterGrid.find(".grid-item");
  var $all = filterGrid.find("#all");

  $closeBtn.click(function() {
    filterGrid.hide();
    return false;
  });

  $("#searchtext").on('input', function() {

  });

  $okBtn.click(function() {
    filterGrid.find(".grid-item").each(function(ind, ele) {
      if ($(ele).find("input").is(":checked")) {
        $(arrayMap[ind]).show();
      } else {
        $(arrayMap[ind]).hide();
      }
    });

    filterGrid.hide();
    return false;
  });

  $checkElems.click(function(event) {
    event.stopPropagation();
  });

  $gridItems.click(function(event) {
    var chk = $(this).find("input[type='checkbox']");
    $(chk).prop("checked", !$(chk).is(":checked"));
  });

  $all.change(function() {
    var chked = $(this).is(":checked");
    filterGrid.find(".grid-item [type='checkbox']").prop("checked", chked);
  });

  filterGrid.click(function(event) {
    event.stopPropagation();
  });

  return filterGrid;
}
table {
  margin: 0 auto;
  margin-top: 20px;
  width: 100%;
  position: relative;
  overflow: auto;
  overflow-y: overlay;
}

th,
thead {
  position: sticky;
  top: 0;
  border: 1px solid #dddddd;
  background-color: #1f2d54;
  text-align: center;
  color: white;
  table-layout: fixed;
  word-break: break-word;
  height: 45px;
}

.filter {
  position: absolute;
  width: 20vw;
  height: 40vh;
  display: none;
  text-align: left;
  font-size: small;
  z-index: 9999;
  overflow: auto;
  background: #ffffff;
  color: #1f2d54;
  border: 1px solid #dddddd;
}

.filter input {
  margin: 5px !important;
  padding: 0 !important;
  width: 10%;
}

input.largerCheckbox {
  margin: 5px;
  padding: 0;
  width: 13px;
  height: 13px;
}

input[type='checkbox'] {
  vertical-align: middle;
  position: relative;
  bottom: 1px;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<table style='padding: 8px;'>
  <tr>
    <th index=0>
      Email
      <div class = "filter"></div>
    </th>
    <th index=1>
      Name
      <div class = "filter"></div>
    </th>
    <th index=2>
      Level
      <div class = "filter"></div>
    </th>
    <th index=3>
      Location
      <div class = "filter"></div>
    </th>
  </tr>

  <tr>
    <td>Email 1</td>
    <td>Name 1</td>
    <td>Level 1</td>
    <td>Location 2</td>
  </tr>
  <tr>
    <td>Email 1</td>
    <td>Name 1</td>
    <td>Level 1</td>
    <td>Location 1</td>
  </tr>
  <tr>
    <td>Email 2</td>
    <td>Name 1</td>
    <td>Level 2</td>
    <td>Location 1</td>
  </tr>
  <tr>
    <td>Email 3</td>
    <td>Name 2</td>
    <td>Level 2</td>
    <td>Location 1</td>
  </tr>
  <tr>
    <td>Email 3</td>
    <td>Name 3</td>
    <td>Level 1</td>
    <td>Location 2</td>
  </tr>
  <tr>
    <td>Email 1</td>
    <td>Name 2</td>
    <td>Level 2</td>
    <td>Location 1</td>
  </tr>
</table>

Ваш вопрос неясен; почему ваш код не работает должным образом?

mykaf 11.07.2024 17:20

Вы поделились тем, над чем работаете, но.... в чем вопрос?

trincot 11.07.2024 17:23

@trincot я отредактировал вопрос и добавил изображение

KitKat 11.07.2024 17:46

Я исправил большинство ваших вопросов в stackoverflow.com/questions/78731609/… — почему бы не использовать мой измененный код в качестве основы?

mplungjan 11.07.2024 18:36

@mplungjan извини, братан. Это не соответствует нашим потребностям. Наш менеджер действительно хочет этого требования. Пожалуйста, помогите мне. Мне нужно 2 вещи. 1. отфильтруйте небольшую сетку фильтров в столбце заголовка и 2. отфильтруйте основную большую сетку в соответствии с установленным флажком. Мое понимание было неправильным, когда мой менеджер сказал мне. Пожалуйста помоги.

KitKat 11.07.2024 18:45

Мой скрипт фильтрует флажки, так что это касается 1, не так ли?

mplungjan 11.07.2024 23:28

@mplungjan Здесь каждый флажок находится внутри каждого элемента div. Так что этот скрипт не будет фильтровать флажки здесь. Попробовал по твоему сценарию. Но это не работает. Пожалуйста, помогите, сэр

KitKat 12.07.2024 10:39

Я. Это большая работа. Я сохраню то, что у меня есть на данный момент

mplungjan 12.07.2024 12:47
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
8
93
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Работа в процессе. Я добавил свое предыдущее решение и работаю над переключением строк таблицы.

$(document).ready(function() {
  $("table th").click(function() {
    showFilterOption(this);
  });
});

var arrayMap = {};

function showFilterOption(tdObject) {
  var filterGrid = $(tdObject).find(".filter");
  if (filterGrid.is(":visible")) {
    filterGrid.hide();
    return;
  }
  $(".filter").hide();

  var index = 0;
  filterGrid.empty();
  var allSelected = true;

  filterGrid.append('<div><input id = "searchtext" type = "text" placeholder = "Search" style = "width: 70% !important"></div>');

  filterGrid.append('<div><input id = "all" type = "checkbox" style = "width: 10% !important" checked>All</div>');

  var $rows = $(tdObject).parents("table").find("tr");
  var values = [];

  // this is not elegant and does not work as expected.
  $rows.each(function(ind, ele) {
    if (ind > 0) {
      var currentTd = $(ele).children()[$(tdObject).attr("index")];
      var val = currentTd.innerHTML;
      if (!values.includes(val)) {
        values.push(currentTd.innerHTML);
        var div = document.createElement("div");
        div.classList.add("grid-item");
        var str = $(ele).is(":visible") ? "checked" : "";
        if ($(ele).is(":hidden")) {
          allSelected = false;
        }
        div.innerHTML = `<br><label><input type = "checkbox" value = "${val}" ${str}>${val}</label>`;
        filterGrid.append(div);
        arrayMap[index] = ele; // this does not work as expected
        index++;
      }
    }
  });

  if (!allSelected) {
    filterGrid.find("#all").removeAttr("checked");
  }

  filterGrid.append('<div style = "text-align: center"><input id = "close" type = "button" value = "Close" style = "width: 40%"/><input id = "ok" type = "button" value = "Ok" style = "width: 40%"/></div>');
  filterGrid.show();

  var $stxt = filterGrid.find("input[type='text']");
  var $closeBtn = filterGrid.find("#close");
  var $okBtn = filterGrid.find("#ok");
  var $checkElems = filterGrid.find("input[type='checkbox']");
  var $gridItems = filterGrid.find(".grid-item");
  var $all = filterGrid.find("#all");
  var $search = $("#searchtext");

  $closeBtn.click(function() {
    filterGrid.hide();
    return false;
  });

  const checkSearch = function(inputValue) {
    inputValue = inputValue.toLowerCase();
    //let allChecked = $('#all').is(':checked');
    $checkElems.each(function() {
      const val = $(this).val().toLowerCase();
      //$(this).closest('.grid-item').toggle(allChecked || val.includes(inputValue));
      $(this).closest('.grid-item').toggle(val.includes(inputValue));
    });
  };

  $search.on('input', function() {
    checkSearch($(this).val())
  });
  $okBtn.click(function(e) {
    e.preventDefault();
    const map = $checkElems
      .filter(function() { return this.checked;})
      .map(function() { return this.value.toLowerCase(); })
      .get();

    $("table tbody tr").each(function() {
      let $row = $(this);
      let found = $row.find('td').toArray().some(td => {
        let cellText = $(td).text().trim().toLowerCase();
        let matchFound = map.some(mapItem => cellText.includes(mapItem)); // Check if any map item is a substring of cellText
        // console.info(map, cellText, matchFound);
        return matchFound;
      });
      // let alwaysShow = map.length > 0 && map[0] === 'on';
      // console.info(alwaysShow || found, $row.text())
      //$row.toggle(alwaysShow || found);
      $row.toggle(found);

    });
    filterGrid.hide();
  });



  $checkElems.click(function(event) {
    event.stopPropagation();
  });

  const $allChecks = $('.filter div.grid-item input[type=checkbox]')
  .on('click', function() {
    const checked = $allChecks.filter(function() { return this.checked }).get();
    console.info(checked.length,$allChecks.length)
    $all.prop('checked',checked.length === $allChecks.length);
  });

  $all.on('click', function() {
    var chked = $(this).is(":checked");
    filterGrid.find("[type=checkbox]").prop("checked", chked);
    checkSearch($search.val());
  });

  filterGrid.click(function(event) {
    event.stopPropagation();
  });

  return filterGrid;
}
table {
  margin: 0 auto;
  margin-top: 20px;
  width: 100%;
  position: relative;
  overflow: auto;
  overflow-y: overlay;
}

th,
thead {
  position: sticky;
  top: 0;
  border: 1px solid #dddddd;
  background-color: #1f2d54;
  text-align: center;
  color: white;
  table-layout: fixed;
  word-break: break-word;
  height: 45px;
}

.filter {
  position: absolute;
  width: 20vw;
  height: 40vh;
  display: none;
  text-align: left;
  font-size: small;
  z-index: 9999;
  overflow: auto;
  background: #ffffff;
  color: #1f2d54;
  border: 1px solid #dddddd;
}

.filter input {
  margin: 5px !important;
  padding: 0 !important;
  width: 10%;
}

input.largerCheckbox {
  margin: 5px;
  padding: 0;
  width: 13px;
  height: 13px;
}

input[type='checkbox'] {
  vertical-align: middle;
  position: relative;
  bottom: 1px;
}


/* For Stackoverflow console */

.as-console-wrapper {
  height: 40px
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<table style='padding: 8px;'>
  <thead>
    <tr>
      <th index=0>
        Email
        <div class = "filter"></div>
      </th>
      <th index=1>
        Name
        <div class = "filter"></div>
      </th>
      <th index=2>
        Level
        <div class = "filter"></div>
      </th>
      <th index=3>
        Location
        <div class = "filter"></div>
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Email 1</td>
      <td>Name 1</td>
      <td>Level 1</td>
      <td>Location 2</td>
    </tr>
    <tr>
      <td>Email 1</td>
      <td>Name 1</td>
      <td>Level 1</td>
      <td>Location 1</td>
    </tr>
    <tr>
      <td>Email 2</td>
      <td>Name 1</td>
      <td>Level 2</td>
      <td>Location 1</td>
    </tr>
    <tr>
      <td>Email 3</td>
      <td>Name 2</td>
      <td>Level 2</td>
      <td>Location 1</td>
    </tr>
    <tr>
      <td>Email 3</td>
      <td>Name 3</td>
      <td>Level 1</td>
      <td>Location 2</td>
    </tr>
    <tr>
      <td>Email 1</td>
      <td>Name 2</td>
      <td>Level 2</td>
      <td>Location 1</td>
    </tr>
  </tbody>
</table>

Огромное спасибо. Одно из предложений: при вводе текста в текстовое поле фильтрация не работает, если флажки установлены. Я жду вашего полного решения.

KitKat 12.07.2024 13:46

Мне потребовалась целая вечность, чтобы понять, что ваша коллекция — это не настоящие строки таблицы. Я добавил thead и tbody и получил строки при нажатии кнопки «ОК».

mplungjan 12.07.2024 14:12

Большое спасибо, сэр. Вы спасли меня. Пожалуйста, исправьте проблему невозможности фильтрации при вводе текста в текстовое поле. Фильтр не работает, если установлены флажки. Пожалуйста помоги.

KitKat 12.07.2024 14:25

Я улучшил это. Я остановлю это сейчас. Я потратил слишком много времени, и было бы проще написать с нуля.

mplungjan 12.07.2024 14:47

Другие вопросы по теме