I have a list of users from an array. And I want to filter them based on the search box(name) at the top. I saw that there are filters in VueJS 1. But not available in VuesJS 2.
I have done this by having my property "array" with the data elements and a computed property (array as well) with the filtered elements. The HTML renders the filtered elements. I have a property bound to the text box. For simplicity, something like this:
data: function () {
return{
search: '',
customers: [
{ id: '1', name: 'user 1', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'ab@gmail.com', phone:'+91959657248', unread:'0' },
{ id: '2', name: 'user 2', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'abcd@gmail.com', phone:'+919456664023', unread:'0' },
{ id: '3', name: 'user 3', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'test@gmail.com', phone:'+919566565065', unread:'0' },
{ id: '4', name: 'user 4', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'sample@gmail.com', phone:'+916466004566', unread:'0' }
]
},
computed:
{
filteredCustomers:function()
{
var self=this;
return this.customers.filter(function(cust){return cust.name.toLowerCase().indexOf(self.search.toLowerCase())>=0;});
}
}
Bind your HTML to filteredCustomers. You should now have a reactive HTML based on what you type on search. That "filter" method is native JavaScript for arrays, I lower-cased both values to make it case insensitive.
Here's a working example in fiddle: https://jsfiddle.net/dkmmhf5y/1/
Edit: Added fiddle and code corrections in computed property
`computed: {
filteredResources(){
return this.Surveyors.filter((surveyor)=>{
return surveyor.Name.toLowerCase().match(this.searchQuery.toLowerCase());
})
}
}`
/Surveyors is data table name and surveyor is its index like in your example you are having customer in customers/
I like the answer by Nathan but I think this would work better and it eliminates the need for the var self = this
assignment. It will also keep eslint happy as the Vue eslint plugin frowns upon using indexOf
when looking for existence. Here it is:
data: function () {
return{
search: '',
customers: [
{ id: '1', name: 'user 1', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'ab@gmail.com', phone:'+91959657248', unread:'0' },
{ id: '2', name: 'user 2', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'abcd@gmail.com', phone:'+919456664023', unread:'0' },
{ id: '3', name: 'user 3', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'test@gmail.com', phone:'+919566565065', unread:'0' },
{ id: '4', name: 'user 4', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'sample@gmail.com', phone:'+916466004566', unread:'0' }
]
},
computed:
{
filteredCustomers () {
return this.customers.filter((customer) => {
return customer.name.toLowerCase().includes(this.search.toLowerCase())
})
}
}
Filters has been removed in vuejs 2. As suggested by @azamat-sharapov, you can have reusable filters using one of following 3 ways:
How can I do it in 2.0?
- Mixin
- Separate module with method
- Separate module with computed prop function
A simple implementation of filter in vuejs 2 can be using a computed property which can call a method to get filtered list. in the method you can pass list, query and it can return the filtered list. see following code and working demo here. Following are generic functions, which can be moved to mixin or module and can be re-used in multple components.
var vm = new Vue({
el: '#demo',
data: {
customers: [
{ id: '1', name: 'user 1', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'ab@gmail.com', phone:'+91959657248', unread:'0' },
{ id: '2', name: 'user 2', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'abcd@gmail.com', phone:'+919456664023', unread:'0' },
{ id: '3', name: 'user 3', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'test@gmail.com', phone:'+919566565065', unread:'0' },
{ id: '4', name: 'user 4', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'sample@gmail.com', phone:'+916466004566', unread:'0' }
],
columns: {
id : {
displayname : "id",
sortorder : 1
},
name : {
displayname : "name",
sortorder : 1
},
email : {
displayname : "email",
sortorder : 1
}
},
query: '',
},
computed: {
tableFilter: function () {
return this.findBy(this.customers, this.query, 'name')
}
},
methods: {
findBy: function (list, value, column) {
return list.filter(function (item) {
return item[column].includes(value)
})
}
}
})
<!-- Searching Bar Start -->
<div class="form-group mb-2">
<span style="float:left; margin:0 10px; padding-top:5px; color:black;">Search:</span>
<input v-model="search" class="form-control" placeholder="Filter users by Queue" style="width:30%;">
</div>
<!-- Searching Bar End -->
<td style="width:25%;cursor:pointer;color: blue;" class="tablecolthree" @click="sortbytotal('pending_duration_day')">Pedning Duration <i class="fa fa-sort" aria-hidden="true"></i></td>
return {
search:'',
dupsearch:'',
currentSort:'pending_duration_day',
currentSortDir:'asc',
}
methods: {
sortbytotal:function(s) {
this.dupsearch='sort';
this.search='';
if(s === this.currentSort) {
this.currentSortDir = this.currentSortDir==='asc'?'desc':'asc';
}
this.currentSort = s;
},
date(e){
if(this.stdate){
var fromdate = [];
this.loading = true;
fromdate.push(moment(this.stdate).format('YYYY-MM-DD'));
this.showstart = moment(this.stdate).format('MMM DD, YYYY');
axios.get('/open-ticket-detail?date='+fromdate).then(response => {
this.openticketdetail = response.data;
this.loading = false;
//console.log(this.openticket);
})
}
e.preventDefault();
}
},
computed:{
sortedCats:function()
{
var self=this;
if(self.search!=''){
this.dupsearch='';
}
if(this.dupsearch=='sort'){
return this.openticketdetail.open_tickets.sort((a,b) => {
let modifier = 1;
if(this.currentSortDir === 'asc') modifier = -1;
if(a[this.currentSort] < b[this.currentSort]) return -1 * modifier;
if(a[this.currentSort] > b[this.currentSort]) return 1 * modifier;
return 0;
});
}
return this.openticketdetail.open_tickets.filter(function(openticket){return openticket.queue_name.toLowerCase().indexOf(self.search.toLowerCase())>=0;});
},
},
This method worked good for me
computed: {
filteredList() {
return this.postList.filter(post => {
var vm = this;
return post.title.toLowerCase().includes(vm.search.toLowerCase())
})
}
}