javascript - JQuery Show/Hide multiple elements based on combined multiple data attributes and search field
问题描述
I have some html elements like this:
<div class="items">
<div class="item" data-opt1="val1" data-opt2="val2,val3">Item 1</div>
<div class="item" data-opt1="val4" data-opt2="val2,val5">Item 2</div>
<div class="item" data-opt1="val1" data-opt2="val3,val6">Item 3</div>
<div class="item" data-opt1="val7" data-opt2="val3,val5">Item 4</div>
</div>
and 2 variables to be used as filters, one array of options and one search string like this:
Example 1
var srcString = "val";
var filters = [
'opt1' : ['val1'],
'opt2' : ['val2','val6']
];
In this example item1 and item3 should be visible, item2 and item4 not visible.
Example 2
var srcString = "value";
var filters = [
'opt1' : ['val1'],
'opt2' : ['val2','val6']
];
All items shouldn't be visible, because var srcString contain a word that are not present in any of the data attributes.
Example 3
var srcString = "val6";
var filters = [];
Only item3 should be visible.
Example 4
var srcString = "";
var filters = [
'opt1' : ['val1','val7'],
'opt2' : ['val5']
];
Only item4 should be visible, because item1 and item3 (even if have opt1=val1) not have val5 in opt2.
Example 5
var srcString = "";
var filters = [
'opt1' : ['val1','val7']
];
items: 1,3,4 should be visible.
I was able to make all of these filters work one by one, but problems comes when I try to combinate all of them.
Code for search:
$(".item").each(function(){
var item = $(this);
if (item.data('opt1').toLowerCase().indexOf(srcVal) >= 0
|| item.data('opt2').toLowerCase().indexOf(srcVal) >= 0){
item.removeClass('d-none');
}else{
item.addClass('d-none');
}
});
Code for single filter:
var selectedOptions = filters['opt2'];
$(".item").each(function(){
var item = $(this);
let _options = item.data('opt2') + '';
_options = _options.split(",");
let found = _options.some(r=> selectedOptions.includes(r));
if(found==true){
item.removeClass('d-none');
}else{
item.addClass('d-none');
}
})
Any help is appreciate
解决方案
调整现有代码,您可以将第二次检查移动到第一次检查的通过内。
需要进行一些额外的检查,例如检查.opt2
存在和具有值,但这些都是简单的检查。
$(".item").each(function() {
var item = $(this);
if (item.data('opt1').toLowerCase().indexOf(srcString) >= 0 ||
item.data('opt2').toLowerCase().indexOf(srcString) >= 0) {
item.removeClass('d-none');
var selectedOptions = filters['opt2'];
if (selectedOptions != null) {
let _options = item.data('opt2') + '';
_options = _options.split(",");
if (_options.length > 0) {
let found = _options.some(r => selectedOptions.includes(r));
if (found == true) {
item.removeClass('d-none');
} else {
item.addClass('d-none');
}
}
}
} else {
item.addClass('d-none');
}
});
小提琴:https ://jsfiddle.net/7t26n3pj/
注意:这使用提供的 OP 代码,因此与他们的示例不完全匹配,因为缺少检查opt1
您可以if (_available_) continue
通过将检查移动到单独的函数中来删除以减少代码缩进,并为通过/不通过返回 true/false - 这也将允许您在以后添加新的过滤器。
function applyFilter(filter) {
$(".item").each(function() {
var item = $(this);
if (passesFilter(item, filter))
item.removeClass('d-none');
else
item.addClass('d-none');
})
}
function passesFilter(item, filter) {
if (item.data('opt1').toLowerCase().indexOf(filter.srcString) < 0 &&
item.data('opt2').toLowerCase().indexOf(filter.srcString) < 0)
return false;
var selectedOptions = filter.filters['opt2'];
if (selectedOptions == null) return true;
let _options = item.data('opt2') + '';
_options = _options.split(",");
if (_options.length === 0) return true;
let found = _options.some(r => selectedOptions.includes(r));
return found;
}
// Examples
$("button").click(function() {
var filter = $(this).data("filter");
console.log(filter);
applyFilter(filter);
});
.d-none { display:none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="items">
<div class="item" data-opt1="val1" data-opt2="val2,val3">Item 1</div>
<div class="item" data-opt1="val4" data-opt2="val2,val5">Item 2</div>
<div class="item" data-opt1="val1" data-opt2="val3,val6">Item 3</div>
<div class="item" data-opt1="val7" data-opt2="val3,val5">Item 4</div>
</div>
<button type='button' data-filter='{"srcString":"val","filters":{"opt1":["val1"],"opt2":["val2","val6"]}}'>
test 1
</button>
<button type='button' data-filter='{"srcString":"value","filters":{"opt1":["val1"],"opt2":["val2","val6"]}}'>
test 2
</button>
<button type='button' data-filter='{"srcString":"val6","filters":{}'>
test 3
</button>
<button type='button' data-filter='{"srcString":"","filters":{"opt1":["val1", "val7"],"opt2":["val5"]}}'>
test 4
</button>
<button type='button' data-filter='{"srcString":"","filters":{"opt1":["val1", "val7"]}}'>
test 5
</button>
推荐阅读
- javascript - ng-repeat 不根据 json 对象的顺序打印
- html - 如何修复覆盖网站所有其他 HTML 页面的 index.html
- python - 从 C++ 调用 python 脚本时,python 库如何工作?
- php - 如何将查询结果保存在变量中?
- numpy - 用 numpy 分组计数
- ionic-framework - Ionic 3:使用 F5/浏览器刷新按钮在浏览器中重新加载页面
- javascript - 具有相同名称的多个文件未在环回中上传
- javascript - npm run serve 永远挂起 vue
- asp.net - 当我在自定义 GridView 中更新时,TextBox 返回 null
- dns - DNS - 基于地理位置的固定 IP 顺序