vaadin / vaadin-combo-box-flow

Vaadin Flow Java API for vaadin/vaadin-combo-box Web Component
https://vaadin.com/components/vaadin-combo-box
Other
5 stars 9 forks source link

Initially invisible ComboBox sets value to null when made visible on certain occasions #321

Closed kalmancsaba closed 4 years ago

kalmancsaba commented 4 years ago

Description

I have a ComboBox, that is invisible when attached to the UI, but has a value (a Binder sets the value from a JPA entity). When some conditions are met, the ComboBox becomes visible. The error occures, when the ComboBox is set visible for the first time (it is initialized on the client side) and the value of the ComboBox was changed at least once while it was still invisible.

Vaadin version

I'm using Vaadin 14.1.5

Expected behavior

The value of the ComboBox is visible in the browser.

Actual behavior

The first time the ComboBox is made visible, the client side sets the value to null, and sends this null value to the server. See video below.

ComboBoxError

Code to reproduce

import java.util.stream.IntStream;

import com.vaadin.flow.component.Composite;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.notification.Notification.Position;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;

@Route("ValueAndVisibilityChangingComboBoxTest")
public class ValueAndVisibilityChangingComboBoxTest extends Composite<VerticalLayout> {

    public ValueAndVisibilityChangingComboBoxTest() {
        getContent().setWidthFull();
        addNormal();
        addDialog();
    }

    private void addNormal() {
        ComboBox<String> cb = createComboBox();
        Label l = new Label("The ComboBox is not visible");
        Button btn = new Button("Toggle ComboBox");
        btn.addClickListener(evt -> {
            cb.setVisible(!cb.isVisible());
            l.setVisible(!l.isVisible());
            if (cb.isVisible()) {
                cb.setValue("Item " + (int) (Math.random() * 500));
            }
        });
        getContent().add(new HorizontalLayout(btn, l, cb));
    }

    private void addDialog() {
        ComboBox<String> cb = createComboBox();
        Label l = new Label("The ComboBox is not visible");
        Dialog dialog = new Dialog(new HorizontalLayout(l, cb));
        Button btn = new Button("Open dialog");
        btn.addClickListener(evt -> {
            if (!dialog.getParent().isPresent()) {
                getContent().add(dialog);
            }
            else {
                l.setVisible(!l.isVisible());
                cb.setVisible(!cb.isVisible());
            }
            if (cb.isVisible()) {
                cb.setValue("Item " + (int) (Math.random() * 500));
            }
            dialog.open();
        });
        getContent().add(btn);
    }

    private static ComboBox<String> createComboBox() {
        ComboBox<String> cb = new ComboBox<>();
        cb.setDataProvider((filter, offset, limit) -> IntStream.range(offset, offset + limit)
                .mapToObj(i -> "Item " + i),
                filter -> 500);
        cb.setVisible(false);
        cb.setValue("Item " + (int) (Math.random() * 500));
        cb.addValueChangeListener(
                evt -> Notification.show(String.format("Value set from '%s' to '%s'", evt.getOldValue(), evt.getValue()), 2000, Position.BOTTOM_STRETCH));
        return cb;
    }
}
alvarezguille commented 4 years ago

Seems to be caused by this code https://github.com/vaadin/vaadin-combo-box-flow/blob/4c4f36327929804d43f4309148d40269263a8e4e/vaadin-combo-box-flow/src/main/java/com/vaadin/flow/component/combobox/ComboBox.java#L363-L366 I'll continue the research on Monday