How to bind whole Bean from Combobox to BeanItemContainer ??

I have Grid + BeanItemContainer + Combobox. I try to edit data and comit it through Grid’s out-of-the-box editor.

This is the code:

[code]
Grid grid = new Grid();
BeanItemContainer container = new BeanItemContainer(User.class);

grid.setContainerDataSource(container);
grid.setEditorEnabled(true);

container.addNestedContainerBean(“role”);

grid.removeColumn(“id”);
grid.removeColumn(“role.id”);

grid.setEditorFieldFactory(new DefaultFieldGroupFieldFactory() {
@Override
public T createField(Class<?> type, Class fieldType) {
if (type.equals(Role.RoleEnum.class)) {
ComboBox comboBox = new ComboBox();
BeanItemContainer container = new BeanItemContainer<>(Role.class);
container.addAll(
IteratorUtils.toList(RoleRepository.findAll().iterator())
);
comboBox.setContainerDataSource(container);

          comboBox.setItemCaptionMode(Select.ITEM_CAPTION_MODE_PROPERTY);          
          comboBox.setItemCaptionPropertyId("name");
    }
}

});
[/code]This is my model classes (they have also getters/setters):

[code]
public class User {
private Integer id;
private String name;
private Role role;
}

public class Role {
private Integer id;
private RoleEnum name;
}
[/code]
The problem is:
when I try to save it through “Save” button on Grid’s editor - I’ve got that kind of error:

Unable to convert value of type demo.Role to model type class Role$RoleEnum. No converter is set and the types are not compatible.
   at com.vaadin.data.util.converter.ConverterUtil.convertToModel(ConverterUtil.java:181)
  • I used Enum for Role name ( Role.RoleEnum) because Grid’s Editor creates automatically ComboBox for Enums.


I want to achive:
when I select some role on ComboBox - it will change the model also.

Example:

  • if I have selected Roles:

[ { "id":1, "name": "admin" }, { "id":2, "name":"user" } ] * Combobox should show values: “admin”, “user”

  • When I change from “user”, to “admin” - it should change also whole Role object in User’s field “role”
  • Because what I can do now is bind only “name” field - so after the same change - it afects only “name” field and id remains the same - so data become inconsisten in User model.

Does anyone know how to help me?

Hi,

Why are you calling “container.addNestedContainerBean(“role”);” ? I think you should just “replace” that property with a combobox select in edit mode (when reading you can count on toString or customize the string presentation).

cheers,
matti

OK, this is some kind of idea and in fact it works, but providing custom toString() method, just for one particular ComboBox, seems to be some kind of hack - not the regular solution :wink:

Nevertheless - thanks for your advice! Because it’s the closest solusion to the expected result :slight_smile:

So removing “container.addNestedContainerBean(“role”);” made it work?

In the ComboBox you can naturally use the setItemCaptionPropertyId that you had used before as well. And to avoid toString usage for normal (read only) representation you can use getColumn(“role”).setConverter(Converter) to avoid Grid doing toString for the Role object in your User objects that are listed in Grid. Using toString is no hack if it happens to give you a decent presentation, but it sure is not what you want most of the time :slight_smile:

BTW. If you want to have handy way to customize the text presentation of objects listed in the ComboBox, you should check out TypedSelect from Viritin add-on. It has a concept called CaptionGenerator that makes customizing the caption really easy - right as you want it. That is my regular solution :wink:

cheers,
matti

Thanks onece more :slight_smile: it’s really comprehensive answer. For my proof-of-concept overriding toString() method is more than enough :slight_smile: but for real application I will look for CaptionGenerator.

there is one more thinng… When I changed something on editor’s combobox it automaticaly refresh coresponding field on the grid’s row.

But when I edit aTextField - gid is not updated, but underlying datasource is changed in the same way like in the case of combobox.

How to refresh entire grid’s row after commit editor’s changes to datasource?

Hello Ziemo,
Apology for raising the dead but i have to ask if you managed to find a solution on:

If you did, could you please share your sources.

Hi,

If you use MGrid extension from Viritin, you can use this method:


https://github.com/viritin/viritin/blob/master/src/main/java/org/vaadin/viritin/grid/MGrid.java#L181-L202

cheers,
matti

Thanks for the response…!!
Awesome plugin too.