Loading...
Important Notice - Forums is archived

To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Product icon
TUTORIAL

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.

Vaadin 8 add filter to each column of grid dynamically

Naj Htuaf
3 years ago May 28, 2019 3:03pm
Kaspar Scherrer
3 years ago May 29, 2019 8:00am

Hi Jan

I went through the same situation as you. First of all, I think your current approach does not really work - the reasons for this I explained in this post. In short, every change in any of your filter fields will add a filter to the dataProvider. After some valuechanges, there will be too many contradicting filters (the filters are added with AND not OR - all added filters must match an item for it to show up), which will soon result in no matching items. Key sentence in linked post:

for every filter field, add the same ValueChangeListener, which will take all filter values into account when it sets the new filter (with setFilter! let only one filter be active at any time but let that filter include all values you want to filter by)

My solution - also explained in above link - will not only fix abovementioned shortcoming of your solution, but also will it be less code to write for each column filter (you still have to create the filter fields. But you could write a a method for that so your code still looks nice and non-repetitive). If you have questions about my approach, feel free to ask.

// filter fields must be class fields, to access them in onFilterChange
private TextField nameFilter, addressFilter;

private void createFilterFields(){
	HeaderRow filterRow = someGrid.appendHeaderRow();
	
	// for each column you want to filter, create a filter field here like so:
	nameFilter = singleFilterTextField("name", filterRow); 
	addressFilter = singleFilterTextField("address", filterRow); // added another filter to show how multiple filters work
}
private TextField singleFilterTextField(String cellName, HeaderRow filterRow){
	TextField filterField = new TextField();
	filterField.setValueChangeMode(ValueChangeMode.EAGER);
	filterField.setWidth("100%");
	filterField.addValueChangeListener(this::onFilterChange);
	filterRow.getCell(cellName).setComponent(filterField);
	return filterField;
}
private void onFilterChange(HasValue.ValueChangeEvent event){
	ListDataProvider<FooBar> dataProvider = (ListDataProvider<FooBar>) getDataProvider();
	dataProvider.setFilter((item) -> {
		// for each filter field, add a line to check if that filter matches the item
		boolean nameDoesMatch = item.getName().contains(nameFilter.getValue());
		boolean addressDoesMatch = item.getAddress().contains(addressFilter.getValue());

		return nameDoesMatch && addressDoesMatch;
	});
}
Last updated on May, 29th 2019
Naj Htuaf
3 years ago May 29, 2019 8:43am
Kaspar Scherrer
3 years ago May 29, 2019 9:19am
Oleg Wahl
3 years ago Jun 11, 2019 8:06am
Kaspar Scherrer
3 years ago Jun 11, 2019 8:49am
Oleg Wahl
3 years ago Jun 14, 2019 8:36am
Kaspar Scherrer
3 years ago Jun 14, 2019 11:42am