Grid with Componet Renderers

Hi all,

I have a grid for which I provide the functionality to change which columns are displayed in the application. Once the user has set the columns they wish to view, I remove all the columns in the grid and re-add the columns they have selected.

As such…

this.getColumns().stream().forEach(this::removeColumn);

I then add them back in…

for (String key : settings.getVisiblecolumns()) {
	this.addColumn(key).setSortable(true);
}

I have added component renderers for a few of the columns, for example…

this.addColumn(new ComponentRenderer<Component, Enquiry>() {
			@Override
			public Component createComponent(Enquiry item) {
					Div s = new Div(new Span(code.getStdesc()));					
					return s;			
			}
		})).setKey(key).setSortable(true);

So all that works fine. However, once you’ve selected the columns and I remove and add and refresh the grid, the values in the component renderers vanish. If I refresh the grid again (same code path), the values re-appear. Also, if I re-attach the grid, they appear.

Does anybody have any pointers or is it a case of waiting for v14 :slight_smile:

I’ve attached a vid to illustrate whats happening. (ok, its here: https://gc4.io/images/halo.mov )

Are you adding the new columns without the renderers? Renderers is set on Column objects. If you remove them, so you do with the renderers. Maybe something missing in the refresh logic you implemented? I guess more code is needed to tell. Or even better if you can share a minimal runnable project with the issue.

As Alejandro said, it may be related to the refresh logic.

There is also an open bug related to component renderer in a grid: https://github.com/vaadin/vaadin-grid-flow/issues/710

EDIT: I think this is related to this bug. Here an example to reproduce the error. You can comment the ticket and follow it.


        Button btn = new Button("add col", e -> {
            grid.addColumn(new ComponentRenderer<>(person -> new Button("COL age "+person.getAge()))).setHeader("h1");
            // not working
            grid.addColumn(new ComponentRenderer<Component,Person>() {
                @Override
                public Component createComponent(Person item) {
                    Div s = new Div(new Span(item.getFirstName()));
                    return s;
                }
            }).setHeader("h2");
            grid.getDataProvider().refreshAll();

        });

You can try this as a workaround:


        Button btn = new Button("add col", e -> {
            grid.addColumn(new ComponentRenderer<>(person -> new Button("COL age "+person.getAge()))).setHeader("h1");
            // not working
            grid.addColumn(new ComponentRenderer<Component,Person>() {
                @Override
                public Component createComponent(Person item) {
                    Div s = new Div(new Span(item.getFirstName()));
                    return s;
                }
            }).setHeader("h2");
            grid.getElement().getNode().runWhenAttached(ui -> ui.getInternals().getStateTree()
                    .beforeClientResponse(grid.getElement().getNode(),
                            context -> grid.getDataProvider().refreshAll()
                                    ));

        });

Thanks for sharing the info. I linked this discussion in the issue.

Hi Jean-Christophe,

Yes, that bug describes exactly what is happening! Thanks!!

I’ll be following that :slight_smile:

Stuart.