Я работал с 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>
Вы поделились тем, над чем работаете, но.... в чем вопрос?
@trincot я отредактировал вопрос и добавил изображение
Я исправил большинство ваших вопросов в stackoverflow.com/questions/78731609/… — почему бы не использовать мой измененный код в качестве основы?
@mplungjan извини, братан. Это не соответствует нашим потребностям. Наш менеджер действительно хочет этого требования. Пожалуйста, помогите мне. Мне нужно 2 вещи. 1. отфильтруйте небольшую сетку фильтров в столбце заголовка и 2. отфильтруйте основную большую сетку в соответствии с установленным флажком. Мое понимание было неправильным, когда мой менеджер сказал мне. Пожалуйста помоги.
Мой скрипт фильтрует флажки, так что это касается 1, не так ли?
@mplungjan Здесь каждый флажок находится внутри каждого элемента div. Так что этот скрипт не будет фильтровать флажки здесь. Попробовал по твоему сценарию. Но это не работает. Пожалуйста, помогите, сэр
Я. Это большая работа. Я сохраню то, что у меня есть на данный момент
Работа в процессе. Я добавил свое предыдущее решение и работаю над переключением строк таблицы.
$(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>
Огромное спасибо. Одно из предложений: при вводе текста в текстовое поле фильтрация не работает, если флажки установлены. Я жду вашего полного решения.
Мне потребовалась целая вечность, чтобы понять, что ваша коллекция — это не настоящие строки таблицы. Я добавил thead и tbody и получил строки при нажатии кнопки «ОК».
Большое спасибо, сэр. Вы спасли меня. Пожалуйста, исправьте проблему невозможности фильтрации при вводе текста в текстовое поле. Фильтр не работает, если установлены флажки. Пожалуйста помоги.
Я улучшил это. Я остановлю это сейчас. Я потратил слишком много времени, и было бы проще написать с нуля.
Ваш вопрос неясен; почему ваш код не работает должным образом?