javascript - 检查多个复选框时过滤数据
问题描述
目前在我的应用程序中,用户可以通过输入游戏名称来搜索游戏名称。当他们开始使用过滤器方法输入结果更新。我现在正在尝试使用多个复选框来做同样的事情。因此,当用户例如检查 playstation 和/或 xbox 时,结果仅显示这些类别的游戏。当他们取消选中时,结果将使用更新的值刷新。
目前我已经成功地为所有复选框创建了更改事件并将它们的值推送到 filters.categories 数组。我遇到的问题是我不知道如何将此数组连接到我现有的过滤器方法。我需要以某种方式遍历数组并将当前值与我的商店对象中的 category.name 进行比较,以查看它们是否匹配。这可以在过滤器方法中执行吗?有什么想法我哪里出错了吗?
提前致谢。
的HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<aside>
<ul>
<li>
<label>
<input type="checkbox" value="playstation" class="category-cb">
<span>Playstation</span>
</label>
<li>
<label>
<input type="checkbox" value="xbox" class="category-cb">
<span>Xbox</span>
</label>
</li>
<li>
<label>
<input type="checkbox" value="nintendo" class="category-cb">
<span>Nintendo</span>
</label>
</li>
</li>
</ul>
</aside>
<main>
<input type="text" class="store-search" placeholder="Search">
<ul class="grid"></ul>
</main>
<script src="app.js"></script>
</body>
</html>
js:
/*----------------------------
data
----------------------------*/
const stores = [{
id: 0,
name: 'The Last Of Us',
studio: 'Naughtydog',
thumbnail: '',
category: {
id: 0,
name: 'Playstation'
},
price: 50.00
}, {
id: 1,
name: 'Animal Crossing',
studio: 'Nintendo',
thumbnail: '',
category: {
id: 1,
name: 'Nintendo'
},
price: 60.00
}, {
id: 2,
name: 'Gears 5',
studio: 'The Coalition',
thumbnail: '',
category: {
id: 2,
name: 'Xbox'
},
price: 10.00
}, {
id: 3,
name: 'DOOM Eternal',
studio: 'id Software',
thumbnail: '',
category: {
id: 3,
name: 'Playstation'
},
price: 50.00
}, {
id: 4,
name: 'The Legend of Zelda: Link\'s Awakening',
studio: 'Grezzo',
thumbnail: '',
category: {
id: 4,
name: 'Nintendo'
},
price: 35.00
}, {
id: 5,
name: 'Resident Evil 3',
studio: 'Capcom',
thumbnail: '',
category: {
id: 5,
name: 'Playstation'
},
price: 40.00
}];
let filters = {
searchText: '',
categories: []
}
/*----------------------------
functions
----------------------------*/
let filterStores = function (stores, filters) {
let filteredStores = stores.filter(function (store) {
let storeName = store.name.toLowerCase().includes(filters.searchText.toLowerCase());
return storeName;
});
let grid = document.querySelector('.grid');
grid.innerHTML = '';
filteredStores.forEach(function (store) {
let li = document.createElement('li');
li.textContent = store.name;
grid.appendChild(li);
});
}
/*----------------------------
events
----------------------------*/
document.addEventListener('DOMContentLoaded', function () {
filterStores(stores, filters);
document.querySelector('.store-search').addEventListener('input', function (event) {
filters.searchText = event.target.value;
filterStores(stores, filters);
});
document.querySelectorAll('.category-cb').forEach(function (checkbox) {
checkbox.addEventListener('change', function (event) {
if (checkbox.checked) {
filters.categories.push(event.target.value);
filterStores(stores, filters);
console.log(filters.categories);
}
});
});
});
解决方案
要实现的主要功能有两个:
未选中时删除类别
我建议您使用 Set as ,这样您就可以轻松地分别通过、和
filters.categories
来检查、添加和删除条目。has
add
delete
//onchange event if (checkbox.checked) { filters.categories.add(event.target.value); } else { filters.categories.delete(event.target.value); } filterStores(stores, filters);
也过滤
stores
基于类别修改你的
.filter
回调也考虑到这一点:store.name.toLowerCase().includes(filters.searchText.toLowerCase()) && filters.categories.has(store.category.name.toLowerCase())
此外,要在未选择任何类别时显示全部,请执行以下操作:
store.name.toLowerCase().includes(filters.searchText.toLowerCase()) && ( filters.categories.has(store.category.name.toLowerCase()) || filters.categories.size === 0 )
全部一起:
/*----------------------------
data
----------------------------*/
const stores = [{
id: 0,
name: 'The Last Of Us',
studio: 'Naughtydog',
thumbnail: '',
category: {
id: 0,
name: 'Playstation'
},
price: 50.00
}, {
id: 1,
name: 'Animal Crossing',
studio: 'Nintendo',
thumbnail: '',
category: {
id: 1,
name: 'Nintendo'
},
price: 60.00
}, {
id: 2,
name: 'Gears 5',
studio: 'The Coalition',
thumbnail: '',
category: {
id: 2,
name: 'Xbox'
},
price: 10.00
}, {
id: 3,
name: 'DOOM Eternal',
studio: 'id Software',
thumbnail: '',
category: {
id: 3,
name: 'Playstation'
},
price: 50.00
}, {
id: 4,
name: 'The Legend of Zelda: Link\'s Awakening',
studio: 'Grezzo',
thumbnail: '',
category: {
id: 4,
name: 'Nintendo'
},
price: 35.00
}, {
id: 5,
name: 'Resident Evil 3',
studio: 'Capcom',
thumbnail: '',
category: {
id: 5,
name: 'Playstation'
},
price: 40.00
}];
let filters = {
searchText: '',
categories: new Set
}
/*----------------------------
functions
----------------------------*/
let filterStores = function (stores, filters) {
let filteredStores = stores.filter(store => (
store.name.toLowerCase().includes(filters.searchText.toLowerCase()) &&
(
filters.categories.has(store.category.name.toLowerCase()) ||
filters.categories.size === 0 //No selected categories, show all
)
));
let grid = document.querySelector('.grid');
grid.innerHTML = '';
filteredStores.forEach(function (store) {
let li = document.createElement('li');
li.textContent = store.name;
grid.appendChild(li);
});
}
/*----------------------------
events
----------------------------*/
document.addEventListener('DOMContentLoaded', function () {
filterStores(stores, filters);
document.querySelector('.store-search').addEventListener('input', function (event) {
filters.searchText = event.target.value;
filterStores(stores, filters);
});
document.querySelectorAll('.category-cb').forEach(function (checkbox) {
checkbox.addEventListener('change', function (event) {
if (checkbox.checked) {
filters.categories.add(event.target.value);
} else {
filters.categories.delete(event.target.value);
}
filterStores(stores, filters);
});
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<aside>
<ul>
<li>
<label>
<input type="checkbox" value="playstation" class="category-cb">
<span>Playstation</span>
</label>
</li>
<li>
<label>
<input type="checkbox" value="xbox" class="category-cb">
<span>Xbox</span>
</label>
</li>
<li>
<label>
<input type="checkbox" value="nintendo" class="category-cb">
<span>Nintendo</span>
</label>
</li>
</ul>
</aside>
<main>
<input type="text" class="store-search" placeholder="Search">
<ul class="grid"></ul>
</main>
<script src="app.js"></script>
</body>
</html>
您还可以使用数组:
/*----------------------------
data
----------------------------*/
const stores = [{
id: 0,
name: 'The Last Of Us',
studio: 'Naughtydog',
thumbnail: '',
category: {
id: 0,
name: 'Playstation'
},
price: 50.00
}, {
id: 1,
name: 'Animal Crossing',
studio: 'Nintendo',
thumbnail: '',
category: {
id: 1,
name: 'Nintendo'
},
price: 60.00
}, {
id: 2,
name: 'Gears 5',
studio: 'The Coalition',
thumbnail: '',
category: {
id: 2,
name: 'Xbox'
},
price: 10.00
}, {
id: 3,
name: 'DOOM Eternal',
studio: 'id Software',
thumbnail: '',
category: {
id: 3,
name: 'Playstation'
},
price: 50.00
}, {
id: 4,
name: 'The Legend of Zelda: Link\'s Awakening',
studio: 'Grezzo',
thumbnail: '',
category: {
id: 4,
name: 'Nintendo'
},
price: 35.00
}, {
id: 5,
name: 'Resident Evil 3',
studio: 'Capcom',
thumbnail: '',
category: {
id: 5,
name: 'Playstation'
},
price: 40.00
}];
let filters = {
searchText: '',
categories: []
}
/*----------------------------
functions
----------------------------*/
let filterStores = function (stores, filters) {
let filteredStores = stores.filter(store => (
store.name.toLowerCase().includes(filters.searchText.toLowerCase()) &&
(
filters.categories.includes(store.category.name.toLowerCase()) ||
filters.categories.length === 0 //No selected categories, show all
)
));
let grid = document.querySelector('.grid');
grid.innerHTML = '';
filteredStores.forEach(function (store) {
let li = document.createElement('li');
li.textContent = store.name;
grid.appendChild(li);
});
}
/*----------------------------
events
----------------------------*/
document.addEventListener('DOMContentLoaded', function () {
filterStores(stores, filters);
document.querySelector('.store-search').addEventListener('input', function (event) {
filters.searchText = event.target.value;
filterStores(stores, filters);
});
document.querySelectorAll('.category-cb').forEach(function (checkbox) {
checkbox.addEventListener('change', function (event) {
if (checkbox.checked) {
filters.categories.push(event.target.value);
} else {
filters.categories.splice(filters.categories.indexOf(event.target.value), 1);
}
filterStores(stores, filters);
});
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<aside>
<ul>
<li>
<label>
<input type="checkbox" value="playstation" class="category-cb">
<span>Playstation</span>
</label>
</li>
<li>
<label>
<input type="checkbox" value="xbox" class="category-cb">
<span>Xbox</span>
</label>
</li>
<li>
<label>
<input type="checkbox" value="nintendo" class="category-cb">
<span>Nintendo</span>
</label>
</li>
</ul>
</aside>
<main>
<input type="text" class="store-search" placeholder="Search">
<ul class="grid"></ul>
</main>
<script src="app.js"></script>
</body>
</html>
推荐阅读
- azure - Azure Functions - 无法使用 VSCODE 扩展部署函数 - 部署在将 zip 包上传到存储容器时永远挂起
- android - 安卓外挂。如何录制流式 RTSP 视频
- python - 错误:命令出错,退出状态为 1:在 Heroku 上部署代码时
- javascript - Firebase v9 Beta 库的模块化使用
- java - 如何在 Java 中使用多核运行 Z3?
- mongodb - 解决 MongoDB 单文本索引限制
- c# - 如何从 local.settings.json 绑定抽象类列表?
- javascript - 遍历对象数组并比较结果的简单方法?
- reactjs - 在其他设备上直播 netlify 应用程序黑屏
- vb.net - iText 7签名字段对齐