]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fix binder.load to reset validation status in the end
authorPekka Hyvönen <pekka@vaadin.com>
Tue, 13 Sep 2016 12:14:04 +0000 (15:14 +0300)
committerPekka Hyvönen <pekka@vaadin.com>
Tue, 13 Sep 2016 12:15:56 +0000 (15:15 +0300)
Otherwise any validation triggered by field value changes listeners
would cause errors to be visible after loading a new bean.

Change-Id: I741529f491ae6b36ff2a9aa4326c394cc12fb320

server/src/main/java/com/vaadin/data/Binder.java
server/src/test/java/com/vaadin/data/BinderTest.java

index ba579148b917bfc92e1cc64c3e00238dd7e5ae0c..0a7e33c5560cf88d8f06ce837611186790f7b3f9 100644 (file)
@@ -759,6 +759,10 @@ public class Binder<BEAN> 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));
     }
 
     /**
index d780345f78c28e35c12c7c63f32f72ae1d9e729e..16ad4b70e3666a219637cbd18c3b0cc5d6b86f6a 100644 (file)
@@ -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<Person, String, String> 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<String> lengthPredicate = v -> v.length() > 2;
+
+        Binding<Person, String, String> firstNameBinding = binder
+                .forField(nameField).withValidator(lengthPredicate, "length");
+        firstNameBinding.bind(Person::getFirstName, Person::setFirstName);
+
+        Binding<Person, String, String> 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());
+    }
 }