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

Jas*_*vis 11 javascript jquery filter

我已经使用HTML并使用jQuery将基本示例任务列表表入侵.我附上了一些on change事件给我Filter DropDown Selection Fields

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

在此输入图像描述

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

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

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

对于每个任务行,我将每个可过滤选项的值存储在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>
Run Code Online (Sandbox Code Playgroud)

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

具有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();  
  }
});
Run Code Online (Sandbox Code Playgroud)

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

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

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


更新测试2

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

 return $(this).data('milestone') != taskMilestone;
Run Code Online (Sandbox Code Playgroud)

相反,它需要更像这样......

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

那个听起来是对的吗?

没关系,只是试着没有运气!

Luc*_*iva 9

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

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

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

顺便说一句,如果你可以改变data-user-assigneddata-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();
})();
Run Code Online (Sandbox Code Playgroud)

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

  • 这简直太棒了!我从来没有想出这么优雅的解决方案,显然没有其他人也可以!非常感谢,这对我正在开发的项目管理应用程序非常有帮助. (2认同)