vaadin / vaadin-grid-flow

Vaadin Flow Java API for vaadin/vaadin-grid Web Component
https://vaadin.com/components/vaadin-grid
Other
14 stars 16 forks source link

Grid components are not always rendered immediately #557

Closed drewharvey closed 5 years ago

drewharvey commented 5 years ago

Vaadin 10.0.11 Chrome

Some times components in Grid cells do not get rendered until another action takes place. It seems that it is usually the first two cells that do not render. Even after the user performs an action on the grid (selects another visible component in the grid) the missing components render but the row height is not adjusted to fit.

I've attached an example of a situation where this issue is reproducible 100% of the time. I'm changing the number of items in the Grid's internal list from 0 to 1 to 2. Once there are 2 items, you can see some of the ComboBox components do not render immediately.

grid-component-rendering-issue

marcelo107 commented 5 years ago

It is not necesssarily always the first two cells. In my case the component column is the last cell of the row. It also does not render until another action takes place. Edit: I am using vaadin version 13.0.0.beta1, vaadin-grid-flow 3.0.0 and vaadin-grid 5.3.0

retomerz commented 5 years ago

We run in the same problem. We use Vaadin 13 beta 1

anasmi commented 5 years ago

@marcelo107 @retomerz could try to update to beta2. Is issue still reproducible there? Also, does grid rendered wrongly also in Firefox?

ujoni commented 5 years ago

I tried the following snippet

@Route("")
public class MainView extends VerticalLayout {

    public MainView() {
        final List<Thing> things = new ArrayList<>();
        things.add(thingWithValues(8));

        ListDataProvider<Thing> provider = new ListDataProvider<>(things);

        Grid<Thing> thingsGrid = new Grid<>();
        thingsGrid.setDataProvider(provider);

        thingsGrid.addColumn(new ComponentRenderer<>(thing -> new ComboBox<>(thing.getValues1().size() + " items", thing.getValues1()))).setHeader("1/3 items");
        thingsGrid.addColumn(new ComponentRenderer<>(thing -> new ComboBox<>(thing.getValues2().size() + " items", thing.getValues2()))).setHeader("2/3 items");
        thingsGrid.addColumn(new ComponentRenderer<>(thing -> new ComboBox<>(thing.getValues3().size() + " items", thing.getValues3()))).setHeader("3/3 items");

        Button button = new Button("Add row", event -> {
            things.add(thingWithValues(11));
            provider.refreshAll();
        });

        add(new Paragraph(Version.getFullVersion()), thingsGrid, button);
    }

    private static class Thing {
        private List<String> values;
        private int third;
        Thing(List<String> values) {
            this.values = values;
            third = (int)Math.ceil(values.size() / 3.0);
        }

        List<String> getValues1() { return values.subList(0, third); }

        List<String> getValues2() { return values.subList(third, 2 * third); }

        List<String> getValues3() { return values.subList(2 * third, values.size()); }
    }

    private static Random r = new Random();
    private static Thing thingWithValues(int count) {
        return new Thing(IntStream.range(0, count).map(i -> r.nextInt()).mapToObj(Integer::toHexString).collect(Collectors.toList()));
    }
}

and I was able to replicate the problem using Vaadin 10.0.11 but not with Vaadin 13.0.0.beta2 nor Vaadin 13.0.0.beta1. @marcelo107, @retomerz what are the specific conditions in which you face this problem?

marcelo107 commented 5 years ago

@anasmi, strangely enough I can't reproduce the issue any more. I tried with Vaadin 12.0.7, 13.0.0.beta1 and 13.0.0.beta2 and they all seem to work now (tried with Chrome and FF). @ujoni my use case basically envolves uploading a file and then the file is presented in the grid with one of the columns as a button that downloads said file. selecao_391

drewharvey commented 5 years ago

Just updated to the latest Chrome and I can still reproduce this 100% of the time with my original example.

Legioth commented 5 years ago

Just updated to the latest Chrome and I can still reproduce this 100% of the time with my original example.

Could you please share a reduced test case so that we can actually reproduce the issue.

drewharvey commented 5 years ago

I am able to reproduce the issue with the following code. I also tried the same thing by using Grid.addComponentColumn and had the same result (non-rendered ComboBoxes). Seems that using different browser window widths affects which components do/don't render. I will post an image showing the difference.

import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.renderer.ComponentRenderer;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.veracyte.entity.veralis.data.lab.afirma.NoduleLocation;
import com.veracyte.entity.veralis.data.lab.afirma.ReceivedOrder;
import com.veracyte.ui.views.MainView;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

