如何将多个过滤器组合在一起使用jQuery过滤任务行?

时间:2015-06-23 04:53:04

标签: javascript jquery filter

我已经使用HTML并使用jQuery将基本示例任务列表表入侵。我已将一些on change个事件附加到Filter DropDown Selection Fields

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

enter image description here

我有一个过滤器选择字段:

  • 指定用户
  • 任务状态
  • 里程碑
  • 优先级
  • 标签

独立地,他们都努力完成工作,从我的任务列表中过滤掉不匹配的结果。

对于每个任务行,我将每个可过滤选项的值存储在Data Attribute中,例如任务行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>

因此Task行的实际Text无关紧要,因为Task行不会显示所有属性。重要的是存储在任务行数据属性中的值。

Miledstone设置为Milestone 2的任务行/记录将具有此类data-milestone="Milestone 2"

的数据属性

示例JavaScript / jQuery Filter代码:

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

正如我所提到的那样。我可以自己让每个“过滤器”工作,但是一旦我尝试一次应用多个过滤器,它就无法使用当前的代码。

我很感激您在修改我的代码以制作有效的多重过滤器示例方面有任何帮助吗?

我目前的演示在这里:http://codepen.io/jasondavis/pen/MwOwMX?editors=101

更新测试2

经过一番思考后,我想我可能需要将所有当前的Filter值存储到变量中,然后再存储在每个change事件中,而不是:

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

它需要更像这样......

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

这听起来是对的吗?

没关系,只是试了一下,没有运气!

1 个答案:

答案 0 :(得分:9)

你在第二次测试中接近了。这是一个有效的演示:

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:

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

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