jQuery / Javascript - 连接两个过滤器 - 仅显示tr与td匹配的数组

时间:2015-11-06 21:22:28

标签: javascript jquery

我的代码目前有两个独立的过滤器,可根据自己的标准过滤表格。

我已经为代码的这个特定部分创建了一个愚蠢的jsfiddle。

我要做的是将这两个过滤器连接在一起。因此,例如,如果选择了“学生”,则按钮提交仅筛选出与数组编号对应的学生,但不会触及任何其他类型的驱动程序。

同样,如果表已经过滤,则选择驱动程序类型仅适用于已过滤的行。

以下是代码:

$('body').on('click', 'button', function() {
    var array = [123, 124, 125, 126];
  var filter = function() {
    var match = false;
    $(this).find('td').each(function() {
      var currentText = $(this).text();
      var filtered = array.filter(function(value) {
        return value == currentText;
      });
      if (filtered.length > 0) {
        match = true;
      }
    });
    return match;
  };
  $('tr').hide().filter(filter).show();
});

                $('#driverTypes').change(function () {
                    var val = parseInt($(this).val(), 10);
                    switch (val) {
                        case 777:
                        $('tr').show();
                        break;
                        case 19:
                        $('tr').hide();
                            $('tr').filter(function() {
                                return $(this).data('filtercriteria') == "Lease Purchase";
                            }).show();
                        break;
                        case 20:
                        $('tr').hide();
                            $('tr').filter(function() {
                                return $(this).data('filtercriteria') == "Company Driver Team";
                            }).show();
                        break;
                        case 21:
                        $('tr').hide();
                            $('tr').filter(function() {
                                return $(this).data('filtercriteria') == "Student";
                            }).show();
                        break;
                        case 22:
                        $('tr').hide();
                            $('tr').filter(function() {
                                return $(this).data('filtercriteria') == "Company Driver";
                            }).show();
                        break;
                    }
                    });

http://jsfiddle.net/m4orLpd3/12/

由于

2 个答案:

答案 0 :(得分:1)

以下代码将执行您想要的操作。它将当前过滤器保留在全局对象中。每列存储一个单独的过滤器,并在执行过滤器时将两者合并:

// List of zip codes of interest
var zipFinal2 = [123, 124, 125, 126];
// Variable to retain currently applied filter:
// An array with a filter per column. 
var columnFilters = [{}, {}, {}, {}]; // add as many as you have columns
var zipColumnNo = 0;
var driverColumnNo = 1;

function applyFilter(filter) {
    $('tr').each(function() {
        $(this).toggle( // show when no TD has mismatching content
            !$(this).find('td').filter(function(idx) {
                // return true when content does not match the filter on this column
                return filter[idx] && Object.keys(filter[idx]).length &&
                                !filter[idx].hasOwnProperty($(this).text());
            }).length
        );
    });
}

$('#zipButton').click(function() {
    // toggle first-column filter:
    var newFilter = {};
    if (!Object.keys(columnFilters[zipColumnNo]).length) {
        // turn zipFinal2[] into object with values as properties for faster lookup
        zipFinal2.forEach(function(zip) {
            newFilter[zip] = 1;
        });
    }
    columnFilters[zipColumnNo] = newFilter;
    applyFilter(columnFilters);
});

$('#driverTypes').change(function () {
    columnFilters[driverColumnNo] =  {}; // no filter
    if (this.selectedIndex) {
         // filter second column on text in selected option
         columnFilters[driverColumnNo][$(this.options[this.selectedIndex]).text()] = 1;
    }
    applyFilter(columnFilters);
});

// reset filter on page load:
$(function() {
    $('#driverTypes').val(777);
});

查看fiddle

作为奖励,此代码还将“提交”按钮(奇怪名称)视为切换:当您再次单击该列时,该列上的过滤器将被删除。

刷新页面时,某些浏览器会在下拉列表框中保留上次选择的值。所以我最后添加了重置它所需的代码。否则情况不一致:表格的所有条目都可见,但在下拉列表中选择了过滤器。

只要使用其中一个控件,代码就会调用applyFilter方法,然后在所有toggle元素上调用tr方法。参数决定了可见性。仅当td个元素与过滤器不匹配时,才会设置可见性。当{且仅当为该列定义过滤器(与空对象不同)时,td不匹配,并且td中的值不是该过滤器对象的属性。

如果您希望仅在ECMAScript 6兼容浏览器中运行,则可以使用Set代替对象属性来存储过滤器值,从而使代码更好。

此外,如果您希望使用更多表进行过滤,可以通过将table标记传递给applyFilter函数并将columnFilters数组存储在{{1}中来使其更通用。 } tag的数据属性。

答案 1 :(得分:0)

修改了您的过滤方法。使用$('tr:visible')而不是$('tr')。 jQuery hide()相当于css(“display”,“none”),它被认为是可见的,因为它们仍然占用了布局中的空间。

var filter = function() {
    var text = $(this).text();
    var result = array.filter(function(id){
        return ((text.indexOf(id) >= 0) ? true : false);
    });
    return !result.length;
};
$('tr:visible').filter(filter).hide();

http://jsfiddle.net/m4orLpd3/13/