diff options
6 files changed, 142 insertions, 25 deletions
diff --git a/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java b/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java index 70bec08e4f..f009f483e0 100644 --- a/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java +++ b/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java @@ -1997,7 +1997,6 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>> renderCalendar(); } } - } /** diff --git a/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java b/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java index d894653609..4df4d0e325 100644 --- a/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java +++ b/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java @@ -377,7 +377,6 @@ public abstract class VAbstractPopupCalendar<PANEL extends VAbstractCalendarPane * Opens the calendar panel popup. */ public void openCalendarPanel() { - if (!open && !readonly && isEnabled()) { open = true; @@ -393,6 +392,8 @@ public abstract class VAbstractPopupCalendar<PANEL extends VAbstractCalendarPane popup.setWidth(""); popup.setHeight(""); popup.setPopupPositionAndShow(new PopupPositionCallback()); + + checkGroupFocus(true); } else { getLogger().severe("Cannot reopen popup, it is already open!"); } @@ -451,6 +452,7 @@ public abstract class VAbstractPopupCalendar<PANEL extends VAbstractCalendarPane * Sets focus to Calendar panel. * * @param focus + * {@code true} for {@code focus}, {@code false} for {@code blur} */ public void setFocus(boolean focus) { calendar.setFocus(focus); @@ -683,19 +685,16 @@ public abstract class VAbstractPopupCalendar<PANEL extends VAbstractCalendarPane // are in the lower right corner of the screen if (overflow) { return left; - } else { - return left + calendarToggle.getOffsetWidth(); - } - } else { - int[] margins = style.getMargin(); - int desiredLeftPosition = calendarToggle.getAbsoluteLeft() - - width - margins[1] - margins[3]; - if (desiredLeftPosition >= 0) { - return desiredLeftPosition; - } else { - return left; } + return left + calendarToggle.getOffsetWidth(); } + int[] margins = style.getMargin(); + int desiredLeftPosition = calendarToggle.getAbsoluteLeft() - width + - margins[1] - margins[3]; + if (desiredLeftPosition >= 0) { + return desiredLeftPosition; + } + return left; } private boolean positionRightSide() { @@ -721,6 +720,11 @@ public abstract class VAbstractPopupCalendar<PANEL extends VAbstractCalendarPane } } + @Override + protected boolean hasChildFocus() { + return open; + } + private static Logger getLogger() { return Logger.getLogger(VAbstractPopupCalendar.class.getName()); } diff --git a/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java b/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java index 66ddf1d829..11102a218e 100644 --- a/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java +++ b/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java @@ -21,6 +21,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import com.google.gwt.aria.client.Roles; +import com.google.gwt.core.client.Scheduler; import com.google.gwt.dom.client.Element; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; @@ -76,14 +77,19 @@ public abstract class VAbstractTextualDate<R extends Enum<R>> /** For internal use only. May be removed or replaced in the future. */ private TimeZone timeZone; + /** + * Specifies whether the group of components has focus or not. + */ + private boolean groupFocus; + public VAbstractTextualDate(R resoluton) { super(resoluton); text = new TextBox(); text.addChangeHandler(this); text.addFocusHandler( - event -> fireBlurFocusEvent(event, true, EventId.FOCUS)); + event -> fireBlurFocusEvent(event, true)); text.addBlurHandler( - event -> fireBlurFocusEvent(event, false, EventId.BLUR)); + event -> fireBlurFocusEvent(event, false)); if (BrowserInfo.get().isIE()) { addDomHandler(this, KeyDownEvent.getType()); } @@ -394,27 +400,54 @@ public abstract class VAbstractTextualDate<R extends Enum<R>> } private void fireBlurFocusEvent(DomEvent<?> event, - boolean addFocusStyleName, String eventId) { + boolean focus) { String styleName = VTextField.CLASSNAME + "-" + VTextField.CLASSNAME_FOCUS; - if (addFocusStyleName) { + if (focus) { text.addStyleName(styleName); } else { text.removeStyleName(styleName); } - if (getClient() != null && connector.hasEventListener(eventId)) { - // may excessively send events if if focus went to another - // sub-component - if (EventId.FOCUS.equals(eventId)) { + + Scheduler.get().scheduleDeferred(() -> checkGroupFocus(focus)); + + // Needed for tooltip event handling + fireEvent(event); + } + + /** + * Checks if the group focus has changed, and sends to the server if needed. + * + * @param textFocus + * the focus of the {@link #text} + * @since + */ + protected void checkGroupFocus(boolean textFocus) { + boolean newGroupFocus = textFocus | hasChildFocus(); + if (getClient() != null + && connector.hasEventListener( + textFocus ? EventId.FOCUS : EventId.BLUR) + && groupFocus != newGroupFocus) { + + if (newGroupFocus) { rpc.focus(); } else { rpc.blur(); } sendBufferedValues(); + groupFocus = newGroupFocus; } + } - // Needed for tooltip event handling - fireEvent(event); + /** + * Returns whether any of the child components has focus. + * + * @return {@code true} if any of the child component has focus, + * {@code false} otherwise + * @since + */ + protected boolean hasChildFocus() { + return false; } /** @@ -479,4 +512,5 @@ public abstract class VAbstractTextualDate<R extends Enum<R>> private static Logger getLogger() { return Logger.getLogger(VAbstractTextualDate.class.getName()); } + } diff --git a/uitest/src/main/java/com/vaadin/tests/components/FocusAndBlurListeners.java b/uitest/src/main/java/com/vaadin/tests/components/FocusAndBlurListeners.java index b1e5f2ef59..d34eadf7f6 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/FocusAndBlurListeners.java +++ b/uitest/src/main/java/com/vaadin/tests/components/FocusAndBlurListeners.java @@ -43,7 +43,7 @@ public class FocusAndBlurListeners extends TestBase { AbstractDateField<?, ?> df = new TestDateField("DateField"); l.addComponent(df); - ComboBox cb = new ComboBox("ComboBox"); + ComboBox<String> cb = new ComboBox<>("ComboBox"); l.addComponent(cb); Button btn = new Button("Button"); @@ -91,7 +91,6 @@ public class FocusAndBlurListeners extends TestBase { ogm.addBlurListener(blurListener); l.addComponent(messages); - } private OptionGroup createOptionGroup(String caption) { diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldFocus.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldFocus.java new file mode 100644 index 0000000000..2edfa0ab9f --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldFocus.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.datefield; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.DateField; +import com.vaadin.ui.TextField; + +public class DateFieldFocus extends AbstractTestUIWithLog { + + @Override + protected void setup(VaadinRequest request) { + DateField dateField = new DateField(); + dateField.addFocusListener(e -> log("focused")); + dateField.addBlurListener(e -> log("blurred")); + addComponent(dateField); + + TextField textField = new TextField(); + textField.setCaption("second"); + addComponent(textField); + } + + @Override + protected String getTestDescription() { + return "DateField should not trigger events when nagivating between sub-components."; + } + + @Override + protected Integer getTicketNumber() { + return 1008; + } + +} diff --git a/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldFocusTest.java b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldFocusTest.java new file mode 100644 index 0000000000..423ff2e71c --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldFocusTest.java @@ -0,0 +1,34 @@ +package com.vaadin.tests.components.datefield; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.vaadin.testbench.elements.DateFieldElement; +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class DateFieldFocusTest extends MultiBrowserTest { + + @Test + public void focus() { + openTestURL(); + + assertEquals(" ", getLogRow(0)); + DateFieldElement dateField = $(DateFieldElement.class).first(); + TextFieldElement textField = $(TextFieldElement.class).caption("second") + .first(); + + dateField.openPopup(); + dateField.openPopup(); + + dateField.openPopup(); + dateField.openPopup(); + + assertEquals("1. focused", getLogRow(0)); + + textField.focus(); + + waitUntil(input -> "2. blurred".equals(getLogRow(0))); + } +} |