diff options
author | Tatu Lund <tatu@vaadin.com> | 2019-11-29 14:33:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-29 14:33:59 +0200 |
commit | dda9b052604967b8d8cfec5c20d06e72f6f78d33 (patch) | |
tree | 55a257469a401f6f4f0564a6ac5367455529050a | |
parent | a8bce6437bb3fb05fa52910cc80cde325b1e72a9 (diff) | |
download | vaadin-framework-dda9b052604967b8d8cfec5c20d06e72f6f78d33.tar.gz vaadin-framework-dda9b052604967b8d8cfec5c20d06e72f6f78d33.zip |
Add method writeBeanAsDraft(bean) in Binder (#11833)
* Add method writeBeanAsDraft(bean) in Binder
With current Binder implementation it is not easy to support Forms, which you want to save as draft, i.e. incomplete. For example there can be big text areas, that require time to fill, or lot of fields. Therefore it is needed to that form can be saved, e.g. to other bean in incomplete state when it is not yet passing validation and this other bean can be persisted to draft storage for further editing in the future. This method helps to achieve that easily.
* Add test case for Binder.writeBeanAsDraft(bean)
Bind a field with validator, set value that does not pass validator and save, assert that value was saved.
* Updating test
* Fixing logic flaw in test
* Further improvement of the test case
* Clarification of the JavaDoc
* Fixing typo
* JavaDoc language check
* Fixing whitespace issue
* Fixing whitespaces
* Fixing whitespaces
* Updating JavaDoc
-rw-r--r-- | server/src/main/java/com/vaadin/data/Binder.java | 34 | ||||
-rw-r--r-- | server/src/test/java/com/vaadin/data/BinderTest.java | 33 |
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); |