Skip to content

Commit 0ba155c

Browse files
caaladorvaadin-bot
authored andcommitted
fix: binder to update value on validation success (#23172)
After failed validation for null value write null to bean when validatio passes. Fixes vaadin/flow-components#8209
1 parent 6218d97 commit 0ba155c

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

flow-data/src/main/java/com/vaadin/flow/data/binder/Binder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,8 +1391,8 @@ public BindingImpl(BindingBuilderImpl<BEAN, FIELDVALUE, TARGET> builder,
13911391
&& getField() instanceof HasValidator) {
13921392
HasValidator<FIELDVALUE> hasValidatorField = (HasValidator<FIELDVALUE>) getField();
13931393
onValidationStatusChange = hasValidatorField
1394-
.addValidationStatusChangeListener(
1395-
event -> this.validate());
1394+
.addValidationStatusChangeListener(event -> getBinder()
1395+
.handleFieldValueChange(this));
13961396
}
13971397

13981398
this.getter = getter;

flow-data/src/test/java/com/vaadin/flow/data/binder/BinderValidationStatusChangeListenerTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,41 @@ public void fieldWithHasValidatorFullyOverridden_boundFieldGetsUnbind_validation
184184
Assert.assertEquals(INVALID_DATE_FORMAT, componentErrors.get(field));
185185
}
186186

187+
@Test
188+
public void fieldWithHasValidator_validationStatusChangesToTrueWithNullValue_beanIsUpdated() {
189+
// Setup: bind field to bean with an initial date value
190+
var field = new TestHasValidatorDatePicker.DataPickerHasValidatorOverridden();
191+
LocalDate initialDate = LocalDate.of(2023, 1, 15);
192+
item.setBirthDate(initialDate);
193+
binder.bind(field, BIRTH_DATE_PROPERTY);
194+
binder.setBean(item);
195+
196+
// Verify initial state
197+
Assert.assertEquals(initialDate, item.getBirthDate());
198+
Assert.assertEquals(initialDate, field.getValue());
199+
200+
// Simulate: user enters invalid input (field keeps null value
201+
// internally,
202+
// validation fails)
203+
// field.setValue(null);
204+
field.fireValidationStatusChangeEvent(false);
205+
206+
// Bean should still have old value since validation failed
207+
Assert.assertEquals(1, componentErrors.size());
208+
Assert.assertEquals(initialDate, item.getBirthDate());
209+
210+
// Simulate: user clears the field to null (which is now accepted)
211+
// Field value is already null, but validation now passes
212+
field.setValue(null);
213+
field.fireValidationStatusChangeEvent(true);
214+
215+
// Error should be cleared
216+
Assert.assertEquals(0, componentErrors.size());
217+
218+
// Bug: Bean should be updated to null, but currently it's not
219+
Assert.assertNull(
220+
"Bean property should be updated to null when validation passes",
221+
item.getBirthDate());
222+
}
223+
187224
}

flow-data/src/test/java/com/vaadin/flow/data/binder/testcomponents/TestDatePicker.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ public class TestDatePicker
1111
private String label = null;
1212

1313
public TestDatePicker() {
14-
super(null, LocalDate::parse, LocalDate::toString);
14+
super(null, LocalDate::parse,
15+
value -> value != null ? value.toString() : null);
1516
}
1617

1718
public TestDatePicker(String label) {

0 commit comments

Comments
 (0)