How can I Update item on Vaadin's Grid without putting explicitly all field

I try to create regular CRUD operations on Grid table for User entity - which is like this:

public class User { private id; private String name private Role role; } with appropriate getters and setters.

  • The Grid should have 2 fields: name and role.name.
  • I want to create a data IndexedContainerfor that Grid
  • I want to make updates - which will bind container’s data to User model.
    [list]
  • by model I mean User entity, not Vaadin’s internal model

    [/list]


How can I do that? I have problem with 2 things:

  • creating appropriate listener
  • binding existing User model to row/index in data IndexedContainer


Explanation:

  • IndexedContainer has itemId property, where I can left user’s id for future binding on update. But after creating ValueChangeListener on the IndexedContainer I found that I have no access to its itemId field.
  • So I tried with CommitHandler in EditorFieldGroup (the field of Grid object) and there is the same scenario, but I see itemId property in debug made, but I can’t reach it because it is a private field. I can of course get it through reflection - but I don’t think that this is a good way to do that.

Maby there is some other way to update User model from Grid tabular data?

Maby I should add User id field to grid as regular IndexedContainer property, but make it hidden and read-only? But I wonder if it is safe and there’s no threat that someone change frontend form and can update User with id not presented on the Grid table.

If anyone know what is the best practice on that typical case, please let me know. I will be very glad for your help!

Is there any particular reason to use IndexedContainer instead of BeanItemContainer? The BIC writes changes directly to the beans…

ValueChangeListener is bound to a Property, and does not know anything about the item in which the property is; hence it doesn’t get the item ID. If you use one VCL per property, you can store the item ID in your VCL implementation.

If you want to handle saving the Grid editor in some special way, you can extend Grid and override saveEditor() to add custom behaviour.

Yes, I know that I can extend Grid or store some extra field on my Event implementation but I’m new in the field of Vaadin, so I want to know general best practices for handle this case. I assume that what I wanted to achieve - is a well known scenario - so there should be some well known answers.

I could use BIC, but as far as I know, it creates containers’ fields automatically. There are 3 issues with that:

  • I don’t want to insert any “id” column.
    [list]
  • I know that I can hide it, but I want to be sure that if someone explicitly change that hidden field on the front side of my app - it wont affect other User data (does ''read-only" field is sufficient for that?)

    [/list]
  • What if I needed to change column name and it will be totally different then in my Model class? BIC allows that?
  • and what if I needed to merge two fields into one - as far I know, that kind of field is read-only ?

I don’t quite know what your case exactly is, but IndexedContainer is not normally used when you have beans. But if you want to do it that way, overriding saveEditor() would maybe be the best way. A CommitHandler is probably not what you need; it’s a FieldGroup feature and a FG is bound to an item. An item doesn’t have any identity (such as item ID) in itself, but only in the context of a container containing many items. I suppose you could get the item ID of the currently edited item in a commit handler, if you pass a reference to the Grid to it.

Regarding BIC:

  1. If a column is hidden or read-only, it’s not possible to change the values.
  2. What do you mean by column name here? You can set column caption with getColumn(“mycolumn”).setHeaderCaption(“My Nice Column”)
  3. Yeah, that gets difficult. You could merge columns with a GeneratedPropertyContainer, but the generated properties are indeed read-only. You could do it by adding a merged property in your bean or by wrapping the beans in a wrapper with such a merged property, which handles merging the field values, as well as a setter that “unmerges” the values.

All right, thank you very much! Your answer explained me a lot!

So I assume that people often use BIC instead of IndexedContainer for that kind of puspose?

Yes, if you have beans, use BIC, unless there’s some very good reason not to.

OK, I have one last question :slight_smile:

  1. Is it the same as read-only?

grid.getColumn("Id").setEditable(false); 2. and this make column hidden?

grid.removeColumn("Id")