]> source.dussan.org Git - vaadin-framework.git/commitdiff
Add API to prevent invalid input when integrated range validator is used (#12168)
authorTatu Lund <tatu@vaadin.com>
Fri, 19 Feb 2021 09:11:49 +0000 (11:11 +0200)
committerGitHub <noreply@github.com>
Fri, 19 Feb 2021 09:11:49 +0000 (11:11 +0200)
Do not fire DateField's value change event if the new date is not within the range.

Fixes: #12163
server/src/main/java/com/vaadin/ui/AbstractDateField.java
uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldPreventInvalidInput.java [new file with mode: 0644]
uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldPreventInvalidInputTest.java [new file with mode: 0644]

index dbbc19b673c8dd1e762f1531659342a43d2bf919..d14393c5419c4b541f290b2197065420e4b0b9a3 100644 (file)
@@ -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 (file)
index 0000000..257feef
--- /dev/null
@@ -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 (file)
index 0000000..9b3d1c1
--- /dev/null
@@ -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());
+    }
+}