diff options
author | Márcio P. Dantas <marciopd@gmail.com> | 2018-03-26 17:44:28 +0300 |
---|---|---|
committer | Ilia Motornyi <elmot@vaadin.com> | 2018-03-26 17:44:28 +0300 |
commit | 3c52491a5b44456f94777e6cec71af2a1a70ae46 (patch) | |
tree | fd9853a6a92265d99378fd1707c905a933345772 /server/src | |
parent | f3e06f4f4157ed4675619608b5da4cd7e5584876 (diff) | |
download | vaadin-framework-3c52491a5b44456f94777e6cec71af2a1a70ae46.tar.gz vaadin-framework-3c52491a5b44456f94777e6cec71af2a1a70ae46.zip |
Added method asRequired with a custom required validator to BindingBuilder. (#10724)
Diffstat (limited to 'server/src')
-rw-r--r-- | server/src/main/java/com/vaadin/data/Binder.java | 30 | ||||
-rw-r--r-- | server/src/test/java/com/vaadin/data/BinderTest.java | 92 |
2 files changed, 119 insertions, 3 deletions
diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java index f9e076e13f..360daa73bf 100644 --- a/server/src/main/java/com/vaadin/data/Binder.java +++ b/server/src/main/java/com/vaadin/data/Binder.java @@ -728,6 +728,23 @@ public class Binder<BEAN> implements Serializable { */ public BindingBuilder<BEAN, TARGET> asRequired( ErrorMessageProvider errorMessageProvider); + + /** + * Sets the field to be required and delegates the required check to a custom validator. + * This means two things: + * <ol> + * <li>the required indicator will be displayed for this field</li> + * <li>the field value is validated by customRequiredValidator</li> + * </ol> + * + * @see HasValue#setRequiredIndicatorVisible(boolean) + * @param customRequiredValidator + * validator responsible for the required check + * @return this binding, for chaining + * @since + */ + public BindingBuilder<BEAN, TARGET> asRequired( + Validator<TARGET> customRequiredValidator); } /** @@ -885,11 +902,18 @@ public class Binder<BEAN> implements Serializable { @Override public BindingBuilder<BEAN, TARGET> asRequired( ErrorMessageProvider errorMessageProvider) { + return asRequired( + Validator.from( + value -> !Objects.equals(value, field.getEmptyValue()), + errorMessageProvider)); + } + + @Override + public BindingBuilder<BEAN, TARGET> asRequired( + Validator<TARGET> customRequiredValidator) { checkUnbound(); field.setRequiredIndicatorVisible(true); - return withValidator( - value -> !Objects.equals(value, field.getEmptyValue()), - errorMessageProvider); + return withValidator(customRequiredValidator); } /** diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java index 0163b65b51..5ca469011c 100644 --- a/server/src/test/java/com/vaadin/data/BinderTest.java +++ b/server/src/test/java/com/vaadin/data/BinderTest.java @@ -30,6 +30,7 @@ import com.vaadin.shared.ui.ErrorLevel; import com.vaadin.tests.data.bean.Person; import com.vaadin.tests.data.bean.Sex; import com.vaadin.ui.TextField; +import org.apache.commons.lang.StringUtils; public class BinderTest extends BinderTestBase<Binder<Person>, Person> { @@ -502,6 +503,97 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> { } @Test + public void setRequired_withCustomValidator_fieldGetsRequiredIndicatorAndValidator() { + TextField textField = new TextField(); + textField.setLocale(Locale.CANADA); + assertFalse(textField.isRequiredIndicatorVisible()); + + BindingBuilder<Person, String> binding = binder.forField(textField); + assertFalse(textField.isRequiredIndicatorVisible()); + AtomicInteger invokes = new AtomicInteger(); + + Validator<String> customRequiredValidator = (value, context) -> { + invokes.incrementAndGet(); + if (StringUtils.isBlank(value)) { + return ValidationResult.error("Input is required."); + } + return ValidationResult.ok(); + }; + binding.asRequired(customRequiredValidator); + assertTrue(textField.isRequiredIndicatorVisible()); + + binding.bind(Person::getFirstName, Person::setFirstName); + binder.setBean(item); + assertNull(textField.getErrorMessage()); + assertEquals(0, invokes.get()); + + textField.setValue(" "); + ErrorMessage errorMessage = textField.getErrorMessage(); + assertNotNull(errorMessage); + assertEquals("Input is required.", errorMessage.getFormattedHtmlMessage()); + // validation is done for all changed bindings once. + assertEquals(1, invokes.get()); + + textField.setValue("value"); + assertNull(textField.getErrorMessage()); + assertTrue(textField.isRequiredIndicatorVisible()); + } + + @Test + public void setRequired_withCustomValidator_modelConverterBeforeValidator() { + TextField textField = new TextField(); + textField.setLocale(Locale.CANADA); + assertFalse(textField.isRequiredIndicatorVisible()); + + Converter<String, String> stringBasicPreProcessingConverter = new Converter<String, String>() { + @Override + public Result<String> convertToModel(String value, ValueContext context) { + if (StringUtils.isBlank(value)) { + return Result.ok(null); + } + return Result.ok(StringUtils.trim(value)); + } + + @Override + public String convertToPresentation(String value, ValueContext context) { + if (value == null) { + return ""; + } + return value; + } + }; + + AtomicInteger invokes = new AtomicInteger(); + Validator<String> customRequiredValidator = (value, context) -> { + invokes.incrementAndGet(); + if (value == null) { + return ValidationResult.error("Input required."); + } + return ValidationResult.ok(); + }; + + binder.forField(textField) + .withConverter(stringBasicPreProcessingConverter) + .asRequired(customRequiredValidator) + .bind(Person::getFirstName, Person::setFirstName); + + binder.setBean(item); + assertNull(textField.getErrorMessage()); + assertEquals(0, invokes.get()); + + textField.setValue(" "); + ErrorMessage errorMessage = textField.getErrorMessage(); + assertNotNull(errorMessage); + assertEquals("Input required.", errorMessage.getFormattedHtmlMessage()); + // validation is done for all changed bindings once. + assertEquals(1, invokes.get()); + + textField.setValue("value"); + assertNull(textField.getErrorMessage()); + assertTrue(textField.isRequiredIndicatorVisible()); + } + + @Test public void validationStatusHandler_onlyRunForChangedField() { TextField firstNameField = new TextField(); TextField lastNameField = new TextField(); |