Vaadin data Binder - ComboBox issues

Viewed 345

Later Edit: I noticed that by returning one of the options in ValueProvider's apply method leads to having the check mark present, but appears to show the previous select too. I.e. if the current and previous values are distinct, two check marks are shown.

I am having troubles with ComboBox binding. I cannot get the com.vaadin.flow.data.binder.Binder properly select an option inside the combobox - i.e. tick the check mark in the dropdown.

My binder is a "generic", i.e. I am using it along with a Map, and I provide dynamic getters/setters for various map keys. So, consider Binder<Map>, while one of the properites inside the Map should be holding a Person's id.

ComboBox<Person> combobox = new ComboBox<>("Person");
List<Person> options = fetchPersons();
combobox.setItems(options);

combobox.setItemLabelGenerator(new ItemLabelGenerator<Person>() {
    @Override
        public String apply(final Person p) {
            return p.getName();
        }
});

binder.bind(combobox, new ValueProvider<Map, Person>() {
    @Override
    public Person apply(final Map p) {
        return new Person((Long)p.get("id"), (String)p.get("name"));
    }
}, new Setter<Map, Person>() {
    @Override
    public void accept(final Map bean, final Person p) {
        bean.put("name", p.getName());
    }
});

Wondering what could I possibly do wrong...

Later edit: Adding a screenshot for the Status ComboBox which has a String for caption and Integer for value.

Malfunction example

1 Answers

Your problem is that you are creating a new instance in your binding, which is not working. You probably have some other bean, (I say here Bean) where Person is a property. So you want to use Binder of type Bean, to bind ComboBox to the property, which is a Person. And then populate your form with the Bean by using e.g. binder.readBean(bean). Btw. using Java 8 syntax makes your code much less verbose.

Bean bean = fetchBean();
Binder<Bean> binder = new Binder();
ComboBox<Person> combobox = new ComboBox<>("Person");
List<Person> options = fetchPersons();
combobox.setItems(options);

combobox.setItemLabelGenerator(Person::getName);

binder.forField(combobox).bind(Bean::getPerson, Bean::setPerson);
binder.readBean(bean);
Related