I have a form with a FormFieldFactory and two Selects. One is productFamilyId and the other is productId. The productId item list depends on the productFamilyId value. At field creation time there is no problem because the form item, i.e. all the properties, is available
public Field createField(Item item, Object propertyId, Component uiContext) {
What I don’t know is how to get the other field and force it to refill options.
I have attached a ValueChangeListener to the productFamilyId and I know the new value when it changes.
f6.addListener( new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
Integer newProductFamilyId = (Integer) event.getProperty().getValue();
event.getProperty().getType();
}
});
I added a ValueChangeListener to form but id doesn’t receive any event. Is there any way to receive an event with the current item when a property changes. I’ve tried to add a Property.ValueChangeListener to the form, but the IDE says that interface is not implemented.
How to get access to the productId form field? Is there any other way to implement cross-field events?
Well, I’ve found a way to do it: create a class that implements ValueChangeListener with access to all the form fields. So, when a Select field changes, I can fill another select.
I have implemented an interface to receive all the ValueChangeEvents of the form
@Override
public void crossFieldChange(Form fc, ValueChangeEvent event) {
Property p = event.getProperty();
try {
Field f = (Field) p;
if (f.getCaption().equals(f6.getCaption())) {
AbstractSelect as = (Select) f7.getField();
as.removeAllItems();
List<E1> lc = service.findOptions((Integer) p.getValue());
for (E1 c: lc) {
as.addItem(c.getUserId());
as.setItemCaption(c.getUserId(), "" + c.getUserId() + " " + c.getUserName());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Now when f6 select value changes, f7 select list is updated. Both fields are required. When f6 changes a “!” appears near f7 because f7 becomes blank: current f7 value does not match any option of the new list. I select a new option in f7 and the “!” disappears but then commit fails. Exception is Validator$EmptyValueException. I’ve checked the form doesn’t like removing and adding items.
Every form field is immediate, form is also immediate, not invalidCommited and not writeThrough.
I’m also interested in dynamic forms and I’m trying to understand this topic with help of your example.
Selection and dynamic moon refilling works fine, but I have a problem with
form.commit() : when I use
commit() the moon ComboBox is emptied.
Details:
I added these lines of code to your example:
Button apply = new Button("commit()", new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
try {myform.commit();}
catch (Exception e) {System.out.println(e.toString());}
}
});
addComponent(apply);
After starting the application I first choose “Jupiter” and then “Callisto” as moon value. Fine! Then I press the commit button. What happens is that the first ComboBox still displays “Jupiter”, but the second ComboBox displays “-- Select a Moon --” again.
Is there a good way to make sure, that the dynamic filled ComboBox still shows the selected value after
commit() ?
I just want to bring up this topic because the effect I mentioned still exists in 6.4. It is difficult to create dynamic forms because of this. I hope there will be a solution/workaround in future.
I’m also having the same problem under 6.7.0. Under form.commit, the dependant select goes empty, and the commit doesn’t succeed. Also, it should be pointed out that when I want to edit the same bean again, it will execute:
formsetItemDataSource(bi)
Again, but this second time, an exception is thrown:
Cause: java.lang.NullPointerException
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:532)
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:164)
at com.vaadin.ui.AbstractComponent.fireEvent(AbstractComponent.java:1219)
at com.vaadin.ui.AbstractField.fireValueChange(AbstractField.java:906)
at com.vaadin.ui.AbstractField.setPropertyDataSource(AbstractField.java:645)
at com.vaadin.ui.Form.setItemDataSource(Form.java:770)
at com.vaadin.ui.Form.setItemDataSource(Form.java:718)
I’m running out of ideas or alternatives… any help appreciated.