From 376a4d5b897327e957483bd43e7075f180a02e8f Mon Sep 17 00:00:00 2001 From: Aleksi Hietanen Date: Fri, 9 Sep 2016 15:11:21 +0300 Subject: [PATCH] Add hasChanges to Binder Change-Id: Id308bd9b08973804e61706192c96118fd6446d3f --- .../src/main/java/com/vaadin/data/Binder.java | 35 +++++++++++++++++-- .../test/java/com/vaadin/data/BinderTest.java | 27 ++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java index 9150c046f6..af5f429252 100644 --- a/server/src/main/java/com/vaadin/data/Binder.java +++ b/server/src/main/java/com/vaadin/data/Binder.java @@ -500,8 +500,10 @@ public class Binder implements Serializable { private void bind(BEAN bean) { setFieldValue(bean); - onValueChange = getField() - .addValueChangeListener(e -> storeFieldValue(bean, true)); + onValueChange = getField().addValueChangeListener(e -> { + binder.setHasChanges(true); + storeFieldValue(bean, true); + }); } @Override @@ -641,6 +643,8 @@ public class Binder implements Serializable { private BinderStatusHandler statusHandler; + private boolean hasChanges = false; + /** * Returns an {@code Optional} of the bean that has been bound with * {@link #bind}, or an empty optional if a bean is not currently bound. @@ -752,6 +756,7 @@ public class Binder implements Serializable { * nothing. */ public void unbind() { + setHasChanges(false); if (bean != null) { bean = null; bindings.forEach(BindingImpl::unbind); @@ -775,6 +780,7 @@ public class Binder implements Serializable { */ public void load(BEAN bean) { Objects.requireNonNull(bean, "bean cannot be null"); + setHasChanges(false); bindings.forEach(binding -> binding.setFieldValue(bean)); } @@ -860,6 +866,9 @@ public class Binder implements Serializable { // Item validator failed, revert values bindings.forEach((BindingImpl binding) -> binding.setBeanValue(bean, oldValues.get(binding))); + } else { + // Save successful, reset hasChanges to false + setHasChanges(false); } return itemValidatorErrors; } @@ -1149,4 +1158,26 @@ public class Binder implements Serializable { } } + /** + * Sets whether the values of the fields this binder is bound to have + * changed since the last explicit call to either bind, save or load. + * + * @param hasChanges + * whether this binder should be marked to have changes + */ + private void setHasChanges(boolean hasChanges) { + this.hasChanges = hasChanges; + } + + /** + * Check whether any of the bound fields' values have changed since last + * explicit call to bind, save or load. Unsuccessful save operations will + * not affect this value. + * + * @return whether any bound field's value has changed since last call to + * bind, save or load + */ + public boolean hasChanges() { + return hasChanges; + } } diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java index e6b78eb6b3..4b69fdf50e 100644 --- a/server/src/test/java/com/vaadin/data/BinderTest.java +++ b/server/src/test/java/com/vaadin/data/BinderTest.java @@ -1059,4 +1059,31 @@ public class BinderTest { Assert.assertEquals(1, results.size()); } + @Test + public void binderHasChanges() throws ValidationException { + binder.forField(nameField) + .withValidator(Validator.from(name -> !"".equals(name), + "Name can't be empty")) + .bind(Person::getFirstName, Person::setFirstName); + Assert.assertFalse(binder.hasChanges()); + binder.bind(p); + Assert.assertFalse(binder.hasChanges()); + + nameField.setValue("foo"); + Assert.assertTrue(binder.hasChanges()); + binder.load(p); + Assert.assertFalse(binder.hasChanges()); + + nameField.setValue("bar"); + binder.saveIfValid(new Person()); + Assert.assertFalse(binder.hasChanges()); + + nameField.setValue("baz"); + binder.save(new Person()); + Assert.assertFalse(binder.hasChanges()); + + nameField.setValue(""); + binder.saveIfValid(new Person()); + Assert.assertTrue(binder.hasChanges()); + } } -- 2.39.5