Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Search a list while typing in textbox VueJS 2

Tags:

vue.js

vuejs2

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. How can achieve this in VueJS 2

<input type="text" v-model="search"/>   
<div class="row profile" v-for="customer in customers">
 <div class="col-md-offset-1 col-md-3"><img :src="customer.profile_pic" class="profile-pic" /></div>
 <div class="col-md-8"><h4 class="name">{{customer.name}}</h4></div>
</div>
<script>
    data: function () {
      return{
        search: '',
        customers: [
          { id: '1', name: 'user 1', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+91959657248', unread:'0' },
          { id: '2', name: 'user 2', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919456664023', unread:'0' },
          { id: '3', name: 'user 3', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919566565065', unread:'0' },
          { id: '4', name: 'user 4', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+916466004566', unread:'0' }
        ]
      }
    }
</script>
like image 766
Gijo Varghese Avatar asked Jan 18 '17 06:01

Gijo Varghese


4 Answers

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:'[email protected]', phone:'+91959657248', unread:'0' },
          { id: '2', name: 'user 2', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919456664023', unread:'0' },
          { id: '3', name: 'user 3', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919566565065', unread:'0' },
          { id: '4', name: 'user 4', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+916466004566', unread:'0' }
        ]
},
computed:
{
    filteredCustomers () {
      return this.customers.filter((customer) => {
        return customer.name.toLowerCase().includes(this.search.toLowerCase())
      })
    }
}
like image 196
Kelvin Omereshone Avatar answered Sep 24 '22 23:09

Kelvin Omereshone


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:'[email protected]', phone:'+91959657248', unread:'0' },
          { id: '2', name: 'user 2', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919456664023', unread:'0' },
          { id: '3', name: 'user 3', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919566565065', unread:'0' },
          { id: '4', name: 'user 4', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', 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

like image 26
Nelson Rodriguez Avatar answered Oct 18 '22 21:10

Nelson Rodriguez


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:'[email protected]', phone:'+91959657248', unread:'0' },
          { id: '2', name: 'user 2', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919456664023', unread:'0' },
          { id: '3', name: 'user 3', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', phone:'+919566565065', unread:'0' },
          { id: '4', name: 'user 4', profile_pic: 'https://i.stack.imgur.com/CE5lz.png', email:'[email protected]', 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)
      })
    }
  }
})
like image 6
Saurabh Avatar answered Oct 18 '22 19:10

Saurabh


This method worked good for me

computed: {
   filteredList() {
     return this.postList.filter(post => {
       var vm = this;
       return post.title.toLowerCase().includes(vm.search.toLowerCase())
     })
   }
}
like image 1
Afraz Ahmad Avatar answered Oct 18 '22 20:10

Afraz Ahmad