summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/src/main/java/com/vaadin/client/ui/ShortcutActionHandler.java42
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/CompatibilityDateFieldShortcut.java47
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/datefield/CompatibilityDateFieldShortcutTest.java39
3 files changed, 125 insertions, 3 deletions
diff --git a/client/src/main/java/com/vaadin/client/ui/ShortcutActionHandler.java b/client/src/main/java/com/vaadin/client/ui/ShortcutActionHandler.java
index 7499779352..1c03a2719d 100644
--- a/client/src/main/java/com/vaadin/client/ui/ShortcutActionHandler.java
+++ b/client/src/main/java/com/vaadin/client/ui/ShortcutActionHandler.java
@@ -126,15 +126,31 @@ public class ShortcutActionHandler {
target = Util.findPaintable(client, et);
}
final ComponentConnector finalTarget = target;
-
event.preventDefault();
-
/*
* The focused component might have unpublished changes, try to
* synchronize them before firing shortcut action.
*/
client.flushActiveConnector();
-
+ /*
+ * Legacy components don't have built-in logic for flushing, they need a
+ * workaround with blur and focus to trigger the value change.
+ */
+ ComponentConnector activeConnector = getActiveConnector(client);
+ if (activeConnector != null) {
+ Class<?> clz = activeConnector.getClass();
+ while (clz != null) {
+ if (clz.getName().equals(
+ "com.vaadin.v7.client.ui.AbstractLegacyComponentConnector")) {
+ shakeTarget(et);
+ Scheduler.get().scheduleDeferred(() -> {
+ shakeTarget(et);
+ });
+ break;
+ }
+ clz = clz.getSuperclass();
+ }
+ }
Scheduler.get().scheduleDeferred(() -> {
if (finalTarget != null) {
client.updateVariable(paintableId, "actiontarget", finalTarget,
@@ -144,6 +160,26 @@ public class ShortcutActionHandler {
});
}
+ /**
+ * We try to fire value change in the component the key combination was
+ * typed. E.g. TextField may contain newly typed text that is expected to be
+ * sent to server before the shortcut action is triggered. This is done by
+ * removing focus and then returning it immediately back to target element.
+ * <p>
+ * This is a hack copied over from V7 in order to keep the compatibility
+ * classes working. Main V8 classes don't require shaking.
+ */
+ private static void shakeTarget(final Element e) {
+ blur(e);
+ focus(e);
+ }
+
+ private static native ComponentConnector getActiveConnector(
+ ApplicationConnection ac)
+ /*-{
+ return ac.@com.vaadin.client.ApplicationConnection::getActiveConnector()();
+ }-*/;
+
private static native void blur(Element e)
/*-{
if (e.blur) {
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/CompatibilityDateFieldShortcut.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/CompatibilityDateFieldShortcut.java
new file mode 100644
index 0000000000..0881ced2fc
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/CompatibilityDateFieldShortcut.java
@@ -0,0 +1,47 @@
+package com.vaadin.tests.components.datefield;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.event.ShortcutListener;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Notification;
+import com.vaadin.v7.ui.DateField;
+
+@SuppressWarnings("deprecation")
+public class CompatibilityDateFieldShortcut extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ String dateFormat = "dd/MM/yyyy";
+
+ DateField dateField = new DateField();
+ dateField.setValue(new Date(2018 - 1900, 0, 11));
+ dateField.setDateFormat(dateFormat);
+
+ dateField.addShortcutListener(
+ new ShortcutListener("Enter", KeyCode.ENTER, null) {
+ @Override
+ public void handleAction(Object sender, Object target) {
+ SimpleDateFormat df = new SimpleDateFormat(dateFormat);
+ Notification.show(df.format(dateField.getValue()));
+ }
+ });
+
+ addComponent(dateField);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Modify the date manually (without using the popup element) and"
+ + " then press Enter. The notification should show the modified"
+ + " value instead of the old value.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 10854;
+ }
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/datefield/CompatibilityDateFieldShortcutTest.java b/uitest/src/test/java/com/vaadin/tests/components/datefield/CompatibilityDateFieldShortcutTest.java
new file mode 100644
index 0000000000..8ed2da2b77
--- /dev/null
+++ b/uitest/src/test/java/com/vaadin/tests/components/datefield/CompatibilityDateFieldShortcutTest.java
@@ -0,0 +1,39 @@
+package com.vaadin.tests.components.datefield;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elements.DateFieldElement;
+import com.vaadin.testbench.elements.NotificationElement;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class CompatibilityDateFieldShortcutTest extends SingleBrowserTest {
+
+ private static final String DATEFIELD_VALUE_ORIGINAL = "11/01/2018";
+ private static final String DATEFIELD_VALUE_MODIFIED = "21/01/2018";
+
+ @Test
+ public void modifyValueAndPressEnter() {
+ openTestURL();
+
+ DateFieldElement dateField = $(DateFieldElement.class).first();
+ WebElement dateFieldText = dateField.findElement(By.tagName("input"));
+
+ assertEquals("DateField value should be \"" + DATEFIELD_VALUE_ORIGINAL
+ + "\"", DATEFIELD_VALUE_ORIGINAL, dateField.getValue());
+
+ dateFieldText.click();
+ dateFieldText.sendKeys(Keys.HOME, Keys.DELETE, "2");
+ dateFieldText.sendKeys(Keys.ENTER);
+
+ assertEquals("DateField value should be \"" + DATEFIELD_VALUE_MODIFIED
+ + "\"", DATEFIELD_VALUE_MODIFIED, dateField.getValue());
+
+ assertEquals(DATEFIELD_VALUE_MODIFIED,
+ $(NotificationElement.class).first().getCaption());
+ }
+}