Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vuejs Search filter

I have a table that is presenting a list of items that I got using the following code:

interface getResources {
    title: string;
    category: string;
    uri: string;
    icon: string;
}
@Component
export default class uservalues extends Vue {

    resources: getResources[] = [];

    created() {
        fetch('api/Resources/GetResources')
            .then(response => response.json() as Promise<getResources[]>)
            .then(data => {
                this.resources = data;
            });
        }
    }
}

And this is my table:

 <div class="panel panel-default">
     <div class="panel-heading" style="font-weight:bold"><span class="glyphicon glyphicon-align-justify"></span> All Resources</div>
         <div class="row">
             <div class="search-wrapper panel-heading col-sm-12">
                 <input class="form-control" type="text" v-model="searchQuery" placeholder="Search" />
             </div>                        
         </div>
         <div class="panel-body" style="max-height: 400px;overflow-y: scroll;">
             <table v-if="resources.length" class="table">
                 <thead>
                     <tr>
                         <th>Resource</th>
                     </tr>
                 </thead>
                 <tbody>
                     <tr v-for="item in resources">
                         <td><a v-bind:href="item.uri" target="_blank">{{item.title}}</a></td>
                     </tr>
                 </tbody>
             </table>
         </div>
     </div>
</div>

I'm trying to implement a Search bar that filters the results for the user but I'm lost!

Any suggestions?

like image 751
user3376642 Avatar asked Sep 28 '18 15:09

user3376642


People also ask

How do you implement a search on Vue?

Creating the search bar component in Vue In Vue, all the Single-File Components must be wrapped in the template tag. Vue is going to compile everything inside it into the Virtual DOM. We also created the input field itself. We set the type to text because we will enter the search queries inside it.

How do I sort a list in Vue?

The Grid component has support to sort data bound columns in ascending or descending order. This can be achieved by setting allowSorting property as true. To dynamically sort a particular column, click on its column header.

How do I get data from JSON file in Vue?

To get data from a local JSON file, we need to import the file into the component where we want to process the data. We do the import just like we would with a component, except the component name is replaced with whatever we want to call the data set.


2 Answers

You can use the includes() function of the array to search any position in a sentence or phrase.

new Vue({
  el: '#app',
  data() {
    return {
        searchQuery: null,
        resources:[
            {title:"ABE Attendance",uri:"aaaa.com",category:"a",icon:null},
            {title:"Accounting Services",uri:"aaaa.com",category:"a",icon:null},
            {title:"Administration",uri:"aaaa.com",category:"a",icon:null},
            {title:"Advanced Student Lookup",uri:"bbbb.com",category:"b",icon:null},
            {title:"Art & Sciences",uri:"bbbb.com",category:"b",icon:null},
            {title:"Auxiliares Services",uri:"bbbb.com",category:"b",icon:null},
            {title:"Basic Skills",uri:"cccc.com",category:"c",icon:null},
            {title:"Board of Trustees",uri:"dddd.com",category:"d",icon:null}
        ]
    };
  },
  computed: {
    resultQuery(){
      if(this.searchQuery){
      return this.resources.filter((item)=>{
        return this.searchQuery.toLowerCase().split(' ').every(v => item.title.toLowerCase().includes(v))
      })
      }else{
        return this.resources;
      }
    }
  }
 

})
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" >

</head>
<body>
<div id="app">
   <div class="panel panel-default">
   <div class="panel-heading">
         <strong> All Resources</strong></div>
            <div class="row">
                 <div class="search-wrapper panel-heading col-sm-12">
                     <input class="form-control" type="text" v-model="searchQuery" placeholder="Search" />
                </div>                        
            </div>
        <div class="table-responsive">
            <table v-if="resources.length" class="table">
                <thead>
                    <tr>
                         <th>Resource</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="item in resultQuery">
                        <td><a v-bind:href="item.uri" target="_blank">{{item.title}}</a></td>
                    </tr>
                </tbody>
            </table>
        </div>
   </div>
   </div>

</body>
</html>

Based on this answer → Vue.js search keyword in array

like image 51
Vladimir Salguero Avatar answered Oct 07 '22 22:10

Vladimir Salguero


You could use computed property for this case, so, i created one called filteredResources which will be used in v-for loop, i had used dummy data, but you could keep your resources declared empty and call a promise function to fill it in created hook, check this code if your are preferring single file component or the following code of you're using Vue via CDN

new Vue({
  el: '#app',
  data() {
    return {
      searchQuery:'',
    resources:[
    {title:"aaa",uri:"aaaa.com",category:"a",icon:null},
     {title:"add",uri:"aaaa.com",category:"a",icon:null},
      {title:"aff",uri:"aaaa.com",category:"a",icon:null},
    {title:"bbb",uri:"bbbb.com",category:"b",icon:null},
    {title:"bdd",uri:"bbbb.com",category:"b",icon:null},
    {title:"bsb",uri:"bbbb.com",category:"b",icon:null},
    {title:"ccc",uri:"cccc.com",category:"c",icon:null},
    {title:"ddd",uri:"dddd.com",category:"d",icon:null}
    ]
    };
  },
  computed: {
    filteredResources (){
      if(this.searchQuery){
      return this.resources.filter((item)=>{
        return item.title.startsWith(this.searchQuery);
      })
      }else{
        return this.resources;
      }
    }
  }
 

})
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" >

</head>
<body>
<div id="app">

   <div class="panel panel-default">
                <div class="panel-heading" style="font-weight:bold"><span class="glyphicon glyphicon-align-justify"></span> All Resources</div>
                <div class="row">
                    <div class="search-wrapper panel-heading col-sm-12">
                        <input class="form-control" type="text" v-model="searchQuery" placeholder="Search" />
                    </div>                        
                </div>
                <div class="panel-body" style="max-height: 400px;overflow-y: scroll;">
                    <table v-if="resources.length" class="table">
                        <thead>
                            <tr>
                                <th>Resource</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="item in filteredResources">
                                <td><a v-bind:href="item.uri" target="_blank">{{item.title}}</a></td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
</div>

</body>
</html>
like image 35
Boussadjra Brahim Avatar answered Oct 07 '22 23:10

Boussadjra Brahim