有没有办法让这两个下拉菜单“协同工作”来过滤表格

问题描述 投票:0回答:1

您好,我有一个表,我想使用自定义 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';
        }
    });

    }

由于单个主管可以有多行,因此主管下拉列表将过滤表,可见的行将由用户名下拉列表动态选取。然后,我可以过滤用户名。两个下拉列表中的选项也将是多选的,并且表格将进行相应的过滤。我还打开了一个选项,用户可以在其中输入并过滤任一下拉选项及其所在的单独列。

我承认我使用了大量人工智能来帮助修复我遇到的一些错误,所以我可能无法解释所有内容的推理,但如果您有任何问题,我会尽力而为。

javascript dropdown multi-select
1个回答
0
投票

我还没有读完所有的过滤逻辑。我也不知道表数据是什么。

要过滤数组,您可以在数组对象上使用 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)

然后您可以在表格中显示过滤后的数组。

© www.soinside.com 2019 - 2024. All rights reserved.