Grid filter by all columns using only one filter field

Hi dear vaadin forum users! I’m continue learn vaadin framework and faced one problem, this is grid filter. I watched some tutorials like [this]
(https://www.youtube.com/watch?v=Ty3dhCkQP1E), but this solution has one big problem, this is cost of request, each time when customer filter data, it request database, so what if there will be more than thousands rows and more than hundred users, which will filter data at same time? I can store data in a RAM or use Spring cache or even Redis to reduce the load, but it is to much code just to filter table by using only one text filed and filter by any column or row.
Actually I would like to have something like [this]
(https://www.w3schools.com/jquery/jquery_filters.asp) it looks simple and short and it don’t uses database to filter data. Someone can tell why I’m not using jquery for that? So I have low knowledge about JS and JQuery, I already tried to integrate this to my grids, but no success. What i did is just add class name to my grid and text filed and tried to modify js script by changing access by id to access by class selector.
Is there simple solution for vaadin to implement something like example on w3schools?

I’m also looking for same solution :slight_smile:

I think you should save the list that you get from the source and when filtering do it on the list and not make a new request to the source when typing in the search field.
The solution I think does not have to do with Vaadin but with a logic in Java.

I had a need to develop something similar, a search term that applies to all columns. I implemented it the way Diego mentioned in the previous post. The value change listener on the single search field applies the search condition to all of the columns in the grid purely in Java.

Hi Stanislav,

Generally speaking, you want to let each tier of your architecture do their work. Thousands of rows is not a problem for a database, neither is hundreds of users.

Offloading/caching in other tiers (outside of spring caching) may lead to overly complex code and risk of stale data.

My recomnendation would be to let the data provider and database do their job, but (if anything) tune the size of the result objects, i.e. dont fetch the entire object if you’re only showing a small piece of the data (if you use JPA, take a look at entity graphs).

Stanislav Wong:
Hi dear vaadin forum users! I’m continue learn vaadin framework and faced one problem, this is grid filter. I watched some tutorials like [this]
(https://www.youtube.com/watch?v=Ty3dhCkQP1E), but this solution has one big problem, this is cost of request, each time when customer filter data, it request database, so what if there will be more than thousands rows and more than hundred users, which will filter data at same time? I can store data in a RAM or use Spring cache or even Redis to reduce the load, but it is to much code just to filter table by using only one text filed and filter by any column or row.
Actually I would like to have something like [this]
(https://www.w3schools.com/jquery/jquery_filters.asp) it looks simple and short and it don’t uses database to filter data. Someone can tell why I’m not using jquery for that? So I have low knowledge about JS and JQuery, I already tried to integrate this to my grids, but no success. What i did is just add class name to my grid and text filed and tried to modify js script by changing access by id to access by class selector.
Is there simple solution for vaadin to implement something like example on w3schools?

Hi there, I found solution for this thread. Let me describe it, So we have view, entity and service. What we need to do is create method in service which will filter entities by all information which entity have. I did it by using regex. My method just get string representation of entity and then calling string mathes method. Something like this:

public List<Tour> filter(String string) {
        return tours.stream()
                .filter(tour -> tour.toString().toLowerCase().matches(String.format("(.*)%s(.*)", string.toLowerCase())))
                .collect(Collectors.toList());
    }

Then in a view create new method to call service method. Like this:

@Override
    public void filter(String string){
        grid.setItems(tourService.filter(string));
    }

And finally in a view call filter method inside text field addValueChangeListener like this:

driversTextField.addValueChangeListener(s -> {
            if (s.getValue() == null || s.getValue().isEmpty()) {
                grid.setItems(tourService.getAll());
            } else {
                //filterByDriver(s.getValue());
                filter(s.getValue());
            }
        });

As result grid will be filtered using only one filed but will use all information of entity to filter.
Yes it is not the best/elegance solution, but it solves problem of this thread.
Now i have another problem, how to use only one field, but filter many grids ))) I created another thread about this if you interesting navigate [here]
(https://vaadin.com/forum/thread/18368058/grid-filter-not-updates-items-in-a-grid). I found somethink that looks like a solution, but it works not always it with some strange bugs))

You have different ways to manage the grid data.
You can use In Memory DataProvider and Lazy Loading data provider.

  • InMemoryDataProvider will store the entire list in memory, then you can filter, sort … in Java (you make a find all at the beginning).
  • Lazy Loading data provider will only need the size of the list and the current page. All the operation (sort, scroll down, filter) will require at least 1 or 2 queries to your backend.

To filter a In Memory DataProvider you can check this example: https://vaadin.com/docs/v14/flow/binding-data/tutorial-flow-data-provider.html#filtering-in-memory-data
As it’s inmemory, there is no need to call the service layer to filter it.

You shouldn’t use a list property in your Service layer, it’s ok for test purpose but as a service in a singleton it’s shared for all the users and could be accessed/modified by everyboday at the same time, You will have ConcurrentModificationException as soon as 2 users will update it at the same time.

I would also avoid the EAGER mode on the Filter TextField because it will trigger the filter for each change. TextField LAZY or TIMEOUT is better.

To answer your last question, you can do everything you want when the filter text changes:

filterTextField.addValueChangeListener(s -> {
            // filter driver grid
			// filter xx grid
			// filter yy grid
        });

If all the grid are not visible then you should probably avoid to filter the hidden grid (and filter it once they are visible).