FieldGroup field order issue for ValueChangeListeners

I’m not positive, but with Vaadin 6 it seems if I specified Form.setItemDataSource with an array of property ids, the form would create and set the field values in that order. This allowed me to order the fields in the case where the value of one field reflects on another (such as if one field is set to a value, then another field is enabled/disabled).

But it seems like a FieldGroup is not doing that for me. I have tried to bind those two fields in the order I’d like, but it seems that when FieldGroup.setItemDataSource() is called, it’s not guaranteed that it will set my fields in the order I did the FieldGroup.bind() calls.

Is that true or is something else going wrong? What I find is that when I change the value in “trigger field” it correctly updates the enabled/disabled status of the “target field” as expected (via the ValueChangeListener), but when a new object is set via setItemDataSource(), or even when I “save” my object and the FieldGroup.commit() takes place, the fields are set in a different order and so the trigger field’s value is not set first to cause the target field to be enabled/disabled.

Is there a way to ensure this works so I don’t have to do special logic on setItemDataSource() to replicate how the ValueChangeListeners work to update related fields?

Hi,

have you confirmed with a debugger that the order is really incorrect? Just looking at the code it seems to me that the order should be preserved - on bind the fields are put into a LinkedHashMap and on setItemDataSource the same LinkedHashMap is used for the re-binding loop, so the order should indeed be the same.

-tepi

Interesting. What would I debug against to determine this? It’s tricky because we just call setItemDataSource(), and all of the properties in the Item are updated in there “somehow” along with the fields themselves and it doesn’t call my code where I know to debug. I only figured this was the reason because despite ensuring the order is correct, I don’t get the same behavior I had when it was a “deprecated” Form instead, and all of the FieldGroup documentation states the the order is not guaranteed.

Let me know how I can best see the order my fields are set after I call FieldGroup.setItemDataSource() and I’ll give it a look. Thanks!

I think I may know how things are different. What I noted is that when I click the SAVE button, and then FieldGroup.commit(), we basically unselect and reselect a Item from the associated Table, which fires events that call setItemDataSource() for us. But it first calls it with a null item (probably when we unselected everything) and then with our updated item (reselected).

But I think the fields – because we don’t rebuild the SELECTs and TEXTFIELDs like we did with the older Form style in which the fields were repeatedly reconstructed – already have the values set in them, and so when they are set again to the same values, no “change” is detected and thus my ValueChangeListener doesn’t fire.

So, is there a simple way to clear the values in all of fields so that whatever they are set to will cause the value change event? I already set the data source to null, so that would be a good place for me to reset all fields. I mean, I suppose I can use FieldGroup.getFields() and set all the values to null, but is there a better way to do this?

You’re right, seems that the fields are not cleared when the datasource is set to null. I think this could even be seen as a bug. At least I don’t see why the fields should not be cleared when setting a null datasource. You might want to write a ticket about this at dev.vaadin.com.

A more reasonable workaround would be to set a new (clear, with all fields as nulls) instance of your bean type as the datasource.

What I found is that even attempting to clear the fields is not easy or the solution. That is, not everything can be set to null, and selection lists preclude setting the value to something not defined as acceptable.

Our basic method is to create a layout, add in Fields to that layout, and as each field is added, we bind the Field with our property id (in our case, it’s a BeanItem). Then when we call setItemDataSource() with a bean, the underlying code sets all of the values of the Fields based on the property id mappings.

What we’d like is when we call setItemDataSource(null), it should remove all property values in the Fields so we get all fresh values (and all of the ValueChangeListeners can then fire because there is no previous value whatsoever).

The issue we see is we have a Field A, that when it changes value, we enable/disable Field B. But if Field A has the value ‘1’ and that causes Field B to be disabled, when we set a new BeanItem to the data source and its value was also ‘1’, we noted that Field B was no longer was disabled, and the Field A value change listener didn’t fire (presumably because we changed the value from 1 to 1) so it doesn’t re-disabled Field B.

Created
ticket 12371
to track this issue.

+1
Just ran into this today. setItemDataSource(null) would be exceptionally handy.