您好,我有一个表,我想使用自定义 JavaScript 下拉过滤器功能来过滤它。它们单独工作时效果很好,但是当我尝试同时使用两者来过滤表内容时,问题就出现了。这是我的 JavaScript 代码:
function searchUserName(input, tableName) {
dropDown(input, tableName, 0);
}
function searchSupervisorName(input, tableName) {
dropDown(input, tableName, 1);
}
var dropdown0 = false;
var dropdown1 = false;
function dropDown(input, tableName, colPos) {
var table = document.getElementById(tableName);
var tr = table.getElementsByTagName("tr");
var userDropdown;
var userNamesArray = [];
if (colPos == 0) {
if (!dropdown0) {
createDropdown();
dropdown0 = true;
}
}
else if (colPos == 1) {
if (!dropdown1) {
createDropdown();
dropdown1 = true;
}
}
function createDropdown() {
if (!userDropdown) {
userDropdown = document.createElement("div");
userDropdown.id = "userDropdown";
userDropdown.className = "dropdown";
userNamesArray = Array.from(tr).map(row => {
var td = row.getElementsByTagName("td")[colPos];
if (td) {
return td.textContent.trim();
}
}).filter(Boolean);
// Sort the user names alphabetically
userNamesArray.sort((a, b) => a.localeCompare(b));
var userNamesSet = new Set(userNamesArray);
// Add "Deselect All" option
var deselectAllContainer = createOptionContainer("Deselect All");
userDropdown.appendChild(deselectAllContainer);
// Add separator line after "Deselect All"
var separator = document.createElement("hr");
userDropdown.appendChild(separator);
userNamesSet.forEach(name => {
var optionContainer = createOptionContainer(name);
userDropdown.appendChild(optionContainer);
});
input.parentNode.insertBefore(userDropdown, input.nextSibling);
} else {
userDropdown.style.display = '';
}
removeOptionFromDropdown("null, null");
}
function removeOptionFromDropdown(optionText) {
if (userDropdown) {
Array.from(userDropdown.children).forEach(optionContainer => {
var optionContainerText = optionContainer.textContent.trim();
if (optionContainerText === optionText) {
userDropdown.removeChild(optionContainer);
}
});
}
}
function createOptionContainer(name) {
var optionContainer = document.createElement("label");
optionContainer.className = "option-container";
if (name === "Deselect All") {
var checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.value = name;
optionContainer.appendChild(checkbox);
optionContainer.classList.add("deselect-option");
} else {
var checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.value = name;
optionContainer.appendChild(checkbox);
}
var optionText = document.createTextNode(name);
optionContainer.appendChild(optionText);
return optionContainer;
}
//showing dropdown onclick event
function showDropdown() {
if (userDropdown) {
userDropdown.style.display = 'block';
}
}
function moveSelectedOptionsToTop() {
var deselectAllContainer = userDropdown.querySelector('input[value="Deselect All"]').parentNode;
var selectedOptions = Array.from(userDropdown.getElementsByClassName("option-container"))
.filter(optionContainer => {
var checkbox = optionContainer.querySelector('input[type="checkbox"]');
return checkbox.checked && checkbox.value !== "Deselect All";
});
if (selectedOptions.length > 0) {
// Sort selected options alphabetically
selectedOptions.sort((a, b) => {
var textA = a.textContent.trim();
var textB = b.textContent.trim();
return textB.localeCompare(textA);
});
// Move all selected options to the top
selectedOptions.forEach(optionContainer => {
userDropdown.insertBefore(optionContainer, userDropdown.firstChild.nextSibling); // Insert after "Deselect All"
});
} else {
// If no options are selected, move "Deselect All" to the top
userDropdown.insertBefore(deselectAllContainer, userDropdown.firstChild.nextSibling);
var allOptions = Array.from(userDropdown.getElementsByClassName("option-container"));
allOptions = allOptions.filter(optionContainer => {
var checkbox = optionContainer.querySelector('input[type="checkbox"]');
return checkbox.value !== "Deselect All";
});
allOptions.sort((a, b) => {
var textA = a.textContent.trim();
var textB = b.textContent.trim();
return textB.localeCompare(textA);
});
// Move all options below "Deselect All"
allOptions.forEach(optionContainer => {
userDropdown.insertBefore(optionContainer, deselectAllContainer.nextSibling);
});
}
}
function filterTable() {
var visibleRows = [];
var searchValue = input.value.trim().toUpperCase();
var selectedusers = Array.from(userDropdown.getElementsByClassName("option-container"))
.filter(optionContainer => {
var checkbox = optionContainer.querySelector('input[type="checkbox"]');
return checkbox.checked && checkbox.value !== "Deselect All";
})
.map(optionContainer => optionContainer.textContent.trim().toUpperCase());
// Include all options if "Deselect All" is checked
var deselectAllCheckbox = userDropdown.querySelector('input[value="Deselect All"]');
if (deselectAllCheckbox && deselectAllCheckbox.checked) {
// Uncheck all other checkboxes and remove selected options
Array.from(userDropdown.getElementsByClassName("option-container")).forEach(function (optionContainer) {
var checkbox = optionContainer.querySelector('input[type="checkbox"]');
checkbox.checked = false;
});
var deselectAllContainer = userDropdown.querySelector('input[value="Deselect All"]').parentNode;
userDropdown.removeChild(deselectAllContainer);
userDropdown.insertBefore(deselectAllContainer, userDropdown.firstChild.nextSibling); // Insert after the separator line
selectedusers = [];
}
// Move "Deselect All" to the top after checking selected options
moveSelectedOptionsToTop();
Array.from(tr).forEach(function (row) {
var td = row.getElementsByTagName("td")[colPos];
if (td) {
var userName = td.textContent.trim().toUpperCase();
var matchesSearch = userName.includes(searchValue);
var isInSelectedusers = selectedusers.length === 0 || selectedusers.includes(userName);
var displayRow = matchesSearch && isInSelectedusers;
row.style.display = displayRow ? "" : "none";
var hasVisibleRowClass = row.classList.contains('visible-row-dp1');
if (colPos == 0) {
if (displayRow && hasVisibleRowClass) {
row.classList.add('visible-row-dp0');
visibleRows.push(row);
} else {
row.classList.remove('visible-row-dp0');
}
}
else if (colPos == 1) {
if (displayRow) {
row.classList.add('visible-row-dp1');
visibleRows.push(row);
} else {
row.classList.remove('visible-row-dp1');
}
}
applyEvenOddStyling(visibleRows);
}
});
// Display "No matching records found" message if no visible rows
var dataTable = $('#maintable').DataTable();
if (visibleRows.length === 0) {
dataTable.rows().nodes().to$().hide(); // Hide all rows
dataTable.draw(); // Redraw the DataTable
$('#maintable tbody').append('<tr class="no-records"><td colspan="colspan">No matching records found</td></tr>'); // Display no records message
} else {
// If there are visible rows, redraw the DataTable and remove the no records message if present
dataTable.rows().nodes().to$().show(); // Show all rows
$('#maintable tbody .no-records').remove(); // Remove no records message if present
dataTable.draw();
}
Array.from(userDropdown.getElementsByClassName("option-container")).forEach(function (optionContainer) {
var optionText = optionContainer.textContent.trim().toUpperCase();
var displayOption = optionText.includes(searchValue);
optionContainer.style.display = displayOption ? "block" : "none";
});
if (colPos == 1) {
var SuperVisorSearchbar = document.getElementById("searchSupervisorInput");
if (selectedusers.length > 0) {
SuperVisorSearchbar.classList.add("selected-search-bar");
} else {
SuperVisorSearchbar.classList.remove("selected-search-bar");
}
} else if (colPos == 0) {
var UserSearchbar = document.getElementById("searchInput");
if (selectedusers.length > 0) {
UserSearchbar.classList.add("selected-search-bar");
} else {
UserSearchbar.classList.remove("selected-search-bar");
}
}
}
function applyEvenOddStyling(rows) {
rows.forEach(function (row, index) {
if (index % 2 === 0) {
row.classList.add('odd-row');
row.classList.remove('even-row');
} else {
row.classList.add('even-row');
row.classList.remove('odd-row');
}
});
}
userDropdown.addEventListener('change', function () {
filterTable();
moveSelectedOptionsToTop();
});
input.addEventListener("keyup", function () {
filterTable();
});
input.addEventListener("click", function () {
showDropdown();
});
document.addEventListener("click", function (event) {
if (userDropdown && !userDropdown.contains(event.target) && event.target !== input) {
userDropdown.style.display = 'none';
}
});
}
由于单个主管可以有多行,因此主管下拉列表将过滤表,可见的行将由用户名下拉列表动态选取。然后,我可以过滤用户名。两个下拉列表中的选项也将是多选的,并且表格将进行相应的过滤。我还打开了一个选项,用户可以在其中输入并过滤任一下拉选项及其所在的单独列。
我承认我使用了大量人工智能来帮助修复我遇到的一些错误,所以我可能无法解释所有内容的推理,但如果您有任何问题,我会尽力而为。
我还没有读完所有的过滤逻辑。我也不知道表数据是什么。
要过滤数组,您可以在数组对象上使用 filter 方法。
假设您有一群学生;
让学生=
[{name: 'std1' , age: 23, sex: 'male'}, {name: 'std2' , age: 29, sex: 'male'}, {name: 'std3' , age: 25, sex: 'female'}]
要仅获取男学生,您可以像这样过滤学生数组:
let maleStudents = students.filter((student) => student.sex == "male")
进一步筛选男学生,只限26岁以下的男学生;
let maleStudentsBelow26 = maleStudents.filter((maleStudent) => maleStudent.age < 26)
或者您可以在学生数组上立即应用性别和年龄过滤器;
let maleStudentsBelow26 = students.filter((student) => student.sex == 'male' && student.age < 26)
然后您可以在表格中显示过滤后的数组。