【问题标题】:How to combine multiple FIlters together to filter Task Rows using jQuery?如何将多个过滤器组合在一起以使用 jQuery 过滤任务行?
【发布时间】:2015-09-08 17:43:41
【问题描述】:

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

演示:http://codepen.io/jasondavis/pen/MwOwMX?editors=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>

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

Miledstone 设置为Milestone 2 的任务行/记录将具有类似data-milestone="Milestone 2" 的数据属性

一个示例 JavaScript/jQuery 过滤器代码:

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

正如我所提到的。我可以让我的每个“过滤器”自己工作,但是一旦我尝试一次应用超过 1 个过滤器,它将不适用于当前代码。

在修改我的代码以制作一个有效的多过滤器示例方面,我将不胜感激?

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


更新测试 2

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

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

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

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

这听起来对吗?

没关系,只是没有运气!

【问题讨论】:

    标签: javascript jquery filter


    【解决方案1】:

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

    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 中。

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

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

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

    【讨论】:

    • 这简直太棒了!我从来没有想出过如此优雅的解决方案,而且显然其他人也无法做到!非常感谢您,这将对我正在开发的项目管理应用程序非常有帮助。
    • 如果您觉得自己是个挑战,最好为截止日期添加一个新过滤器。选项将类似于到期日在 30 天内、7n 天内等......以及从今天开始到期的到期日。显然你没有义务,但如果你喜欢解决这些类型的问题,那我也想做一个过滤器,我觉得这可能并不难。有什么想法吗?再次感谢上述解决方案,非常感谢您付出的时间和精力!
    • @JasonDavis 不客气!关于截止日期过滤器,请查看moment.js,它是一个用于处理日期/时间的出色库。尝试发布您目前的新问题,也许我们可以从那里开始。
    • 你可以在一个数据属性中有多个值吗?我尝试使用逗号分隔来执行此操作,但您的过滤器不再有效。
    猜你喜欢
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-27
    • 2012-01-08
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    相关资源
    最近更新 更多