0

I am putting together a simple book sorter app and I am having some trouble using the filterBy filter. The filter works fine for filtering the non-fiction genre but for some reason it does not work for fiction. I want to display the book titles and authors, and then in the input field, filter through the list of books being displayed by genre. So if I write fiction in the input field, it should only display the fiction books. This is what my view looks like:

       <div id="app">
            <h1>{{title}}</h1>
              <div id="input">
               <input type="text" v-model="genre" placeholder="Search fiction/non-fiction">
            </div>
             <div id="display-books" v-for=" book in books | filterBy genre in 'genre' ">
               <span>Title: {{book.title}}</span>
               <span>Author: {{book.author}}</span>      
        </div>  
    </div>

And here is my app.js:

var appData = { 
  title: 'Book Sorter',
  filters: 'Search filter',
  filtertext: '* only show title if book is available',
  genre: '',
  books:
    [
      {genre: "fiction", title: "The Hobbit", author: "J.R.R Tolkien", available: false},
      {genre: "non-fiction", title: "Homage to Catalonia", author: "George Orwell", available: true},
      {genre: "non-fiction", title: "The Tipping Point", author: "Malcolm Gladwell", available: false},
      {genre: "fiction", title: "Lord of the Flies", author: "William Golding", available: true},
      {genre: "fiction", title: "The Call of the Wild", author: "Jack London", available: true}   
    ]

}
new Vue({
   el: "#app",
   data: appData,

});

1 Answer 1

1

There is no problem with your setup, Vue's filterBy is working fine in your example. When you type fiction, it will show all Books because they all have the word fiction in the genre, meaning that: fiction and non-fiction both contains fiction, returning true.

Create a custom filter like this:

Vue.filter('match', function (value, input) {
  return input ? value.filter(function(item) {
     return item.genre === input ? value : null;
  }) : value;
});

And change selection from an input to dropdown:

<select v-model="genre">
    <option value="" selected>Select Genre</option> 
    <option value="fiction">Fiction</option>
    <option value="non-fiction">Non-Fiction</option>
</select>

Here is a fiddle implementing it: https://jsfiddle.net/crabbly/br8huz7c/

Sign up to request clarification or add additional context in comments.

3 Comments

Would I need to use an exact match filter then?
Exactly. You can probably create a custom filter for that. However, for showing lists like this, you may want to change the input to a dropdown. This way, it will only trigger an event when the user select the desired genre.
I added a fiddle as an example. Check it out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.