Home > Back-end >  How to use filter and search bar on the same form in VueJS 2
How to use filter and search bar on the same form in VueJS 2

Time:06-29

Here is my code:

<div >
  <h3>Filter <img id="icon-filter" @click="showfilter" :style="{ 'display': display.btn_show_filter }" src="../assets/recruit/angle-down-svgrepo-com.svg" alt=""> <img id="icon-close-filter" :style="{ 'display': display.btn_close_filter }" @click="closefilter" src="../assets/recruit/close-svgrepo-com.svg" alt=""></h3>
  <div   id="group-filter" :style="{ 'display': display.group_filter }" >
    <div  v-for="(check, index) in checks" :key="index">
      <input type="radio" :id="index"  name="fav_language" :value="check" v-model="selected" >
      <label  :for="index">{{check}}</label><br>
    </div>
  </div>
  </div>
  <div >
    <div >
      <div >
        <input type="search" v-model="search" placeholder="Nhập từ khóa để tìm kiếm">
        <button @click="search"><img src="../assets/recruit/search.svg" alt=""></button>
      </div>
    </div>
    <div   v-for="(item, index) in filtered" :key="index">
   <a href=""><h3 >{{item.position}}</h3></a>     
    <div>
      <img src="../assets/recruit/years.svg" alt="">
      <b>{{item.exprerience}}</b>
    </div>
    <div>
      <img src="../assets/recruit/luong.svg" alt="">
      <b>{{item.salary}}</b>
    </div>
    <div>
      <img src="../assets/recruit/diadiem.svg" alt="">
      <b>{{item.headequarters}}</b>
    </div>
    <h6>{{item.createdAt}}</h6>
</div>
<ul>
  <li>{{item.content1}}</li>
  <li>{{item.content2}}</li>
  <li>{{item.content3}}</li>
</ul>

I've done with the filter, but I'm having trouble building the search bar....... i'm using the filtered checkbox to handle the filter but i still haven't figured out how to make both work and show the same place.

My logic code:

export default {
  data(){
     return{     
       checks:['All','Developer','Tester', 'Designer', 'Support',],
       infojobs:[{
                  genres: 'Developer',
                  position:'Senior Java Engineer, Big Data',
                  exprerience:'3-5 Years',
                  salary:'',
                  headequarters:'',
                  content1:'1',
                  content2:'2
                  createdAt: "3"
                 },
                 {
                  genres: 'Designer',
                  position:'Creative professional designer ',
                  exprerience:'1-3 Years',
                  salary:'',
                  headequarters:'',
                  content1:'',
                  content2:'1',
                  content3:'2',
                  createdAt: "3"
                  }
        ],
        selected: 'All',
      }
    },
    computed: {
      filtered() {
        console.log(this.selected)
        if(this.selected=='All'){
            return this.infojobs
        }
        else{ 
          return this.infojobs.filter(i => i.genres === this.selected)
        }
    },                
  },

I hope to handle the search bar and filter without conflict, hope to get some help, thanks a lot...

CodePudding user response:

computed: {
  filtered() {
    let finalFilter = [...this.infojobs];
    console.log(this.selected)
    if (this.selected !== 'All') {
      finalFilter =this.infojobs.filter(i => i.genres === 
    }
    if (this.search.trim()) {
      finalFilter  = finalFilter.filter((i) => Object.values(i).some(v => v.toLowerCase().includes(this.search.toLowerCase())
    }
    return finalFiter
  },                
},

You don't need if-else both. just use if condition.

CodePudding user response:

You can try using the watchers.

Code explanation:

  • Define an extra variable showJobs in data()
  • Place a watcher on selected variable which will show the jobs on basis of filter selection
  • Place a watcher on search variable which triggers the search functionality only if user inputs more than 2 characters, if not, we will be showing default filtered jobs. In addition, we can use debounce to add a delay of 500ms while searching the jobs.

watch: {
 selected(newVal) {
   if (newVal === "All") {
     this.showJobs = this.infojobs;
   } else {
     this.showJobs = this.infojobs.filter((i) => i.genres === newVal);
   }
 },

 search: _.debounce(function (newVal) {
   if (newVal.length > 2) {
     let searchedJobs = this.showJobs.filter((job) =>
       job.position.toLowerCase().includes(newVal.toLowerCase())
     );

     this.showJobs = searchedJobs;
   } else {
     if (this.selected === "All") {
      this.showJobs = this.infojobs;
     } else {
      this.showJobs = this.infojobs.filter((i) => i.genres === this.selected);
    }
   }
 }, 500)
}

Note: You need import debounce from lodash library in the component.

  • Related