javascript 如何使用 jQuery 将多个过滤器组合在一起以过滤任务行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30994081/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to combine multiple FIlters together to filter Task Rows using jQuery?
提问by JasonDavis
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
我用 HTML 和 jQuery 编写了一个基本的示例任务列表。我已将一些on change
事件附加到我的Filter DropDown Selection Fields
Demo: http://codepen.io/jasondavis/pen/MwOwMX?editors=101
演示: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:
对于每个任务行,我将每个可过滤选项的值存储在一个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>
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"
Miledstone
设置为 to 的任务行/记录Milestone 2
将具有这样的数据属性data-milestone="Milestone 2"
An example JavaScript/jQuery Filter code:
一个示例 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();
}
});
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.
所以正如我提到的。我可以让我的每个“过滤器”自行工作,但是一旦我尝试一次应用 1 个以上的过滤器,它就无法使用当前的代码。
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
我目前的演示在这里:http: //codepen.io/jasondavis/pen/MwOwMX?editors=101
Update Test 2
更新测试 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:
经过一番思考,我想也许我需要将所有当前的 Filter 值存储到变量中,然后在每个change
事件中而不是这样:
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!
没关系,只是尝试了这个没有运气!
采纳答案by Lucio Paiva
You were close in your second test. Here's a working demo:
你在第二次测试中很接近。这是一个工作演示:
http://codepen.io/luciopaiva/pen/oXpzGw?editors=101
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
).
我稍微重构了您的代码并集中了围绕 的逻辑updateFilters()
,每次发生任何更改事件时都会调用它。它首先假设应该显示每一行,然后针对与默认值不同的每个过滤器进行测试(无论是“Any”、“None”还是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:
顺便说一句,如果你能data-user-assigned
改成data-user
,这里有一个稍微改进的代码,大大减少了代码行数:
http://codepen.io/luciopaiva/pen/YXYGYE?editors=101
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()
.
我正在使用,call
所以我可以将 DOM 元素(通过 引用this
)传递到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.
我还将所有过滤器放入一个对象 ( filters
) 中,以便我可以按名称访问每个过滤器,例如filters[filterName]
并能够自动执行操作。
It's worth mentioning that filters
variable is global and the whole thing should be put inside an IIFE.
值得一提的是,filters
变量是全局的,整个事情都应该放在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
:
但是让我们继续。您可以更进一步并删除每个change
事件的样板代码,考虑到您可以将元素重命名 #assigned-user-filter
为#user-filter
:
http://codepen.io/luciopaiva/pen/YXYGaY?editors=101
http://codepen.io/luciopaiva/pen/YXYGaY?editors=101
The Javascript of this final approach:
最后一种方法的 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();
})();
Here I used the same logic as in the second approach, using filters names to reference each dropdown. Classic boilerplate!
在这里,我使用了与第二种方法相同的逻辑,使用过滤器名称来引用每个下拉列表。经典样板!