I believe I have found a bug in the Vaadin Grid that can be replicated with the code below.
I would like to save the grid's sorting order whenever it's changed and then restore it when the grid is loaded. The main issue is that the GridSortOrder
list just keeps incrementing in size for the event in the sort listener rather than replacing the sortorder list. I believe this is a bug within Vaadin 14-20 because it only happens if I call setColumnOrder()
in the reset method below (removing that call it works as expected). In other words calling setColumnOrder()
seems to add the list of GridSortOrder
to the event in the sort listener when it should be replacing it. This is actually also true if you do grid.getSortOrder()
in the listener, meaning it's not just the event but also the grid that is compromised.
This can be replicated consistently with the code below. You will first need to change the sort order of Description column by clicking on the column header. Then just click on Reset button 5-10 times. Once this is done click on the Description column header to change the sort order one more time. The System.out
for the listener will show a size of a list of 20 GridSortOrder
instead of the expected 2 GridSortOrder
. There will be replications of columns over and over.
Grid<Car> grid = new Grid<>();
grid.addColumn(Car::getName)
.setSortable(true)
.setComparator(Car::getName)
.setKey("Name")
.setHeader("Name");
grid.addColumn(Car::getPrice)
.setSortable(true)
.setComparator(Car::getPrice)
.setKey("Price")
.setHeader("Price");
grid.addColumn(Car::getDescription)
.setSortable(true)
.setComparator(Car::getDescription)
.setKey("Description")
.setHeader("Description");
grid.setItems(listOfCars);
grid.setColumnReorderingAllowed(true);
grid.setMultiSort(true);
grid.addSortListener(event -> {
System.out.println("Event: " + event.getSortOrder().size() + " : " + event.isFromClient());
System.out.println("Grid: " + grid.getSortOrder().size() + " : " + event.isFromClient());
});
defaultSort(grid);
Button resetButton = new Button("Reset", click -> {
System.out.println("Reset: " + grid.getSortOrder().size());
defaultSort(grid);
grid.setColumnOrder(
grid.getColumnByKey("Name"),
grid.getColumnByKey("Price"),
grid.getColumnByKey("Description"));
});
add(grid, resetButton);
private void defaultSort(Grid grid) {
grid.sort(List.of(
new GridSortOrder<>(grid.getColumnByKey("Name"), SortDirection.ASCENDING),
new GridSortOrder<>(grid.getColumnByKey("Price"), SortDirection.ASCENDING)
));
}
If I remove grid.setColumnOrder()
from the above then the List<GridSortOrder>
works as expected and is two in the event listener. What's especially interesting is that event.getSortOrder().size()
will increase by 2 every time the resetButton
is clicked (but you'll only see it in the sort listener). It doesn't matter if the setColumnOrder()
is before or after the call to defaultSort()
.
With that in mind if you debug grid.setColumnOrder()
it seems to call updateClientSideSorterIndicators(sortOrder)
which is what I believe is the cause and is where it's being added to the GridSortOrder
list. That being said I'm not sure how to proceed from here so that I can reset the grid's setting when clicking on the Reset button.
FYI: This is an issue for me because I'm trying to save the state of the Grid to the database so that when the user reloads the screen (a very complex one) all their grid settings including the sorting order, the column order, and so on are preserved. However with this bug it's impossible to save the sorting order.
PS: This seems to be true in both Vaadin 14 and Vaadin 20.