aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarco Collovati <mcollovati@gmail.com>2017-09-20 07:32:04 +0200
committerHenri Sara <henri.sara@gmail.com>2017-09-26 18:24:43 +0300
commitc9d537b26bdec8dde8660e8ead63aeee3bd5fc1c (patch)
treec639c41def961051a8c0d63a8e4bdeae530f4aa7
parent79b286e8e928ba79cf2486a1adb2551c59c40652 (diff)
downloadvaadin-framework-c9d537b26bdec8dde8660e8ead63aeee3bd5fc1c.tar.gz
vaadin-framework-c9d537b26bdec8dde8660e8ead63aeee3bd5fc1c.zip
Show validation error selecting invalid date from DateField (#10013)
Component error was cleared after selecting a date from calendar popup, even if the date is invalid due to validation errors or if user programmatically sets an UserError. This change inverts the order of setValue() and setComponentError(null) in order to preserve errors set by ValueChangeListeners (e.g. Binder validators). Fixes #10011
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractDateField.java2
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldValidationError.java31
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldValidationErrorTest.java57
3 files changed, 89 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 2ad976a7fe..bc6b5f49a8 100644
--- a/server/src/main/java/com/vaadin/ui/AbstractDateField.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractDateField.java
@@ -249,8 +249,8 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
if (newDateString == null || newDateString.isEmpty()) {
uiHasValidDateString = true;
currentParseErrorMessage = null;
- setValue(newDate, true);
setComponentError(null);
+ setValue(newDate, true);
} else {
if (variables.get("lastInvalidDateString") != null) {
Result<T> parsedDate = handleUnparsableDateString(
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldValidationError.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldValidationError.java
new file mode 100644
index 0000000000..0bc9e1438d
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldValidationError.java
@@ -0,0 +1,31 @@
+package com.vaadin.tests.components.datefield;
+
+import java.time.LocalDate;
+import java.util.Locale;
+
+import com.vaadin.annotations.Widgetset;
+import com.vaadin.data.Binder;
+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.Notification;
+
+@Widgetset("com.vaadin.DefaultWidgetSet")
+public class DateFieldValidationError extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ DateField df = new DateField();
+ df.setLocale(Locale.US);
+ Binder<Void> binder = new Binder<>();
+ binder.forField(df)
+ .withValidator(localDate -> localDate != null && localDate.isAfter(LocalDate.now()), "Invalid date")
+ .bind(v -> LocalDate.now(), (v, t) -> {
+ /* NO-OP */
+ });
+ addComponent(df);
+ addComponent(new Button("Validate", e -> Notification.show(binder.validate().isOk() ? "OK" : "Fail")));
+ }
+
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldValidationErrorTest.java b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldValidationErrorTest.java
new file mode 100644
index 0000000000..6bfa1d2e2b
--- /dev/null
+++ b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldValidationErrorTest.java
@@ -0,0 +1,57 @@
+package com.vaadin.tests.components.datefield;
+
+import java.time.LocalDate;
+
+import com.vaadin.testbench.elements.DateFieldElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+
+public class DateFieldValidationErrorTest extends MultiBrowserTest {
+
+ @Test
+ public void testComponentErrorShouldBeShownWhenEnteringInvalidDate() throws InterruptedException {
+ openTestURL();
+ DateFieldElement dateField = $(DateFieldElement.class).first();
+ dateField.getInputElement().click();
+ dateField.getInputElement().sendKeys("01/01/01", Keys.TAB);
+
+ assertHasErrorMessage(dateField);
+ }
+
+ @Test
+ public void testComponentErrorShouldBeShownWhenSelectingInvalidDate() throws InterruptedException {
+ openTestURL();
+ DateFieldElement dateField = $(DateFieldElement.class).first();
+ dateField.setDate(LocalDate.now());
+ dateField.openPopup();
+ waitUntil(ExpectedConditions.visibilityOfElementLocated(By.className("v-datefield-popup")));
+
+ WebElement popup = findElement(com.vaadin.testbench.By.className("v-datefield-popup"));
+ // select day before today
+ WebElement popupBody = popup.findElement(By.className("v-datefield-calendarpanel"));
+ popupBody.sendKeys(Keys.ARROW_LEFT, Keys.ENTER);
+
+ // move focus away otherwise tooltip is not shown
+ WebElement inputElement = dateField.getInputElement();
+ inputElement.click();
+ inputElement.sendKeys(Keys.TAB);
+
+ assertHasErrorMessage(dateField);
+ }
+
+ private void assertHasErrorMessage(DateFieldElement dateField) {
+ waitForElementPresent(By.className("v-errorindicator"));
+ dateField.showTooltip();
+ waitUntil(driver -> "Invalid date".equals(getTooltipErrorElement().getText()));
+ }
+
+ @Override
+ protected boolean requireWindowFocusForIE() {
+ return true;
+ }
+
+}