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

bedakb's avatar

VueJS - Multiple filterBy values

Hello everyone.

I have JSON file that contains some objects.One that I'm interested in, and that I use for filtering is PAID. It could have value that is equal to 0 (mean not paid), and equal to 1 (mean paid).

The problem is that I have to output the all not paid items, + additional 20 paid items

If I try to do something like this, it won't work for sure:

<tr v-for="item in items | filterBy searchInvoice | filterBy '0' in 'paid' | filterBy '1' in 'paid' | limitBy 20">
    <!--Nothing important here-->
</tr>

I also tried to create custom Vue filter, but no luck, same issue:

Vue.filter('openedInvoices', function(value,paid) {
    return value.filter(function(item) {
        return item.paid == paid;
    });
});

Thanks

0 likes
14 replies
davestewart's avatar

I do know that loop filters are being removed in Vue 2.0 so you might be better making this a computed property, and doing all your calculation in there:

<tr v-for="item in filteredItems">
   <!--Nothing important here-->
</tr>
computed:
{
    filteredItems:function()
    {
        return this.items.filter( ... );
    }
}
2 likes
bedakb's avatar

Hi @davestewart , thank you for response.

I'm pretty new in VueJS world, so could you please explain it a bit more.

Thanks.

davestewart's avatar
Level 11

Sure thing.

So computed properties are pretty much the best thing about Vue. Rather than setting "dumb" values like you used to, you specify values as functions in your computed property in your Vue / component definition. This is then converted into a JS getter, so later you just reference the property, but it runs a function to return a value:

myComponent.filteredItems; // does a calculation and returns a filtered list

So for your list, you're limited by the syntax you can write in an expression, so if you're hitting the limits of that, move the heavy lifting to a more explicit computed property:

computed:
{
    filteredItems:function()
    {
        return this.items
            .filter(function(item)
            {
                return item.someProp == 'some value'; // I don't know what your "searchInvoice" is, this is just dummy code
            })
            .filter(function(item)
            {
                return item.paid == 0 || item.paid == 1;
            })
            .slice(0, 20);
    }
}

You can reference this from anywhere:

console.log(this.filteredItems);

Or set other values that affect it:

{
    // previous filtering
    return this.items.slice(this.currentPage, this.pageLength);
}

Make sense?

3 likes
bedakb's avatar

Thank you so much @davestewart , this did the trick.

The searchInvoice is set as v-model on input, so It just search the items, so in mine data object, searchInvoice is set to empty string, and it was attached to v-for as the filter.

1 like
bedakb's avatar

Hey @davestewart , your code works good but there are things that I forgot on.

  1. There should be the button, that filter all items (not only 20)

2.The slice method is not the best option because it output the 20 items of all e.g - if I have 3 not paid items, it would show 17 paid items, instead the 20.

I tried something like this but get bunch of errors in console:

    computed: {
        filteredItems: function() {
          
            count = 0;

            return this.items

                .filter(function(item) {

                  if(item.paid == 0){
                    return true;
                  }else{
                    if(count < 20){
                      count++;
                      return true;
                    }
                  }

                  return false;
                })
        },
    }

There are errors

https://s32.postimg.org/6x9wuo2qd/Screen_Shot_2016_06_30_at_11_15_38.png

Any suggestion ? Thanks.

EDIT: About errors I forgot to close quote sign (") :) So thing 2 is solved.

davestewart's avatar

Not sure if that's a binding issue, or something else.

What does a console.log(this, this.items) from within filteredItems output?

bedakb's avatar

I'm not sure does we mean on same thing, did you read this :) ?

EDIT: About errors I forgot to close quote sign (") :) So thing 2 is solved.

About filtering all method.

I had one method that filter only opened items, it looks like this

        filterOpened: function(paid) {
            this.openInvoice = paid;
        },

Then I just make the event that fire the filterOpened function with value 0

<a href="#" @click.prevent="filterOpened('0')">Open Invoices</a>

And for sure, on v-for directive I had to assign this

filterBy openInvoice in 'paid'

Is there maybe way to reuse this to show all invoices from json file ? If I set empty value to filterOpened(''), it won't work - basically it would work but it would be limited again, it won't show everything.

davestewart's avatar

Sorry bud, that's a bit vague for me!

It looks like you're mixing things up a fair bit there; strings for numbers, functions for assignments, list filters with expressions.

Maybe you want to put some sample code into JSFiddle or CodePen to make it easier for folks who'd like to give you a hand :)

1 like
bedakb's avatar

Sorry for that, I'll try to explain it better.

Unfortunately can't provide code public, but I use this example to make button filtering https://jsfiddle.net/quetzalarc/LdcdLqe3/2/

The main issue is that I can't find the way to display all items from JSON file.

I could maybe send the code to private message (I'm not sure does laracasts forum has them) - or maybe better I will make some fake api and provide here.

Thank you.

davestewart's avatar

OK, that's a bit of a mess to be honest!

  • Your JSON is invalid. I had to correct it before parsing
  • Why are you passing numbers as strings in the data?
  • I trimmed out all the extra functions, this is a demo after all
  • Not sure why you are loading images and logos, see above point

Start with this: https://jsfiddle.net/cjrqqj5L/1/

The reason your precious demo was failing with this.items.filter is not a function was because items is a string, not an array.

  • You need to parse JSON before assigning it
  • You had items as a default string in your data, it should really be []

Does that get you where you need to be?

1 like
bedakb's avatar

@davestewart thank you so much, beer on me :)

I'm pretty new in VueJS World, started with learning few days ago, so that's the probabbly reason why it's messy.

About images - it's just design stuff, I have to put some svg icons.

Still tricky thing is the Show all filter, it's still don't output everything, seems like it can't exceed the 20 items.

Any suggestion about that ?

Thanks

Please or to participate in this conversation.