如何使用 JQUERY 使用多个表单输入动态过滤表行

发布于 2024-10-11 21:35:55 字数 1027 浏览 3 评论 0原文

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

我想添加第二个文本输入字段,这将帮助我进一步缩小结果范围。因此,例如,如果我有一个 PETS 表,其中一列是 petType,一列是 petColor——我可以在第一个文本字段中输入 CAT,以显示所有猫,然后在第二个文本字段中,我可以输入 black,结果表将仅显示找到 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 行,则第二个过滤器应仅适用于这 10 行。我尝试过 LIVE 和 BIND,但不起作用。

谁能告诉我我哪里出错了?谢谢!

I'm displaying a table with multiple rows and columns. I'm using a JQUERY plugin called uiTableFilter which uses a text field input and filters (shows/hides) the table rows based on the input you provide. All you do is specify a column you want to filter on, and it will display only rows that have the text field input in that column. Simple and works fine.

I want to add a SECOND text input field that will help me narrow the results down even further. So, for instance if I had a PETS table and one column was petType and one was petColor -- I could type in CAT into the first text field, to show ALL cats, and then in the 2nd text field, I could type black, and the resulting table would display only rows where BLACK CATS were found. Basically, a subset.

Here is the JQUERY I'm using:

   $("#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

Problem is, I can use one filter, and it will display the correct subset of table rows, but when I provide input for the other filter, it doesn't seem to recognize the visible table rows that are remaining from the previous column, but instead it appears that it does an entirely new filtering of the original table. If 10 rows are returned after applying one filter, the 2nd filter should only apply to THOSE 10 rows. I've tried LIVE and BIND, but not working.

Can anyone shed some light on where I'm going wrong? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

(り薆情海 2024-10-18 21:35:55

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/ambiguously/hdFDt/1/

The uiTableFilter plugin doesn't support what you're trying to do. A quick look at the source reveals this:

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

and that expands to (essentially) this:

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

So all it does is spin through all the rows, .show() those that match, and .hide() those that don't; uiTableSorter doesn't pay attention to the current shown/hidden state of the rows and there's no way to tell it to filter on multiple columns.

If you really need your desired functionality then you can modify the plugin's behavior (the code is pretty small and simple) or just write your own. Here's a stripped down and simplified version that supports multiple filters and is a more conventional jQuery plugin than uiTableFilter:

(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);

I'll leave error handling and performance as an exercise for the reader, this is just an illustrative example and I wouldn't want to get in the way of your learning. You could wire it up something like this:

$('#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       }
    ]);
});

And here's a live example (which assumes that you're going to enter something in "type" before "color"): http://jsfiddle.net/ambiguous/hdFDt/1/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文