I make a form that extends the BeanValidationForm and shows the fields grouped in different tabs, to solve the problem of multiple tabs in one form I override the attachField method and the fields are shown without any problem.
The problem I have got right now is that the form must be filled out with the data retrieved from a table when a table item was selected and doesn’t works. The problem appears only in this form, I have got too many other forms using the standard addField and the communication works as expected, but when I try to populate the fields of this form the getField(propertyId) returns a null value.
I review the source code of Form class and I saw that in the addField method there are a call to registerField to add the recent added field to form’s field set, then calls attachField and finally calls requestRepaint.
My question is very simple, should be the method registerField public? Or in other words, how can I register the fields created with the overrided attachField method?
Probably I am doing something wrong, but if not, how can I solve the problem?
Sorry about my english, I need to practice a little more.
So you have a Form whose fields are split over multiple tabs, perhaps with a TabSheet in the layout of the Form.
If the fields are created and added to the form by Form.setItemDataSource(), Form.addItemProperty() or even by a direct call to addField(), they should get registered correctly. If adding fields in some other way than setItemDataSource(), some of the “automatic” mechanisms do not apply to the field.
The method attachField() should do just that - attach a field to a layout and do nothing else. It should never be called directly by the user, only by addField(), and it should not create anything. If you want to control how your fields are created, use your own FormFieldFactory in addition to overriding attachField(). The method registerField() is intentionally private and, like attachField(), it should only be called by addField() which in turn is called by Form.setItemDataSource() and Form.addItemProperty().
If you are not calling attachField() directly, some more information on the problem would be needed.
Note, that setting a new data source will remove the internal registration and call Layout.removeComponent() for the field, but you might have to override this behavior to make sure the field component is removed from your other layout if you have overridden attachField(). This means that you might also have to override Form.removeItemProperty() and remove the component from the layout it is in before calling super.removeItemProperty().
The fields are added to the form using the addField of
BeanValidationForm.java used in the SpringApplication example that was in incubator.
As I tell in the previous post, I override the attachField method and the fields are shown without problems, but those fields aren’t registered in the form, and this is the problem, I cannot populate the data received form a SelectValueEvent on a table, in other cases, where I don’t have TabSheets, the communication between table and form fields works fine.
The method attachField has a protected visibility and, in fact, the registerField method is private. I change the code of BeanValidationForm to implement the code of registerField with the same code of registerField method of the Form, and adding some attributes like propertyIds and fields, and adding a little more of logic to match the code base of Form, the form now shows the data selected in table without problems.
If you need some code, just tell me and I try to make a little snippet or something similar.
Try using the
Vaadin Bean Validation add-on from the directory instead. Its locale handling is a little simpler than in the Spring example as it does not depend on Spring, but otherwise it has been updated and improved in several ways and it is better integrated with the Vaadin data model.
This might also solve some of your other problems. If not, a code snippet would be useful.
the problem is not the BeanVallidationForm, in fact, it works fine and I’ve got a Spring+Vaadin based application, so, the Spring dependency is not a problem.
I try my best to put a snippet, but i can not ensure that I have got time to do it
Hi!
So have you found any elegant solution for this? I think the same as you. Method registerField should be public. There’s to heavy workaround for this.
Janez
@Override
protected void attachField(Object propertyId, Field field) {
//ComponentContainer c
if (field instanceof MyField) {
if (((MyField) field).getParentContainer() != null) {
ComponentContainer c = ((MyField) field).getParentContainer();
getLayout().addComponent(c);
c.addComponent(field);
} else
super.attachField(propertyId, field);
} else
super.attachField(propertyId, field);
}
Just a little drawback here is the fact that my custom form fields (extended from Field) should have their own ComponentContainer property.
Now I can add fields to form this way:
form.addField("other1", new MyTextField("Name"));
HorizontalLayout hor = new HorizontalLayout();
hor.setCaption("test caption");
form.addField("cb1", new MyCheckBox("Name1", hor));
form.addField("cb2", new MyCheckBox("Name2", hor));
form.addField("other2", new MyTextField("Address",hor));
Panel hor1 = new Panel();
hor1.setCaption("hor1 caption");
form.addField("cb3", new MyCheckBox("Name3", hor1));
form.addField("cb4", new MyCheckBox("Name4", hor1));
form.addField("cb5", new MyTextField("Name5", hor1));
form.addField("cb6", new CheckBox("Those"));
form.addField("cb6", new MyTextField("Those"));