aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/src/main/java/com/vaadin/data/Binder.java34
-rw-r--r--server/src/test/java/com/vaadin/data/BinderTest.java33
2 files changed, 67 insertions, 0 deletions
diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java
index 699185dea3..747983bfa5 100644
--- a/server/src/main/java/com/vaadin/data/Binder.java
+++ b/server/src/main/java/com/vaadin/data/Binder.java
@@ -1787,6 +1787,23 @@ public class Binder<BEAN> implements Serializable {
}
/**
+ * Writes successfully converted and validated changes from the bound fields
+ * to the bean even if there are other fields with non-validated changes.
+ *
+ * @see #writeBean(Object)
+ * @see #writeBeanIfValid(Object)
+ * @see #readBean(Object)
+ * @see #setBean(Object)
+ *
+ * @param bean
+ * the object to which to write the field values, not
+ * {@code null}
+ */
+ public void writeBeanAsDraft(BEAN bean) {
+ doWriteDraft(bean, new ArrayList<>(bindings));
+ }
+
+ /**
* Writes changes from the bound fields to the given bean if all validators
* (binding and bean level) pass.
* <p>
@@ -1874,6 +1891,23 @@ public class Binder<BEAN> implements Serializable {
}
/**
+ * Writes the successfully converted and validated field values into the
+ * given bean.
+ *
+ * @param bean
+ * the bean to write field values into
+ * @param bindings
+ * the set of bindings to write to the bean
+ */
+ @SuppressWarnings({ "unchecked" })
+ private void doWriteDraft(BEAN bean, Collection<Binding<BEAN, ?>> bindings) {
+ Objects.requireNonNull(bean, "bean cannot be null");
+
+ bindings.forEach(binding -> ((BindingImpl<BEAN, ?, ?>) binding)
+ .writeFieldValue(bean));
+ }
+
+ /**
* Restores the state of the bean from the given values. This method is used
* together with {@link #getBeanState(Object, Collection)} to provide a way
* to revert changes in case the bean validation fails after save.
diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java
index 3e27cc5f9b..401cc07017 100644
--- a/server/src/test/java/com/vaadin/data/BinderTest.java
+++ b/server/src/test/java/com/vaadin/data/BinderTest.java
@@ -270,6 +270,39 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> {
}
@Test
+ public void save_bound_beanAsDraft() {
+ Binder<Person> binder = new Binder<>();
+ binder.forField(nameField)
+ .withValidator((value,context) -> {
+ if (value.equals("Mike")) return ValidationResult.ok();
+ else return ValidationResult.error("value must be Mike");
+ })
+ .bind(Person::getFirstName, Person::setFirstName);
+ binder.forField(ageField)
+ .withConverter(new StringToIntegerConverter(""))
+ .bind(Person::getAge, Person::setAge);
+
+ Person person = new Person();
+
+ String fieldValue = "John";
+ nameField.setValue(fieldValue);
+
+ int age = 10;
+ ageField.setValue("10");
+
+ person.setFirstName("Mark");
+
+ binder.writeBeanAsDraft(person);
+
+ // name is not written to draft as validation / conversion
+ // does not pass
+ assertNotEquals(fieldValue, person.getFirstName());
+ // age is written to draft even if firstname validation
+ // fails
+ assertEquals(age, person.getAge());
+ }
+
+ @Test
public void load_bound_fieldValueIsUpdated() {
binder.bind(nameField, Person::getFirstName, Person::setFirstName);