Description
Maybe other components affected too.
EntityComboBox fires a value change event with fromClient = false when its value is set through a user-driven flow, instead of fromClient = true.
This affects every path that sets the value "as if from the client", e.g.:
- selecting an item in a lookup window and confirming it (
LookupSelectAction);
- clearing the value via
EntityClearAction / ValueClearAction.
Application code that relies on HasValue.ValueChangeEvent#isFromClient() to distinguish user input from programmatic changes behaves incorrectly for these fields.
Steps to reproduce
- Open a view with an
EntityComboBox bound to data and configured with an EntityLookupAction.
- Add a value change listener to the field that logs
event.isFromClient().
- Click the lookup action, select an item in the lookup window, and confirm with the Select button (
LookupSelectAction).
(Alternatively, call entityComboBox.setValueFromClient(entity) directly.)
- Observe the value change event reported to the listener.
Actual behavior
A single value change event is fired with isFromClient() == false.
Expected behavior
A single value change event is fired with isFromClient() == true, because the value originates from a user action (as in 2.7.x).
Root cause (verified)
Introduced in 2.8 by the fix for #5164, which added setPresentationValue(value) before setModelValue(value, true) in EntityComboBox#setValueFromClient (the same change was applied to ComboBoxPicker, JmixMultiSelectComboBoxPicker).
Calling setPresentationValue(value) directly writes the Vaadin element value property; the server-side property write synchronously triggers AbstractSinglePropertyField's sync listener with userOriginated = false → setModelValue(value, false), firing the value change event with fromClient = false. The following setModelValue(value, true) is then a no-op because the model value already equals value. (The presentationUpdateInProgress guard in AbstractFieldSupport is not raised, because it only applies inside AbstractFieldSupport.applyValue(), not on a direct setPresentationValue call.)
In 2.7.x setValueFromClient called only setModelValue(value, true), so the event was fired with the correct flag before the element property was written.
Description
Maybe other components affected too.
EntityComboBoxfires a value change event withfromClient = falsewhen its value is set through a user-driven flow, instead offromClient = true.This affects every path that sets the value "as if from the client", e.g.:
LookupSelectAction);EntityClearAction/ValueClearAction.Application code that relies on
HasValue.ValueChangeEvent#isFromClient()to distinguish user input from programmatic changes behaves incorrectly for these fields.Steps to reproduce
EntityComboBoxbound to data and configured with anEntityLookupAction.event.isFromClient().LookupSelectAction).(Alternatively, call
entityComboBox.setValueFromClient(entity)directly.)Actual behavior
A single value change event is fired with
isFromClient() == false.Expected behavior
A single value change event is fired with
isFromClient() == true, because the value originates from a user action (as in 2.7.x).Root cause (verified)
Introduced in 2.8 by the fix for #5164, which added
setPresentationValue(value)beforesetModelValue(value, true)inEntityComboBox#setValueFromClient(the same change was applied toComboBoxPicker,JmixMultiSelectComboBoxPicker).Calling
setPresentationValue(value)directly writes the Vaadin elementvalueproperty; the server-side property write synchronously triggersAbstractSinglePropertyField's sync listener withuserOriginated = false→setModelValue(value, false), firing the value change event withfromClient = false. The followingsetModelValue(value, true)is then a no-op because the model value already equalsvalue. (ThepresentationUpdateInProgressguard inAbstractFieldSupportis not raised, because it only applies insideAbstractFieldSupport.applyValue(), not on a directsetPresentationValuecall.)In 2.7.x
setValueFromClientcalled onlysetModelValue(value, true), so the event was fired with the correct flag before the element property was written.