[英]Multiple Checkbox Filtering to Narrow Down a Search
Thank you to Khalid Ali for helping me so far up to this point. 感谢Khalid Ali到目前为止帮助我到目前为止。
So I have an array of songs that have descriptions, keywords etc. I have a number of checkboxes that I would like to use to refine a search. 所以我有一系列包含描述,关键字等的歌曲。我有许多复选框,我想用它来优化搜索。 Basically, if someone selects the Pop checkbox it will show all songs with the genre "pop".
基本上,如果有人选择Pop复选框,它将显示所有类型为“pop”的歌曲。 However, if I also select Epic Trailers, it returns all songs with "pop" AND all songs with "epictrailers" in their genre.
但是,如果我还选择了Epic Trailers,它会返回所有带有“pop”的歌曲和所有带有“epictrailers”的歌曲。 What I would like is for it to return songs with both genres only.
我想要的是它只返回两种类型的歌曲。 For example - genre: "pop, epictrailers",
例如 - 流派:“流行音乐,epictrailers”,
In the array below you'll see that song 2 and song 3 both have "dramatic" in moods. 在下面的数组中,你会看到歌曲2和歌曲3都有“戏剧性”的情绪。 But song 2 also has "tense" and song 3 also has "soaring".
但歌曲2也有“紧张”,而歌曲3也有“飙升”。 So if I check the Dramatic and Soaring checkboxes I should only see song 3. At the moment both songs show because both songs have "dramatic".
因此,如果我检查戏剧和飙升复选框,我应该只看到歌曲3.目前两首歌曲都显示,因为这两首歌都有“戏剧性”。
So in short, I want it to return only songs that include ALL checked boxes. 所以简而言之,我希望它只返回包含所有复选框的歌曲。
I hope this makes sense... 我希望这是有道理的...
HTML SNIPPETS: HTML SNIPPETS:
<div id="app">
<div class="search-music">
<input type="text" v-model="search" placeholder="Enter a keyword to refine your search"/>
</div>
<div class='filterboxes'>
<div class="genres"><h1>GENRES</h1><br>
<input type="checkbox" id="rock" key="genre" value="rock" v-model="checkboxFilter">
<label for="rock">Rock</label><br>
<input type="checkbox" id="Pop" key="genre" value="pop" v-model="checkboxFilter">
<label for="Pop">Pop</label><br>
<input type="checkbox" id="funk" key="genre" value="funk" v-model="checkboxFilter">
<label for="funk">Funk</label><br>
<input type="checkbox" id="Jazz" key="genre" value="jazz" v-model="checkboxFilter">
<label for="Jazz">Jazz</label><br>
</div>
<div class="genres"><P></P><br>
<input type="checkbox" id="Dubstep" key="genre" value="dubstep" v-model="checkboxFilter">
<label for="Dubstep">Dubstep</label><br>
<input type="checkbox" id="Classical" key="genre" value="classical" v-model="checkboxFilter">
<label for="Classical">Classical</label><br>
<input type="checkbox" id="Country" key="genre" value="country" v-model="checkboxFilter">
<label for="Country">Country</label><br>
<input type="checkbox" id="Blues" key="genre" value="blues" v-model="checkboxFilter">
<label for="Blues">Blues</label><br>
</div>
<div class="genres"><P></P><br>
<input type="checkbox" id="Hip Hop" key="genre" value="hiphop" v-model="checkboxFilter">
<label for="Hip Hop">Hip Hop</label><br>
<input type="checkbox" id="Orchestral" key="genre" value="orchestral" v-model="checkboxFilter">
<label for="Orchestral">Orchestral</label><br>
<input type="checkbox" id="Epic Trailer" key="genre" value="epictrailer" v-model="checkboxFilter">
<label for="Epic Trailer">Epic Trailer</label><br>
<input type="checkbox" id="EDM" key="genre" value="edm" v-model="checkboxFilter">
<label for="EDM">EDM</label><br>
</div>
<div class="genres"><h1>MOODS</h1><br>
<input type="checkbox" id="Melancholy" key="moods" value="melancholy" v-model="checkboxFilter">
<label for="Melancholy">Melancholy</label><br>
<input type="checkbox" id="Upbeat" key="moods" value="upbeat" v-model="checkboxFilter">
<label for="Upbeat">Upbeat</label><br>
<input type="checkbox" id="Playful" key="moods" value="playful" v-model="checkboxFilter">
<label for="Playful">Playful</label><br>
<input type="checkbox" id="Hopeful" key="moods" value="hopeful" v-model="checkboxFilter">
<label for="Hopeful">Hopeful</label><br>
</div>
<div class="genres"><P></P><br>
<input type="checkbox" id="Dramatic" key="moods" value="dramatic" v-model="checkboxFilter">
<label for="Dramatic">Dramatic</label><br>
<input type="checkbox" id="Disturbing" key="moods" value="disturbing" v-model="checkboxFilter">
<label for="Disturbing">Disturbing</label><br>
<input type="checkbox" id="Uplifting" key="moods" value="uplifting" v-model="checkboxFilter">
<label for="Uplifting">Uplifting</label><br>
<input type="checkbox" id="Tense" key="moods" value="tense" v-model="checkboxFilter">
<label for="Tense">Tense</label><br>
</div>
<div class="genres"><P></P><br>
<input type="checkbox" id="Crazy" key="moods" value="crazy" v-model="checkboxFilter">
<label for="Crazy">Crazy</label><br>
<input type="checkbox" id="Funny" key="moods" value="funny" v-model="checkboxFilter">
<label for="Funny">Funny</label><br>
<input type="checkbox" id="Soaring" key="moods" value="soaring" v-model="checkboxFilter">
<label for="Soaring">Soaring</label><br>
<input type="checkbox" id="Childish" key="moods" value="childish" v-model="checkboxFilter">
<label for="Childish">Childish</label><br>
</div>
<div class="genres"><h1>TEMPO</h1><br>
<input type="checkbox" id="vfast" key="tempo" value="vfast" v-model="checkboxFilter">
<label for="vfast">Very Fast</label><br>
<input type="checkbox" id="fast" key="tempo" value="fast" v-model="checkboxFilter">
<label for="fast">Fast</label><br>
<input type="checkbox" id="moderate" key="tempo" value="moderate" v-model="checkboxFilter">
<label for="moderate">Moderate</label><br>
<input type="checkbox" id="slow" key="tempo" value="slow" v-model="checkboxFilter">
<label for="slow">Slow</label><br>
</div>
<div class="genres"><h1>THEMES</h1><br>
<input type="checkbox" id="Corporate" key="theme" value="corporate" v-model="checkboxFilter">
<label for="Corporate">Corporate</label><br>
<input type="checkbox" id="Technology" key="theme" value="technology" v-model="checkboxFilter">
<label for="Technology">Technology</label><br>
<input type="checkbox" id="Food" key="theme" value="food" v-model="checkboxFilter">
<label for="Food">Food</label><br>
<input type="checkbox" id="Education" key="theme" value="education" v-model="checkboxFilter">
<label for="Education">Education</label><br>
</div>
<div class="genres"><P></P><br>
<input type="checkbox" id="Travel" key="theme" value="travel" v-model="checkboxFilter">
<label for="Travel">Travel</label><br>
<input type="checkbox" id="Sport" key="theme" value="sport" v-model="checkboxFilter">
<label for="Sport">Sport</label><br>
<input type="checkbox" id="Fashion" key="theme" value="fashion" v-model="checkboxFilter">
<label for="Fashion">Fashion</label><br>
<input type="checkbox" id="Landscape" key="theme" value="landscape" v-model="checkboxFilter">
<label for="Landscape">Landscape</label><br>
</div>
</div>
<template v-for='song in filteredSongs'>
<div class="songlayout" >
<div class='wrapper'>
<div>
<img :src="song.cover_art_url" alt="" class='img-fluid rounded'>
</div>
<button class="button_7" @click='openLicense(song.license_url)'>License</button>
<h1 class='song-title'>{{song.title}}</h1>
<p class="song-description" >{{song.description}}</p>
<div class="overlay-play text-center" v-if="isPlaying && (currentSong.id === song.id )" @click='pause'>
<i class="icon ion-ios-pause"></i>
</div>
<div class="overlay-play text-center" @click='play(song)' v-else>
<i class="icon ion-ios-play"></i>
</div>
</div>
</div>
</template>
</div>
JS SNIPPET: JS SNIPPET:
new Vue({
el: '#app',
data: {
songs: [
{
id: 1,
title: "Track 1",
description: "Description 1",
url:"./mp3/track1.mp3",
keywords: "achievement, advertising, background, beautiful, beauty, business, business music, commercial, company, confident, corporate, corporate background, corporate presentation, corporate presentations music, corporate video, corporation, corporative, happy",
genre:"pop, rock",
moods:"uplifting, upbeat, playful",
tempo:"moderate",
theme:"corporate",
},
{
id: 2,
title: "Track 2",
description: "Description 2",
url:"./mp3/track2.mp3",
keywords: "scary, horror, Armageddon, Big Ending, Dramatic, End Of The World, Escape, Fantasy, Film, Film Score, Foreboding, Haunted House, Haunting, Nervous, Nightmare, Pensive",
genre:"epictrailer",
moods:"tense, dramatic, disturbing",
tempo:"moderate",
theme:"landscape",
},
{
id: 3,
title: "Track 3",
description: "Description 3",
url: "./mp3/track3.mp3",
keywords:"Armageddon, Battle, Big Ending, Bomb, Break Out, Busy, Chase, Chilled, Covert Ops, Detective,",
genre:"epictrailer",
moods:"dramatic, soaring, hopeful",
tempo:"moderate",
theme:"sport",
},
],
search: "",
checkboxFilter: [],
},
computed: {
filteredSongs: function(value, key){
let fltrdSongs;
if(this.checkboxFilter.length > 0) {
fltrdSongs = this.songs.filter((song) => {
let length = this.checkboxFilter.length;
while(length--){
if ((song.genre + song.moods + song.theme + song.tempo).indexOf(this.checkboxFilter[length])!=-1)
{return true;}
}
});
} else {
fltrdSongs = this.songs;
}
return fltrdSongs.filter((song) => {
return song.keywords.toLowerCase().match(this.search.toLowerCase()) ||
song.title.toLowerCase().match(this.search.toLowerCase()) ||
song.description.toLowerCase().match(this.search.toLowerCase())
});
},},
Your filteredSongs
computed property never reaches the this.checkboxFilter.length
if statement because of the return
statement before it. 您的
filteredSongs
计算属性永远不会到达this.checkboxFilter.length
if语句,因为它之前的return
语句。
Replace your filteredSongs
computed property with the following one: 将
filteredSongs
计算属性替换为以下值:
filteredSongs: function(value, key){
let fltrdSongs;
if(this.checkboxFilter.length > 0)
fltrdSongs = this.songs.filter((song) => (song.genre)
.includes(this.checkboxFilter.toString()));
else
fltrdSongs = this.songs;
return fltrdSongs.filter((song) => {
return song.keywords.toLowerCase().match(this.search.toLowerCase()) ||
song.title.toLowerCase().match(this.search.toLowerCase()) ||
song.description.toLowerCase().match(this.search.toLowerCase())
});
}
In response to jeanpegg's comment 回应jeanpegg的评论
Use the following computed property to filter the songs by multiple checkboxes: 使用以下计算属性按多个复选框筛选歌曲 :
filteredSongs: function(value, key){
let fltrdSongs;
if(this.checkboxFilter.length > 0) {
fltrdSongs = this.songs.filter((song) => {
let length = this.checkboxFilter.length;
while(length--){
if ((song.genre).indexOf(this.checkboxFilter[length])!=-1) {
return true;
}
}
});
} else {
fltrdSongs = this.songs;
}
return fltrdSongs.filter((song) => {
return song.keywords.toLowerCase().match(this.search.toLowerCase()) ||
song.title.toLowerCase().match(this.search.toLowerCase()) ||
song.description.toLowerCase().match(this.search.toLowerCase())
});
}
In response to jeanpegg's comment 回应jeanpegg的评论
I've edit the code to work with the genre and moods . 我编辑代码以处理流派和情绪 。
HTML: changing v-model="checkboxFilter"
to v-model="checkboxFilter.genre"
and v-model="checkboxFilter.moods"
HTML:将
v-model="checkboxFilter"
更改为v-model="checkboxFilter.genre"
和v-model="checkboxFilter.moods"
JS: changing the checkboxFilter
data property to checkboxFilter: {genre: [], moods: []}
. JS:将
checkboxFilter
数据属性更改为checkboxFilter: {genre: [], moods: []}
。 Also changed the filteredSongs
computed property 还更改了
filteredSongs
计算属性
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script><div id="app">
<div class="search-music">
<input type="text" v-model="search" placeholder="Enter a keyword to refine your search"/>
</div>
<div class='filterboxes'>
<div class="genres"><h1>GENRES</h1><br>
<input type="checkbox" id="rock" key="genre" value="rock" v-model="checkboxFilter.genre">
<label for="rock">Rock</label><br>
<input type="checkbox" id="Pop" key="genre" value="pop" v-model="checkboxFilter.genre">
<label for="Pop">Pop</label><br>
<input type="checkbox" id="funk" key="genre" value="funk" v-model="checkboxFilter.genre">
<label for="funk">Funk</label><br>
<input type="checkbox" id="Jazz" key="genre" value="jazz" v-model="checkboxFilter.genre">
<label for="Jazz">Jazz</label><br>
</div>
<div class="genres"><P></P><br>
<input type="checkbox" id="Dubstep" key="genre" value="dubstep" v-model="checkboxFilter.genre">
<label for="Dubstep">Dubstep</label><br>
<input type="checkbox" id="Classical" key="genre" value="classical" v-model="checkboxFilter.genre">
<label for="Classical">Classical</label><br>
<input type="checkbox" id="Country" key="genre" value="country" v-model="checkboxFilter.genre">
<label for="Country">Country</label><br>
<input type="checkbox" id="Blues" key="genre" value="blues" v-model="checkboxFilter.genre">
<label for="Blues">Blues</label><br>
</div>
<div class="genres"><P></P><br>
<input type="checkbox" id="Hip Hop" key="genre" value="hiphop" v-model="checkboxFilter.genre">
<label for="Hip Hop">Hip Hop</label><br>
<input type="checkbox" id="Orchestral" key="genre" value="orchestral" v-model="checkboxFilter.genre">
<label for="Orchestral">Orchestral</label><br>
<input type="checkbox" id="Epic Trailer" key="genre" value="epictrailer" v-model="checkboxFilter.genre">
<label for="Epic Trailer">Epic Trailer</label><br>
<input type="checkbox" id="EDM" key="genre" value="edm" v-model="checkboxFilter.genre">
<label for="EDM">EDM</label><br>
</div>
<div class="genres"><h1>MOODS</h1><br>
<input type="checkbox" id="Melancholy" key="moods" value="melancholy" v-model="checkboxFilter.moods">
<label for="Melancholy">Melancholy</label><br>
<input type="checkbox" id="Upbeat" key="moods" value="upbeat" v-model="checkboxFilter.moods">
<label for="Upbeat">Upbeat</label><br>
<input type="checkbox" id="Playful" key="moods" value="playful" v-model="checkboxFilter.moods">
<label for="Playful">Playful</label><br>
<input type="checkbox" id="Hopeful" key="moods" value="hopeful" v-model="checkboxFilter.moods">
<label for="Hopeful">Hopeful</label><br>
</div>
<div class="genres"><P></P><br>
<input type="checkbox" id="Dramatic" key="moods" value="dramatic" v-model="checkboxFilter.moods">
<label for="Dramatic">Dramatic</label><br>
<input type="checkbox" id="Disturbing" key="moods" value="disturbing" v-model="checkboxFilter.moods">
<label for="Disturbing">Disturbing</label><br>
<input type="checkbox" id="Uplifting" key="moods" value="uplifting" v-model="checkboxFilter.moods">
<label for="Uplifting">Uplifting</label><br>
<input type="checkbox" id="Tense" key="moods" value="tense" v-model="checkboxFilter.moods">
<label for="Tense">Tense</label><br>
</div>
<div class="genres"><P></P><br>
<input type="checkbox" id="Crazy" key="moods" value="crazy" v-model="checkboxFilter.moods">
<label for="Crazy">Crazy</label><br>
<input type="checkbox" id="Funny" key="moods" value="funny" v-model="checkboxFilter.moods">
<label for="Funny">Funny</label><br>
<input type="checkbox" id="Soaring" key="moods" value="soaring" v-model="checkboxFilter.moods">
<label for="Soaring">Soaring</label><br>
<input type="checkbox" id="Childish" key="moods" value="childish" v-model="checkboxFilter.moods">
<label for="Childish">Childish</label><br>
</div>
<div class="genres"><h1>TEMPO</h1><br>
<input type="checkbox" id="vfast" key="tempo" value="vfast" v-model="checkboxFilter">
<label for="vfast">Very Fast</label><br>
<input type="checkbox" id="fast" key="tempo" value="fast" v-model="checkboxFilter">
<label for="fast">Fast</label><br>
<input type="checkbox" id="moderate" key="tempo" value="moderate" v-model="checkboxFilter">
<label for="moderate">Moderate</label><br>
<input type="checkbox" id="slow" key="tempo" value="slow" v-model="checkboxFilter">
<label for="slow">Slow</label><br>
</div>
<div class="genres"><h1>THEMES</h1><br>
<input type="checkbox" id="Corporate" key="theme" value="corporate" v-model="checkboxFilter">
<label for="Corporate">Corporate</label><br>
<input type="checkbox" id="Technology" key="theme" value="technology" v-model="checkboxFilter">
<label for="Technology">Technology</label><br>
<input type="checkbox" id="Food" key="theme" value="food" v-model="checkboxFilter">
<label for="Food">Food</label><br>
<input type="checkbox" id="Education" key="theme" value="education" v-model="checkboxFilter">
<label for="Education">Education</label><br>
</div>
<div class="genres"><P></P><br>
<input type="checkbox" id="Travel" key="theme" value="travel" v-model="checkboxFilter">
<label for="Travel">Travel</label><br>
<input type="checkbox" id="Sport" key="theme" value="sport" v-model="checkboxFilter">
<label for="Sport">Sport</label><br>
<input type="checkbox" id="Fashion" key="theme" value="fashion" v-model="checkboxFilter">
<label for="Fashion">Fashion</label><br>
<input type="checkbox" id="Landscape" key="theme" value="landscape" v-model="checkboxFilter">
<label for="Landscape">Landscape</label><br>
</div>
</div>
<template v-for='song in filteredSongs'>
<div class="songlayout" >
<div class='wrapper'>
<div>
<img :src="song.cover_art_url" alt="" class='img-fluid rounded'>
</div>
<button class="button_7" @click='openLicense(song.license_url)'>License</button>
<h1 class='song-title'>{{song.title}}</h1>
<p class="song-description" >{{song.description}}</p>
<div class="overlay-play text-center" v-if="isPlaying && (currentSong.id === song.id )" @click='pause'>
<i class="icon ion-ios-pause"></i>
</div>
<div class="overlay-play text-center" @click='play(song)' v-else>
<i class="icon ion-ios-play"></i>
</div>
</div>
</div>
</template>
</div>
new Vue({
el: '#app',
data: {
isPlaying: '',
songs: [
{
id: 1,
title: "Track 1",
description: "Description 1",
url:"./mp3/track1.mp3",
keywords: "achievement, advertising, background, beautiful, beauty, business, business music, commercial, company, confident, corporate, corporate background, corporate presentation, corporate presentations music, corporate video, corporation, corporative, happy",
genre:"pop, rock",
moods:"uplifting, upbeat, playful",
tempo:"moderate",
theme:"corporate",
},
{
id: 2,
title: "Track 2",
description: "Description 2",
url:"./mp3/track2.mp3",
keywords: "scary, horror, Armageddon, Big Ending, Dramatic, End Of The World, Escape, Fantasy, Film, Film Score, Foreboding, Haunted House, Haunting, Nervous, Nightmare, Pensive",
genre:"epictrailer",
moods:"tense, dramatic, disturbing",
tempo:"moderate",
theme:"landscape",
},
{
id: 3,
title: "Track 3",
description: "Description 3",
url: "./mp3/track3.mp3",
keywords:"Armageddon, Battle, Big Ending, Bomb, Break Out, Busy, Chase, Chilled, Covert Ops, Detective,",
genre:"epictrailer",
moods:"dramatic, soaring, hopeful",
tempo:"moderate",
theme:"sport",
},
],
search: "",
checkboxFilter: {genre: [], moods: []},
},
computed: {
filteredSongs: function(value, key){
let fltrdSongs = this.songs;
// checking if "genre" and "moods" arrays have elements in any of them
if(this.checkboxFilter.genre.length + this.checkboxFilter.moods.length > 0) {
// checking if "genre" array has elements
if (this.checkboxFilter.genre.length > 0) {
fltrdSongs = this.songs.filter((song) => {
let length = this.checkboxFilter.genre.length;
while(length--){
if ((song.genre).indexOf(this.checkboxFilter.genre[length])!=-1) {
return true;
}
}
});
}
// checking if "moods" array has elements
if(this.checkboxFilter.moods.length > 0) {
fltrdSongs = fltrdSongs.filter((song) => {
let length = this.checkboxFilter.moods.length;
while(length--){
if ((song.moods).indexOf(this.checkboxFilter.moods[length])!=-1) {
return true;
}
}
});
}
}
return fltrdSongs.filter((song) => {
return song.keywords.toLowerCase().match(this.search.toLowerCase()) ||
song.title.toLowerCase().match(this.search.toLowerCase()) ||
song.description.toLowerCase().match(this.search.toLowerCase())
});
}
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.