0

How can I filter data when button pressed using json files on Vue js. I want to filter by category which is inside each object on data.

portfolio-v1.json

    {
  "data":[
    {
      "image_path":"static/products/DELUXE-BATHROBE.jpg",
      "title":"Beautiful Designs",
      "heading":"Lorem Ipsum is simply dummy.",
      "content": "Lorem Ipsum is simply dummy text of the printing and typesetting industry.",
      "vendor":"George Courey",
      "category":"Blanket"
    },
    {
      "image_path":"static/products/HOME-CARE-SLIP-PAD.png",
      "title":"Mutifunctionals Blocks",
      "heading":"Lorem Ipsum is simply dummy.",
      "content": "Lorem Ipsum is simply dummy text of the printing and typesetting industry.",
      "vendor": "George Courey",
      "category": "Blanket"
    },
    {
      "image_path":"static/products/HERRINGBONE-THERMAL-BLANKET.jpg",
      "title":"Vuejs App For Game",
      "heading":"Lorem Ipsum is simply dummy.",
      "content": "Lorem Ipsum is simply dummy text of the printing and typesetting industry.",
      "vendor": "George Courey",
      "category": "Blanket"
    }
  ]
}

portfolioGrid.vue

<template>
  <div class="row col-space">
    <!-- START PORTFOLIO FILTER AREA -->
    <div class="col-12">
      <div class="text-center">
        <div class="portfolio-filter mb-40">
          <button class="active" data-filter="*">Show all</button>
          <button data-filter=".cat1">Linens</button>
          <button data-filter=".cat2">Blankets</button>
          <button data-filter=".cat3">Protective Products</button>
          <button data-filter=".cat4">Top Sheets</button>
          <button data-filter=".cat5">Staff Apparel</button>
          <button data-filter=".cat6">Towels</button>
          <button data-filter=".cat7">Bathrobes & Slippers</button>
        </div>
      </div>
    </div>
    <!-- END PORTFOLIO FILTER AREA -->
    <div v-for="(portfolio,index) of portfoliov1.data.slice(0,showNoOfPosts)" :key="index"
         class="col-sm-12 col-md-6 col-lg-4 ">
      <div class="overlay-wrap">
        <img :src="portfolio.image_path" alt="gallery images" class="img-fluid border-rad w-100" height="500"
             width="500"/>
        <a :href="portfolio.image_path" class="card-img-overlay primary-tp-layer pos-center text-center"
           data-fancybox="images">
                    <span class="center-holder">
                        <a class="ih-fade-down square-40 rounded-circle bg-white shadow-md">
                            <i class="fa fa-plus align-middle"></i>
                        </a>
                    </span>
        </a>
      </div>
    </div>
  </div>
</template>
<script>
import portfoliov1 from 'Components/data/portfolio-v1.json'

export default {
  props: ['showNoOfPosts'],
  data() {
    return {
      portfoliov1
    }
  }
}
</script>
   

I want to just display the items from the category selected on buttons. It should grab the category and check if it was the one selected by user then display only the items that contain that category. How can this be done.

1 Answer 1

1

I would suggest to create a filter variable in your data object like so:

  data() {
    return {
      portfoliov1,
      filter: ""
    }
  }

On click to one of the button, set the value of this variable.

<button class="active" @click="filter = ''">Show all</button>
<button @click="filter = 'Linens'">Linens</button>

And create a computed property to get your filtered data:

computed: {
  portfolio() {
    if (!this.filter) {
      return this.portfoliov1.data;
    }
    return this.portfoliov1.data.filter(p => p.category === this.filter);
  }
}

Then your template becomes:

<div v-for="(p, index) of portfolio.slice(0,showNoOfPosts)"

Side notes

I would also suggest to create your buttons in a v-for loop like so:

<button v-for="category in categories" :key="category" :class="{ 'active': filter === category }" @click="filter = category" />
data() {
  return {
    // ...
    categories: ["Blanket", /* ... */]
  }
}

Note that you would need to handle the "no-filter" case.

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

2 Comments

This works great! However do you happen to know why I am getting broken images path? I believe the filter interferes with the portfolio image_path.
In your template, it should work great with <img :src="p.image_path". Make sure there is no typo.

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.