diff options
author | Tatu Lund <tatu@vaadin.com> | 2021-02-19 11:11:49 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-19 11:11:49 +0200 |
commit | 551177326f6ae8c4ddd7d5b3ab3bb3311304cc0a (patch) | |
tree | 9f370578832547243f8f516b7f2b30ce79fb1194 | |
parent | 45ed0c173aedb8c0b7194ed0b8eb656d24ddac9d (diff) | |
download | vaadin-framework-551177326f6ae8c4ddd7d5b3ab3bb3311304cc0a.tar.gz vaadin-framework-551177326f6ae8c4ddd7d5b3ab3bb3311304cc0a.zip |
Add API to prevent invalid input when integrated range validator is used (#12168)
Do not fire DateField's value change event if the new date is not within the range.
Fixes: #12163
3 files changed, 106 insertions, 1 deletions
diff --git a/server/src/main/java/com/vaadin/ui/AbstractDateField.java b/server/src/main/java/com/vaadin/ui/AbstractDateField.java index dbbc19b673..d14393c541 100644 --- a/server/src/main/java/com/vaadin/ui/AbstractDateField.java +++ b/server/src/main/java/com/vaadin/ui/AbstractDateField.java @@ -160,7 +160,14 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & } } } else { - setValue(newDate, true); + RangeValidator<T> validator = getRangeValidator(); + ValidationResult result = validator.apply(newDate, + new ValueContext()); + if (!isPreventInvalidInput() || !result.isError()) { + setValue(newDate, true); + } else { + doSetValue(newDate); + } } } } @@ -229,6 +236,8 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & private String dateOutOfRangeMessage = "Date is out of allowed range"; + private boolean preventInvalidInput = false; + /* Constructors */ /** @@ -1130,4 +1139,28 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & public void getAssistiveLabel(AccessibleElement element) { getState(false).assistiveLabels.get(element); } + + /** + * Control whether value change event is emitted when user input value + * does not meet the integrated range validator. + * + * @param preventInvalidInput Set to false to disable the value change event. + * + * @since 8.13 + */ + public void setPreventInvalidInput(boolean preventInvalidInput) { + this.preventInvalidInput = preventInvalidInput; + } + + /** + * Check whether value change is emitted when user input value does + * not meet integrated range validator. The default is false. + * + * @return a Boolean value + * + * @since 8.13 + */ + public boolean isPreventInvalidInput() { + return preventInvalidInput; + } } diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPreventInvalidInput.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPreventInvalidInput.java new file mode 100644 index 0000000000..257feefb6b --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPreventInvalidInput.java @@ -0,0 +1,32 @@ +package com.vaadin.tests.components.datefield; + +import java.time.LocalDate; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.DateField; +import com.vaadin.ui.Label; + +public class DateFieldPreventInvalidInput extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + DateField dateField = new DateField(); + dateField.setRangeStart(LocalDate.ofYearDay(2019, 1)); + dateField.setRangeEnd(LocalDate.ofYearDay(2019, 365)); + dateField.setPreventInvalidInput(true); + Button button = new Button("", event -> { + dateField.clear(); + dateField.setPreventInvalidInput(false); + }); + Label value = new Label(); + value.setValue("no-value"); + value.setId("value"); + dateField.addValueChangeListener(event -> { + value.setValue(dateField.getValue().toString()); + }); + addComponents(dateField,value,button); + } + +} diff --git a/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldPreventInvalidInputTest.java b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldPreventInvalidInputTest.java new file mode 100644 index 0000000000..9b3d1c1ef8 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldPreventInvalidInputTest.java @@ -0,0 +1,40 @@ +package com.vaadin.tests.components.datefield; + +import static org.junit.Assert.assertEquals; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.DateFieldElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class DateFieldPreventInvalidInputTest extends SingleBrowserTest { + + @Test + public void modifyValueAndPressTab() { + openTestURL(); + DateFieldElement dateField = $(DateFieldElement.class).first(); + + WebElement dateTextbox = dateField + .findElement(By.className("v-textfield")); + ButtonElement button = $(ButtonElement.class).first(); + LabelElement label = $(LabelElement.class).id("value"); + + // DateField is set not accept invalid input, this date is not in range + dateTextbox.click(); + dateTextbox.sendKeys("01/01/21", Keys.TAB); + assertEquals("no-value", label.getText()); + + // Set DateField accept invalid input + button.click(); + + dateTextbox.click(); + dateTextbox.sendKeys("01/01/21", Keys.TAB); + Assert.assertNotEquals("no-value", label.getText()); + } +} |