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.