Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jarichypma's avatar

How to implement a range filter (like between in sql)

Hi fellow Laracasters,

I've got a question I can't figure out myself, hopefully someone can help me out here.

What I've got

My ajax-request returns a dataset which I display on the page with v-for. Using a text-input a user can filter the results. Nothing special so far.

The code looks like this:

<input type="search" class="form-control" v-model="search" >
<tr 
  v-for="match in matching
  | filterBy search
  | orderBy sortKey sortByDesc">

What I want

Next I want to add a date filter where only the records between two dates are shown. I have a column named planned_at where I want to filter on.

// The planned_at year should be at least this value
<input type="number" class="form-control" v-model="minYear">

// The planned_at year should be at the most this value
<input type="number" class="form-control" v-model="maxYear">

My filter actually looks a lot like the jQuery UI solution: http://jqueryui.com/slider/#range

  1. Is it possible to make such a filter work in vuejs?

  2. If yes, how should I do this and what would the code look like?

    1. Using a custom filter?
    2. Specifying a filterBy key?
    3. Any other suggestions?

I've tried various things, but since I'm not really a js-expert I've got no clue where to start.

0 likes
4 replies
fetch404's avatar

Pretty sure that this should work.

What you do in your code:

Vue.filter('between', function (value, min, max) {
  return (value >= min) && (value <= max);
});

Then:

<tr 
  v-for="match in matching
  | filterBy search
  | between minYear maxYear 
  | orderBy sortKey sortByDesc">

Hopefully that works!

jarichypma's avatar

Thanks @fetch404 , you got me in the right direction.

My final code looks like this:

<input type="number" class="form-control" v-model="minYear" max="{{planned_at}}">
<input type="number" class="form-control" v-model="maxYear" min="{{planned_at}}">
<input type="search" class="form-control" v-model="search" placeholder="Filter op...">

<tr 
    v-bind:class="{
    active : match.status == 'H',
    success : match.status == 'A'
    }" 
    v-for="match in matching
    | filterBy search
    | between minYear maxYear
    | orderBy sortKey sortByDesc"
>

And the javascript

filters: {
        between: function(items, min, max){
            
            // initialize counter
            var counter = 0;

            // iterate through items
            items.forEach(function(item){
                // convert planned_at to date object
                var date = new Date(item.planned_at.replace(' ', 'T'));
                // get year from date object
                var yyyy = date.getFullYear();
                
                // remove items from array if not within range
                if( yyyy < min || yyyy > max ){
                    items.splice(counter,1);
                }
                
                // increase counter
                counter += 1;
            })

            return items
        },
},
jarichypma's avatar
jarichypma
OP
Best Answer
Level 5

I made some small changes to prevent unwanted behaviour as a result of reindexing the object while splicing.

        between: function(items, min, max){
            
            // initialize counter
            var counter = 0;

            // array with splicable items
            var splicable = []

            // iterate through items
            items.forEach(function(item){
                // convert planned_at to date object
                var date = new Date(item.planned_at.replace(' ', 'T'));
                // get year from date object
                var yyyy = date.getFullYear();
                
                // add index to splicable array if not within range
                if( yyyy < min || yyyy > max ){
                    splicable.push(counter);
                }

                // increase counter
                counter += 1;
            })

            // reverse splicable array to avoid renumbering index
            // if you start with the lowest number, the array index gets updated everytime you splice an item
            // reversing the index fixes this, removing all the right items from the items-object
            splicable.reverse()
            splicable.forEach(function(index){
                // remove item from items object
                items.splice(index,1);
            })
            
            return items
        }

Please or to participate in this conversation.