Skip to content

Commit

Permalink
fix: Avoid processing value change event due writing back of converte…
Browse files Browse the repository at this point in the history
…d value (#12183) (CP: 2.7) (#12338)
  • Loading branch information
TatuLund committed Nov 11, 2021
1 parent e530e5a commit 868d08a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,7 @@ protected static class BindingImpl<BEAN, FIELDVALUE, TARGET>

private Registration onValueChange;
private boolean valueInit = false;
private boolean convertedBack = false;

/**
* Contains all converters and validators chained together in the
Expand Down Expand Up @@ -1267,7 +1268,8 @@ private FIELDVALUE convertToFieldType(TARGET target) {
private void handleFieldValueChange(
ValueChangeEvent<FIELDVALUE> event) {
// Don't handle change events when setting initial value
if (valueInit) {
if (valueInit || convertedBack) {
convertedBack = false;
return;
}

Expand Down Expand Up @@ -1295,6 +1297,7 @@ private BindingValidationStatus<TARGET> writeFieldValue(BEAN bean) {
if (convertBackToPresentation && value != null) {
FIELDVALUE converted = convertToFieldType(value);
if (!Objects.equals(field.getValue(), converted)) {
convertedBack = true;
getField().setValue(converted);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import com.vaadin.flow.data.binder.testcomponents.TestTextField;
import com.vaadin.flow.data.converter.Converter;
import com.vaadin.flow.data.converter.StringToBigDecimalConverter;
import com.vaadin.flow.data.converter.StringToDoubleConverter;
import com.vaadin.flow.data.converter.StringToIntegerConverter;
import com.vaadin.flow.data.validator.IntegerRangeValidator;
import com.vaadin.flow.data.validator.NotEmptyValidator;
Expand Down Expand Up @@ -1683,6 +1684,35 @@ public void invalidUsage_modifyFieldsInsideValidator_binderDoesNotThrow() {
Assert.assertTrue(validatorIsExecuted.get());
}

@Test
public void validationShouldNotRunTwice() {
TestTextField salaryField = new TestTextField();
AtomicInteger count = new AtomicInteger(0);
item.setSalaryDouble(100d);
binder.forField(salaryField)
.withConverter(new StringToDoubleConverter(""))
.bind(Person::getSalaryDouble, Person::setSalaryDouble);
binder.setBean(item);
binder.addValueChangeListener(event -> {
count.incrementAndGet();
});

salaryField.setValue("1000");
assertTrue(binder.isValid());
assertEquals(1, count.get());

salaryField.setValue("salary");
assertFalse(binder.isValid());
assertEquals(2, count.get());

salaryField.setValue("2000");

// Without fix for #12356 count will be 5
assertEquals(3, count.get());

assertEquals(new Double(2000), item.getSalaryDouble());
}

@Test
public void setValidationErrorHandler_handlerIsSet_handlerMethodsAreCalled() {
TestTextField testField = new TestTextField();
Expand Down

0 comments on commit 868d08a

Please sign in to comment.