summaryrefslogtreecommitdiffstats
path: root/server/src
diff options
context:
space:
mode:
authorTatu Lund <tatu@vaadin.com>2020-12-03 05:27:30 +0200
committerGitHub <noreply@github.com>2020-12-03 05:27:30 +0200
commit5c839bc6837b90d72561f3a478c0d6089a8f17ba (patch)
tree4b17b1a847d36805266f3520c7861e608b12ca37 /server/src
parentd59c3d303be95d38320f94b5d7cde068824d81fd (diff)
downloadvaadin-framework-5c839bc6837b90d72561f3a478c0d6089a8f17ba.tar.gz
vaadin-framework-5c839bc6837b90d72561f3a478c0d6089a8f17ba.zip
Binder: Also use converter for user-changed values (#12132)
See: https://vaadin.com/forum/thread/15931682
Diffstat (limited to 'server/src')
-rw-r--r--server/src/main/java/com/vaadin/data/Binder.java10
-rw-r--r--server/src/test/java/com/vaadin/data/BinderTest.java65
2 files changed, 74 insertions, 1 deletions
diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java
index d0ea628986..481b6df361 100644
--- a/server/src/main/java/com/vaadin/data/Binder.java
+++ b/server/src/main/java/com/vaadin/data/Binder.java
@@ -1282,7 +1282,15 @@ public class Binder<BEAN> implements Serializable {
Result<TARGET> result = doConversion();
if (!isReadOnly()) {
- result.ifOk(value -> setter.accept(bean, value));
+ result.ifOk(value -> {
+ setter.accept(bean, value);
+ if (value != null) {
+ FIELDVALUE converted = convertToFieldType(value);
+ if (!field.getValue().equals(converted)) {
+ getField().setValue(converted);
+ }
+ }
+ });
}
return toValidationStatus(result);
}
diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java
index b64dee9c6b..0332572203 100644
--- a/server/src/test/java/com/vaadin/data/BinderTest.java
+++ b/server/src/test/java/com/vaadin/data/BinderTest.java
@@ -10,6 +10,9 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -25,6 +28,7 @@ import org.junit.rules.ExpectedException;
import com.vaadin.data.Binder.Binding;
import com.vaadin.data.Binder.BindingBuilder;
+import com.vaadin.data.converter.StringToBigDecimalConverter;
import com.vaadin.data.converter.StringToIntegerConverter;
import com.vaadin.data.validator.IntegerRangeValidator;
import com.vaadin.data.validator.NotEmptyValidator;
@@ -501,6 +505,19 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> {
}
@Test
+ public void withConverter_writeBackValue() {
+ TextField rentField = new TextField();
+ rentField.setValue("");
+ binder.forField(rentField).withConverter(new EuroConverter(""))
+ .withNullRepresentation(BigDecimal.valueOf(0d))
+ .bind(Person::getRent, Person::setRent);
+ binder.setBean(item);
+ rentField.setValue("10");
+
+ assertEquals("€ 10.00", rentField.getValue());
+ }
+
+ @Test
public void beanBinder_nullRepresentationIsNotDisabled() {
Binder<Person> binder = new Binder<>(Person.class);
binder.forField(nameField).bind("firstName");
@@ -1483,4 +1500,52 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> {
.bind(AtomicReference::get, AtomicReference::set);
return binder;
}
+
+ /**
+ * A converter that adds/removes the euro sign and formats currencies with
+ * two decimal places.
+ */
+ public class EuroConverter extends StringToBigDecimalConverter {
+
+ public EuroConverter() {
+ super("defaultErrorMessage");
+ }
+
+ public EuroConverter(String errorMessage) {
+ super(errorMessage);
+ }
+
+ @Override
+ public Result<BigDecimal> convertToModel(String value,
+ ValueContext context) {
+ if (value.isEmpty()) {
+ return Result.ok(null);
+ }
+ value = value.replaceAll("[€\\s]", "").trim();
+ if (value.isEmpty()) {
+ value = "0";
+ }
+ return super.convertToModel(value, context);
+ }
+
+ @Override
+ public String convertToPresentation(BigDecimal value,
+ ValueContext context) {
+ if (value == null) {
+ return convertToPresentation(BigDecimal.ZERO, context);
+ }
+ return "€ " + super.convertToPresentation(value, context);
+ }
+
+ @Override
+ protected NumberFormat getFormat(Locale locale) {
+ // Always display currency with two decimals
+ NumberFormat format = super.getFormat(locale);
+ if (format instanceof DecimalFormat) {
+ ((DecimalFormat) format).setMaximumFractionDigits(2);
+ ((DecimalFormat) format).setMinimumFractionDigits(2);
+ }
+ return format;
+ }
+ }
}