最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to combine multiple FIlters together to filter Task Rows using jQuery? - Stack Overflow

programmeradmin2浏览0评论

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:

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:


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!

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!

Share Improve this question edited Jun 23, 2015 at 5:09 JasonDavis asked Jun 23, 2015 at 4:53 JasonDavisJasonDavis 49k107 gold badges326 silver badges557 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 10

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!

发布评论

评论列表(0)

  1. 暂无评论