A few years back I wrote about adding table sorting and paging with Vue.js ("Building Table Sorting and Pagination in Vue.js"). While this post is a bit old, it's still helpful and I know this as a reader reached out to me both thank me for the demo and ask if I could demonstrate filtering. I'm not going to go over everything I did in the previous post so be sure to give it a quick read.

Alright, so I'm assuming you've read that post written in the Way Before Pre-COVID times. If so, you saw me load an array of cats that contain names, ages, breeds, and gender. Here's an example of a few:

{
    "name": "Fluffy",
    "age": 9,
    "breed": "calico",
    "gender": "male"
},
{
	"name": "Luna",
	"age": 10,
	"breed": "long hair",
	"gender": "female"
},

And here's how the old demo rendered:

See the Pen Vue - Sortable Table (3) by Raymond Camden (@cfjedimaster) on CodePen.

It's not terribly pretty, but it gets the job done. So given this as a start, how do we add filtering?

I began by adding an input field for my filter:

<input type="search" v-model="filter">

I used type="search" as it provides a quick way of clearing out values. I added filter to my Vue data with a default value of an empty string.

Now comes the fun part. We currently render the table using sortedCats. This was a computed property based on the "raw" cats array that handled sorting the data and "filtering" to a particular page.

To support filtering based on a search term, I used a new computed property, filteredCats. This new property handles filtering the cats based on user input:

filteredCats() {
	return this.cats.filter(c => {
		if(this.filter == '') return true;
		return c.name.toLowerCase().indexOf(this.filter.toLowerCase()) >= 0;
	})
},

Notice that I lowercase both the original value and the user input. Also notice I only filter based on the name. I could absolutely see filtering on name or breed as well. The important thing is the lowercase. This will make it much easier on the end user.

With this computed property, I then updated sortedCats to base it's value on filteredCats:

return this.filteredCats.sort((a,b) => {

The end result is a Vue computed property based on a Vue computed property, which I knew was possible, but I don't think I've actually used it before.

Edit on 3/12/21: After releasing this blog post yesterday, the reader who originally reached out to me discovered a bug. If you go to page 2 and filter to a value that only has one page, you see an empty page. To fix this, I added a watcher such that when you change the filter value, we reset to page one:

watch: {
  filter() {
    console.log('reset to p1 due to filter');
    this.currentPage = 1;
  }
},

Here's the completed CodePen for you to play with:

See the Pen Vue - Sortable / Searchable Table by Raymond Camden (@cfjedimaster) on CodePen.