简体   繁体   English

多个复选框过滤缩小搜索范围

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM