【问题标题】:How to use JQUERY to filter table rows dynamically using multiple form inputs如何使用 JQUERY 使用多个表单输入动态过滤表行
【发布时间】:2011-01-13 00:03:20
【问题描述】:

我正在显示一个包含多行和多列的表格。我正在使用一个名为 uiTableFilter 的 JQUERY 插件,它使用文本字段输入并根据您提供的输入过滤(显示/隐藏)表格行。您所做的只是指定要过滤的列,它将仅显示在该列中具有文本字段输入的行。简单且工作正常。

我想添加一个 SECOND 文本输入字段,以帮助我进一步缩小结果范围。因此,例如,如果我有一个 PETS 表,其中一列是 petType,一列是 petColor——我可以在第一个文本字段中输入 CAT,以显示所有猫,然后在第二个文本字段中,我可以输入黑色,结果表将仅显示找到 BLACK CATS 的行。基本上是一个子集。

这是我正在使用的 JQUERY:

   $("#typeFilter").live('keyup', function() {

    if ($(this).val().length > 2 || $(this).val().length == 0)
  {
                var newTable = $('#pets');
  $.uiTableFilter( theTable, this.value, "petType" );
  } 

   }) // end typefilter

   $("#colorFilter").live('keyup', function() {
    if ($(this).val().length > 2 || $(this).val().length == 0)
  {
  var newTable = $('#pets');
  $.uiTableFilter( newTable, this.value, "petColor" );

  } 

   }) // end colorfilter

问题是,我可以使用一个过滤器,它会显示正确的表格行子集,但是当我为另一个过滤器提供输入时,它似乎无法识别前一个过滤器剩余的可见表格行列,但它似乎对原始表进行了全新的过滤。如果应用一个过滤器后返回 10 行,则第二个过滤器应仅适用于 THOSE 10 行。我已经尝试过 LIVE 和 BIND,但无法正常工作。

谁能阐明我哪里出错了?谢谢!

【问题讨论】:

    标签: jquery-plugins dynamic jquery


    【解决方案1】:

    uiTableFilter 插件不支持您尝试执行的操作。快速浏览一下源代码就会发现:

    elems.each(function(){
        var elem = jQuery(this);
        jQuery.uiTableFilter.has_words(getText(elem), words, false)
            ? matches(elem)
            : noMatch(elem);
    });
    

    这扩展为(基本上)这个:

    elems.each(function(){
        var elem = jQuery(this);
        jQuery.uiTableFilter.has_words(getText(elem), words, false)
            ? elem.show()
            : elem.hide();
    });
    

    所以它所做的只是遍历所有行,.show() 匹配的行,.hide() 不匹配的行; uiTableSorter 不关注行的当前显示/隐藏状态,也无法告诉它过滤多个列。

    如果你真的需要你想要的功能,那么你可以修改插件的行为(代码非常小而且简单)或者只写你自己的。这是一个精简版,支持多个过滤器,是一个比 uiTableFilter 更传统的 jQuery 插件:

    (function($) {
        $.fn.multiFilter = function(filters) {
            var $table = $(this);
            return $table.find('tbody > tr').each(function() {
                var tr = $(this);
    
                // Make it an array to avoid special cases later.
                if(!$.isArray(filters))
                    filters = [ filters ];
    
                howMany = 0;
                for(i = 0, f = filters[0]; i < filters.length; f = filters[++i]) {
                    var index = 0;
                    $table.find('thead > tr > th').each(function(i) {
                        if($(this).text() == f.column) {
                            index = i;
                            return false;
                        }
                    });
                    var text = tr.find('td:eq(' + index + ')').text();
                    if(text.toLowerCase().indexOf(f.word.toLowerCase()) != -1)
                        ++howMany;
                }
                if(howMany == filters.length)
                    tr.show();
                else
                    tr.hide();
            });
        };
    })(jQuery);
    

    我会将错误处理和性能作为练习留给读者,这只是一个说明性示例,我不想妨碍您的学习。你可以这样连接它:

    $('#type').keyup(function() {
        $('#leeLooDallas').multiFilter({ column: 'petType', word: this.value });
    });
    $('#color').keyup(function() {
        $('#leeLooDallas').multiFilter([
            { column: 'petType',  word: $('#type').val() },
            { column: 'petColor', word: this.value       }
        ]);
    });
    

    这是一个活生生的例子(假设您要在“颜色”之前的“类型”中输入一些内容):http://jsfiddle.net/ambiguous/hdFDt/1/

    【讨论】:

    • 哇,mu,这太棒了。在 Fiddle 上尝试了你的代码,它可以工作,所以我会从那里修改它。非常感谢。
    • 如何使这段代码工作,这样无论用户输入“类型”还是“颜色”都不会产生影响?
    • @indiehacker:您可能需要更改 f(text.toLowerCase().indexOf(f.wo.... 部分以同时检查多个位置,但这将是一个全新的问题。
    • 你是神!非常感谢。
    猜你喜欢
    • 2015-08-15
    • 2023-03-31
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 2020-02-08
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多