javascript - html表格的多个过滤器

标签 javascript jquery css html-table

我的 View 中有一个 html 表,我想使用多个过滤器进行过滤。在本例中,我有 3 个过滤器,但我可以有更多。

这里是代码的一小部分,用来说明问题

$(document).ready(function () {
   
   

    $('#datefilterfrom').on("change", filterRows);
    $('#datefilterto').on("change", filterRows);
    $('#projectfilter').on("change", filterProject);
    $('#servicefilter').on("change", filterService);
});

function filterRows() {
    var from = $('#datefilterfrom').val();
    var to = $('#datefilterto').val();

    if (!from && !to) { // no value for from and to
        return;
    }

    from = from || '1970-01-01'; // default from to a old date if it is not set
    to = to || '2999-12-31';

    var dateFrom = moment(from);
    var dateTo = moment(to);

    $('#testTable tr').each(function (i, tr) {
        var val = $(tr).find("td:nth-child(2)").text();
        var dateVal = moment(val, "DD/MM/YYYY");
        var visible = (dateVal.isBetween(dateFrom, dateTo, null, [])) ? "" : "none"; // [] for inclusive
        $(tr).css('display', visible);
    });
}
function filterProject() {
    let dumb = this.options.selectedIndex;
    dumb = this.options[dumb].innerHTML;
    var filter, table, tr, td, i;
    filter = dumb.toUpperCase();
    table = document.getElementById("testTable");
    tr = table.getElementsByTagName("tr");
    for (i = 0; i < tr.length; i++) {
        td = tr[i].getElementsByTagName("td")[2];
        if (td) {
            if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
                tr[i].style.display = "table-row";
            } else {
                tr[i].style.display = "none";
            }
        }

    }
}

function filterService() {
    let dumb = this.options.selectedIndex;
    dumb = this.options[dumb].innerHTML;
    var filter, table, tr, td, i;
    filter = dumb.toUpperCase();
    table = document.getElementById("testTable");
    tr = table.getElementsByTagName("tr");
    for (i = 0; i < tr.length; i++) {
        td = tr[i].getElementsByTagName("td")[3];
        if (td) {
            if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
                tr[i].style.display = "table-row";
            } else {
                tr[i].style.display = "none";
            }
        }

    }
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/moment/moment/2.2.1/min/moment.min.js"></script>
   <div class="row">
        <div class="col-md-3">
            <h4>Date from</h4>
            <input type="date" class="form-control" id="datefilterfrom" data-date-split-input="true">
        </div>
        <div class="col-md-3">
            <h4>Date to</h4>
            <input type="date"  class="form-control" id="datefilterto" data-date-split-input="true">
        </div>
        <div class="col-md-2">
            <h4>Project</h4>
           <select id="projectfilter" name="projectfilter" class="form-control"><option value="1">Test project</option><option value="2">Test2</option></select>
        </div>
     <div class="col-md-2">
            <h4>Service</h4>
           <select id="servicefilter" name="servicefilter" class="form-control"><option value="1">Test service</option><option value="2">Test2 service</option></select>
        </div>
    </div>
<table id="testTable" class="table">
            <thead>
                <tr>
                    <th scope="col">#</th>
                    <th scope="col">Date</th>
                    <th scope="col">Project</th>
                   <th scope="col">Service</th>
               
                </tr>
            </thead>
            <tbody id="report">
              <tr>
                <td class="proposalId">9</td><td> 17/07/2018</td> <td> Test project</td><td> Test service</td>
              </tr>
              <tr><td class="proposalId">8</td><td> 18/07/2018</td><td> Test project</td><td> Test2  service</td></tr>
              <tr><td class="proposalId">7</td><td> 17/07/2018</td><td> Test2</td><td> Test2 service</td></tr>
              <tr style=""><td class="proposalId">3</td><td> 19/07/2018</td><td> Test2</td><td> Test service</td></tr>
              
    </tbody>
        </table>

如果你像这样设置过滤器 enter image description here

你会得到这个

enter image description here

这是不对的。因为我只需要测试2个元素,所以一行。

我的问题在哪里,我该如何解决?

这里是代码的codepen

https://codepen.io/suhomlineugene/pen/pZqyEN

最佳答案

现在每个过滤器都有一个单独的函数,每个过滤器都会忽略其他过滤器的设置并覆盖它们的结果。

相反,您需要将它们合并到一个函数中,该函数将所有过滤器考虑在内。

与其将所有代码真正组合成一个难以维护的复杂函数,一种方法是使用一个使所有行可见的主函数,然后依次调用每个其他过滤器函数;这些函数只会隐藏它们过滤掉的行。最后剩下可见的是与所有过滤器选择匹配的行。

$(document).ready(function () {
    $('#datefilterfrom, #datefilterto, #projectfilter, #servicefilter').on("change", filterAll);
});

function filterAll() {
    $('#testTable tr').show();
    filterRows();
    filterProject();
    filterService();
    // ...etc
}

function filterRows() {  // repeat for filterProject(), filterService(), etc
    // same as your original code, except only hide non-matching rows, do not
    // show matching rows (because filterAll() already took care of that, and
    // you don't want to undo what other filters may have hidden.)
}

(或者,不是显示所有内容然后让每个单独的过滤器逐渐隐藏行,您可以让 filterAll() 构建所有行的数组,将其传递给将从中删除元素的单独过滤器函数,然后使用一次显示/隐藏适当行的最终结果。)

关于javascript - html表格的多个过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51772619/

相关文章:

javascript - 侧边栏动画延迟

jquery - 使用 jquery 按需 javascript 调用窗口卸载

css - 如何让 <li> 在 jQuery 加载前正确显示?

javascript - 为什么这个 Javascript 没有添加到 HTML 中

javascript - 从 jstree 获取选定节点时出错

javascript - 下载链接点击浏览器打开下载窗口

javascript - HTML 表格中的重叠行

javascript - 在 JavaScript 中更新具有多行的两个字段

javascript - Raphael.js 导致 "Forced synchronous layout"瓶颈

javascript - Protractor 和棘手的 Accordion