From 457e802e2fe59ec35089a55acdc7b0321a2d4a5a Mon Sep 17 00:00:00 2001 From: Anna Miroshnik Date: Fri, 24 Oct 2014 20:07:36 +0400 Subject: DateField popup doesn't close when click on popup button (#14857) Fix and tests. Change-Id: I99d92c32727323fae543a24dfb90e849c3338a8c --- .../src/com/vaadin/client/ui/VPopupCalendar.java | 79 +++++++++++++++++++--- 1 file changed, 68 insertions(+), 11 deletions(-) (limited to 'client') diff --git a/client/src/com/vaadin/client/ui/VPopupCalendar.java b/client/src/com/vaadin/client/ui/VPopupCalendar.java index 51b2ee22ec..fbd66cff09 100644 --- a/client/src/com/vaadin/client/ui/VPopupCalendar.java +++ b/client/src/com/vaadin/client/ui/VPopupCalendar.java @@ -27,6 +27,10 @@ import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.DomEvent; import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.event.dom.client.MouseOutEvent; +import com.google.gwt.event.dom.client.MouseOutHandler; +import com.google.gwt.event.dom.client.MouseOverEvent; +import com.google.gwt.event.dom.client.MouseOverHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.i18n.client.DateTimeFormat; @@ -60,7 +64,8 @@ import com.vaadin.shared.ui.datefield.Resolution; * */ public class VPopupCalendar extends VTextualDate implements Field, - ClickHandler, CloseHandler, SubPartAware { + ClickHandler, MouseOverHandler, MouseOutHandler, + CloseHandler, SubPartAware { /** For internal use only. May be removed or replaced in the future. */ public final Button calendarToggle = new Button(); @@ -75,6 +80,20 @@ public class VPopupCalendar extends VTextualDate implements Field, public boolean parsable = true; private boolean open = false; + /* + * To resolve #14857. If to click on calendarToggle button when calendar + * popup is opened (*1) then we have the following chain of calls: + * + * 1) onClose() 2) onClick() + * + * In this case we should prevent calling openCalendarPanel() in onClick. + */ + private boolean preventOpenPopupCalendar = false; + /* + * To resolve #14857. To determine this situation (*1) we use onMouseOver + * and OnMouseOut (for calendarToggle button). + */ + private boolean cursorOverCalendarToggleButton = false; private boolean textFieldEnabled = true; @@ -89,6 +108,10 @@ public class VPopupCalendar extends VTextualDate implements Field, calendarToggle.setText(""); calendarToggle.addClickHandler(this); + + calendarToggle.addMouseOverHandler(this); + calendarToggle.addMouseOutHandler(this); + // -2 instead of -1 to avoid FocusWidget.onAttach to reset it calendarToggle.getElement().setTabIndex(-2); @@ -441,7 +464,10 @@ public class VPopupCalendar extends VTextualDate implements Field, @Override public void onClick(ClickEvent event) { if (event.getSource() == calendarToggle && isEnabled()) { - openCalendarPanel(); + if (!preventOpenPopupCalendar) { + openCalendarPanel(); + } + preventOpenPopupCalendar = false; } } @@ -464,15 +490,22 @@ public class VPopupCalendar extends VTextualDate implements Field, focus(); } - // TODO resolve what the "Sigh." is all about and document it here - // Sigh. - Timer t = new Timer() { - @Override - public void run() { - open = false; - } - }; - t.schedule(100); + open = false; + + if (cursorOverCalendarToggleButton) { + preventOpenPopupCalendar = true; + + // To resolve the problem: onMouseOut event not triggered when + // moving mouse fast (GWT - all browsers) + Timer unPreventClickTimer = new Timer() { + @Override + public void run() { + preventOpenPopupCalendar = false; + } + }; + + unPreventClickTimer.schedule(300); + } } } @@ -642,4 +675,28 @@ public class VPopupCalendar extends VTextualDate implements Field, calendar.setRangeEnd(rangeEnd); } + /* + * (non-Javadoc) + * + * @see + * com.google.gwt.event.dom.client.MouseOverHandler#onMouseOver(com.google + * .gwt.event.dom.client.MouseOverEvent) + */ + @Override + public void onMouseOver(MouseOverEvent event) { + cursorOverCalendarToggleButton = true; + } + + /* + * (non-Javadoc) + * + * @see + * com.google.gwt.event.dom.client.MouseOutHandler#onMouseOut(com.google + * .gwt.event.dom.client.MouseOutEvent) + */ + @Override + public void onMouseOut(MouseOutEvent event) { + cursorOverCalendarToggleButton = false; + } + } -- cgit v1.2.3