Thank you to Khalid Ali for helping me so far up to this point.
So there is an array of songs that have descriptions, keywords etc. there is 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”. However, if I also select Epic Trailers, it returns all songs with “pop” AND all songs with “epictrailers” in their genre. What I would like is for it to return songs with both genres only. For example - genre: “pop, epictrailers”,
In the array below you’ll see that song 2 and song 3 both have “dramatic” in moods. But song 2 also has “tense” and song 3 also has “soaring”. 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”.
So in short, it to return only songs that include ALL checked boxes.
I hope this makes sense…
HTML SNIPPETS:
<div id=”app”>
<div class=”search-music”>
<input type=”text” v-model=”search” placeholder=”Enter a keyword to refine the 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:
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())
});
},},
Solution :
the filteredSongs computed property never reaches the this.checkboxFilter.length if statement because of the return statement before it.
Replace the filteredSongs computed property with the following one:
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
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
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”
JS: changing the checkboxFilter data property to checkboxFilter: {genre: [], moods: []}. Also changed the filteredSongs computed property
<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 the 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())
});
}
}
});