I have a grid with a ComponentRenderer setup like this. My goal is to show all details of all items in the grid by default.
grid.setItems(dataProvider);
// this prevents other items from collapsing when one is clicked (being expanded)
grid.setDetailsVisibleOnClick(false);
// collapse/expand on click
grid.addItemClickListener(event -> grid.setDetailsVisible(event.getItem(), !grid.isDetailsVisible(event.getItem())));
grid.addComponentColumn((item) -> {
HorizontalLayout layout = new HorizontalLayout();
// ... configure and populate layout (omitted)
// expand all details by default
// doing this somehow causes the itemClickListener to fail... ("Child should have this element as a parent")
if (!grid.isDetailsVisible(item)) {
grid.setDetailsVisible(item, true);
}
return layout;
});
grid.setItemDetailsRenderer(new ComponentRenderer<>(() -> {
VerticalLayout layout = new VerticalLayout();
layout.setPadding(false);
layout.setMargin(false);
return layout;
}, (layout, item) -> {
List<Details> details = detailService.listDetails(this.userId, item);
populateDetails(layout, details);
}));
I achieved this by using setItemDetailsVisible in addComponentColumn, however, this causes the ItemClickListener to fail with an exception, as the comments in the code suggest.
Why does this happen? How can it be fixed? Is there perhaps a different approach to this problem which works out of the box?
I am using Vaadin 23.3.5.
This is the StackTrace for the exception.
java.lang.IllegalArgumentException: Child should have this element as a parent
at com.vaadin.flow.dom.Node.ensureChildHasParent(Node.java:589)
at com.vaadin.flow.dom.Node.removeChild(Node.java:482)
at com.vaadin.flow.dom.Node.removeChild(Node.java:466)
at com.vaadin.flow.data.provider.AbstractComponentDataGenerator.refreshData(AbstractComponentDataGenerator.java:53)
at com.vaadin.flow.data.provider.CompositeDataGenerator.lambda$refreshData$2(CompositeDataGenerator.java:62)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
at com.vaadin.flow.data.provider.CompositeDataGenerator.refreshData(CompositeDataGenerator.java:62)
at com.vaadin.flow.data.provider.DataCommunicator.refresh(DataCommunicator.java:391)
at com.vaadin.flow.component.grid.Grid$AbstractGridExtension.refresh(Grid.java:1136)
at com.vaadin.flow.component.grid.Grid$DetailsManager.setDetailsVisible(Grid.java:1204)
at com.vaadin.flow.component.grid.Grid.setDetailsVisible(Grid.java:3143)
at my.comp.project.gui.MyView.lambda$initGrid$9b1b5227$1(MyView.java:190)
Line 190 is the ItemClickListener
Since I could not find an appropriate solution to this issue, I decided to opt for a workaround. Instead of using
setItemDetailsRendererI just render an instance ofDetailsinside of a component column.In order to have the details summary span across the whole column width, I added the class name
summary-width-fulland added this style tovaadin-details.css