From: Pekka Hyvönen Date: Tue, 13 Sep 2016 12:14:04 +0000 (+0300) Subject: Fix binder.load to reset validation status in the end X-Git-Tag: 8.0.0.alpha2~13 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=fa32798f140d6f90a064f5fa55f47aee3a4a413f;p=vaadin-framework.git Fix binder.load to reset validation status in the end Otherwise any validation triggered by field value changes listeners would cause errors to be visible after loading a new bean. Change-Id: I741529f491ae6b36ff2a9aa4326c394cc12fb320 --- diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java index ba579148b9..0a7e33c556 100644 --- a/server/src/main/java/com/vaadin/data/Binder.java +++ b/server/src/main/java/com/vaadin/data/Binder.java @@ -759,6 +759,10 @@ public class Binder implements Serializable { unbind(); this.bean = bean; bindings.forEach(b -> b.bind(bean)); + // if there has been field value change listeners that trigger + // validation, need to make sure the validation errors are cleared + getValidationStatusHandler() + .accept(BinderValidationStatus.createUnresolvedStatus(this)); } /** diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java index d780345f78..16ad4b70e3 100644 --- a/server/src/test/java/com/vaadin/data/BinderTest.java +++ b/server/src/test/java/com/vaadin/data/BinderTest.java @@ -7,6 +7,7 @@ import static org.junit.Assert.assertSame; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Predicate; import org.junit.Assert; import org.junit.Before; @@ -1198,7 +1199,7 @@ public class BinderTest { } @Test - public void binderLoad_clearsErrors() { + public void binderBindAndLoad_clearsErrors() { Binding binding = binder.forField(nameField) .withValidator(notEmpty); binding.bind(Person::getFirstName, Person::setFirstName); @@ -1270,4 +1271,41 @@ public class BinderTest { Assert.assertNull(lastNameField.getComponentError()); Assert.assertEquals("", statusLabel.getValue()); } + + @Test + public void binderLoad_withCrossFieldValidation_clearsErrors() { + TextField lastNameField = new TextField(); + final Predicate lengthPredicate = v -> v.length() > 2; + + Binding firstNameBinding = binder + .forField(nameField).withValidator(lengthPredicate, "length"); + firstNameBinding.bind(Person::getFirstName, Person::setFirstName); + + Binding lastNameBinding = binder + .forField(lastNameField) + .withValidator(v -> !nameField.getValue().isEmpty() + || lengthPredicate.test(v), "err") + .withValidator(lengthPredicate, "length"); + lastNameBinding.bind(Person::getLastName, Person::setLastName); + + // this will be triggered as a new bean is bound with binder.bind(), + // causing a validation error to be visible until reset is done + nameField.addValueChangeListener(v -> lastNameBinding.validate()); + + Person person = new Person(); + binder.bind(person); + + Assert.assertNull(nameField.getComponentError()); + Assert.assertNull(lastNameField.getComponentError()); + + nameField.setValue("x"); + + Assert.assertNotNull(nameField.getComponentError()); + Assert.assertNotNull(lastNameField.getComponentError()); + + binder.bind(person); + + Assert.assertNull(nameField.getComponentError()); + Assert.assertNull(lastNameField.getComponentError()); + } }