@Route(value = "test", layout = MainView.class)
@PageTitle("Grid Rendering Issue")
public class IssueExample extends VerticalLayout {

    private List<Item> items = new ArrayList<>();

    public IssueExample() {

        Grid<Item> grid = new Grid<>();
        grid.setItems(items);

        // ID
        grid.addColumn(new ComponentRenderer<>(ComboBox<String>::new, (comboBox, nodule) -> {

        })).setHeader("ID");

        // Order
        grid.addColumn(new ComponentRenderer<>(ComboBox<ReceivedOrder>::new, (comboBox, nodule) -> {

        })).setHeader("Order");

        // Location
        grid.addColumn(new ComponentRenderer<>(ComboBox<NoduleLocation>::new, (comboBox, nodule) -> {

        })).setHeader("Location");

        // Number of items input

        TextField numItems = new TextField("Num Items");
        numItems.addValueChangeListener(e -> {
            int num = 0;
            try {
                if (e.getValue() != null && !e.getValue().isEmpty()) {
                    num = Integer.parseInt(e.getValue());
                }
            } catch (Exception ex) {

            }
           items.clear();
            IntStream.rangeClosed(1, num).forEach(i -> {
                items.add(new Item(i+"id", i+"location"));
            });

            grid.getDataProvider().refreshAll();
        });

        add(numItems, grid);
    }

    public class Item {
        String id;
        String location;
        public Item(String id, String location) {
            this.id = id;
            this.location = location;
        }
    }
}
drewharvey commented 5 years ago

Full screen width: The issue exists when there are either 1 or 2 items in the Grid. grid-rendering-issue-full-screen

70% screen width: The issue exists when there are 2 items in the Grid. grid-rendering-issue-70-width

Klaudeta commented 5 years ago

So far I can isolate the issue to be present only with comboboxes and the cause of it happening is a combination of the #5025 and a substantial change in vaadin-combo-box(web) done in v4.2.1

#5025 is fixed in flow v1.4.0

The fix done for #5025 does not work for vaadin-combo-box (web) prior to version v4.2.1

So the combination that's working is having both flow v1.4.0 and vaadin-combo-box (web) version v4.2.1 (or greater).

This combination is found in Vaadin 12.0.7, Vaadin 13.0.0.beta2 and 13.0.0.beta3 the versions where I can't reproduce the issue.

Klaudeta commented 5 years ago

The changes of vaadin-combo-box on v4.2.1, specifically this change 6a94726 has decreased considerably the rendering time of the combobox. I guess this allows the fix done for #5025 to be applied also on the comb-box making it to be rendered once the notifyResize is called inside requestAnimationFrame

OlliTietavainenVaadin commented 5 years ago

Minimal example, tested on Vaadin 13.0.1 with Windows 10 on Chrome, Edge and FF:

public class MainLayout extends VerticalLayout {

    protected Grid<String> grid;

    public MainLayout() {
        setSizeFull();
        grid = new Grid<String>();
        grid.addColumn(new ComponentRenderer<>(item -> new Span("test"))).setHeader("Test");
        grid.setItems("Foo");
        add(grid);
        Button btn = new Button("Add new column with Span ComponentRenderer");
        btn.addClickListener(e -> {
            grid.addColumn(new ComponentRenderer<>(item -> new Span("test new"))).setHeader("new column");
        });
        add(btn);
    }
}
pleku commented 5 years ago

The fix will land to Flow 1.0.10 when it is released

Klaudeta commented 5 years ago

@OlliTietavainenVaadin I think your example it's not related to the issue in here. The original issue here is affected/reproducible only for Chrome 72. In the original issue the component is actually being added into the dom but it is not rendered and it is happening when new rows are being added into the grid. While in you example the issue is happening when you are added new columns and by expecting you can see that the component of the last column is not actually being added at all on the dom when the last column is added.

I think you have to open a new issue for the example you provided.

OlliTietavainenVaadin commented 5 years ago

Thanks @Klaudeta , I created https://github.com/vaadin/vaadin-grid-flow/issues/587

rthadhani commented 5 years ago

Adding my issue in the same thread so that it gets tracked and anyone facing the same issue can help.

Issue : Two columns in the vaadin grid render after some period of time. The columns consist of the link. I have used Polymer 2.0 and done minification in es6 . If I remove minification the columns render properly and on time , but when I add it again the columns take time to render. One thing I noticed is ; the columns are there on the DOM but not render on the webpage.

Vaadin-grid version : 5.3.3

Code -