如何使用 jQuery 将多个过滤器组合在一起以过滤任务行? [英] How to combine multiple FIlters together to filter Task Rows using jQuery?

查看:14
本文介绍了如何使用 jQuery 将多个过滤器组合在一起以过滤任务行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用 HTML 和 jQuery 编写了一个基本的示例任务列表.我已将一些 on change 事件附加到我的 Filter DropDown Selection Fields

演示:

<小时>

更新测试 2

经过一番思考,我想也许我需要将所有当前过滤器值存储到变量中,然后在每个 change 事件上而不是这样:

 return $(this).data('milestone') != taskMilestone;

它应该更像这样......

 return $(this).data('milestone') != taskMilestone&&$(this).data('priority') != taskPriority&&$(this).data('tags') != taskTags&&.... 适用于所有过滤器;

这听起来对吗?

没关系,只是尝试了这个没有运气!

解决方案

你在第二次测试中很接近.这是一个工作演示:

http://codepen.io/luciopaiva/pen/oXpzGw?editors=101

我稍微重构了您的代码并将逻辑集中在 updateFilters() 周围,每次发生任何更改事件时都会调用它.它首先假设应该显示每一行,然后针对与默认值不同的每个过滤器进行测试(无论是Any"、None"还是 undefined).

顺便说一下,如果你能把data-user-assigned改成data-user,这里有一个稍微改进的代码,大大减少了代码行数:

http://codepen.io/luciopaiva/pen/YXYGYE?editors=101

我正在使用 call 这样我就可以将 DOM 元素(通过 this 引用)传递给 changeFilter() 的上下文.

我还将所有过滤器放入一个对象 (filters) 中,这样我就可以通过名称访问每个过滤器,例如 filters[filterName] 并能够自动化操作.

值得一提的是,filters 变量是全局变量,整个内容应该放在 IIFE.

但让我们继续.您可以更进一步删除每个 change 事件的样板代码,考虑到您可以将元素 #assigned-user-filter 重命名为 #user-filter:

http://codepen.io/luciopaiva/pen/YXYGaY?editors=101

最后一种方法的 Javascript:

(函数(){无功过滤器 = {用户:空,状态:空,里程碑:空,优先级:空,标签: 空};函数更新过滤器(){$('.task-list-row').hide().filter(function () {无功self = $(this),结果=真;//在被证明有罪之前无罪Object.keys(filters).forEach(function (filter) {if (filters[filter] && (filters[filter] != 'None') && (filters[filter] != 'Any')) {结果 = 结果 &&过滤器[过滤器] === self.data(过滤器);}});返回结果;}).展示();}函数 bindDropdownFilters() {Object.keys(filters).forEach(function (filterName) {$('#' + filterName + '-filter').on('change', function () {过滤器[过滤器名称] = this.value;更新过滤器();});});}bindDropdownFilters();})();

这里我使用了与第二种方法相同的逻辑,使用过滤器名称来引用每个下拉列表.经典样板!

I have hacked together a basic example Task List Table with HTML and using jQuery. I have attached some on change events to my Filter DropDown Selection Fields

Demo: http://codepen.io/jasondavis/pen/MwOwMX?editors=101

I have a Filter Selection Field for each of these:

  • Assigned User
  • Task Status
  • Milestone
  • Priority
  • Tags

Independently they all work to get the job done in filtering out non matching results from my Task List Table.

For each Task Row, I store the value of each filterable option in a Data Attribute like this example Task Row HTML:

      <tr id="task-3"
          class="task-list-row" 
          data-task-id="3"
          data-assigned-user="Donald"
          data-status="Not Started"
          data-milestone="Milestone 1"
          data-priority="Low"
          data-tags="Tag 3">
        <td>Task title 3</td>
        <td>11/16/2014</td>
        <td>02/29/2015</td>
        <td>Low</td>
        <td>Milestone 1</td>
        <td>Donald</td>
        <td>Tag 3</td>
      </tr>

So the actual Text for the Task row does not matter because the Task row will not show all the properties. WHat matters is the value stored in the Task Row Data Attributes.

A Task row/record with a Miledstone set to Milestone 2 will have a Data Attribute like this data-milestone="Milestone 2"

An example JavaScript/jQuery Filter code:

// Task Milestone Dropdown Filter
$('#milestone-filter').on('change', function() {
  var taskMilestone = this.value;

  if(taskMilestone === 'None'){
    $('.task-list-row').hide().filter(function() {
      return $(this).data('milestone') != taskMilestone;
    }).show();
  }else{
    $('.task-list-row').hide().filter(function() {
      return $(this).data('milestone') == taskMilestone;
    }).show();  
  }
});

So as I mentioned. I can get each of my "FIlters" to work by thereself, however as soon as I try to apply more than 1 filter at a time, it will not work with this current code.

I would appreciate any help in modifying my code to make a working multi-filter example please?

My current demo is here: http://codepen.io/jasondavis/pen/MwOwMX?editors=101


Update Test 2

After some thought, I am thinking that perhaps I need to store all the current Filter values into variables and then on each change event instead of this:

 return $(this).data('milestone') != taskMilestone;

It would instead need to be more like this...

 return $(this).data('milestone') != taskMilestone
        && $(this).data('priority') != taskPriority
        && $(this).data('tags') != taskTags
        && .... for all filters;

Does that sound about right?

Nevermind, just tried this with no luck!

解决方案

You were close in your second test. Here's a working demo:

http://codepen.io/luciopaiva/pen/oXpzGw?editors=101

I refactored your code a little and centralized the logic around updateFilters(), which is called every time any change event occurs. It starts by assuming each row should be shown and then tests against each filter that is different from the default value (be it 'Any', 'None' or undefined).

By the way, if you can change data-user-assigned into data-user, here's a slightly improved code that greatly reduces the number of lines of code:

http://codepen.io/luciopaiva/pen/YXYGYE?editors=101

I'm using call so I can pass the DOM element (referenced through this) to the context of changeFilter().

I also put all filters into an object (filters) so I can access each one by its name, like filters[filterName] and be able to automate things.

It's worth mentioning that filters variable is global and the whole thing should be put inside an IIFE.

But let's continue. You can go even further and remove the boilerplate code for each change event, considering you can rename element #assigned-user-filter to #user-filter:

http://codepen.io/luciopaiva/pen/YXYGaY?editors=101

The Javascript of this final approach:

(function () {
  var
    filters = {
      user: null,
      status: null,
      milestone: null,
      priority: null,
      tags: null
    };

  function updateFilters() {
    $('.task-list-row').hide().filter(function () {
      var
        self = $(this),
        result = true; // not guilty until proven guilty

      Object.keys(filters).forEach(function (filter) {
        if (filters[filter] && (filters[filter] != 'None') && (filters[filter] != 'Any')) {
          result = result && filters[filter] === self.data(filter);
        }
      });

      return result;
    }).show();
  }

  function bindDropdownFilters() {
    Object.keys(filters).forEach(function (filterName) {
      $('#' + filterName + '-filter').on('change', function () {
        filters[filterName] = this.value;
        updateFilters();
      });
    });
  }

  bindDropdownFilters();
})();

Here I used the same logic as in the second approach, using filters names to reference each dropdown. Classic boilerplate!

这篇关于如何使用 jQuery 将多个过滤器组合在一起以过滤任务行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