aboutsummaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorHenri Sara <henri.sara@gmail.com>2017-08-25 13:49:00 +0300
committerGitHub <noreply@github.com>2017-08-25 13:49:00 +0300
commitc67f157e4581610a1efd4208c6f7356cc28f51f6 (patch)
tree8e9b7576f88121a4c5f7682fbe50de9b13e73973 /client
parent74e8bd248d54a093314a2858eef65ca81248dacd (diff)
downloadvaadin-framework-c67f157e4581610a1efd4208c6f7356cc28f51f6.tar.gz
vaadin-framework-c67f157e4581610a1efd4208c6f7356cc28f51f6.zip
Move ComboBox popup with ComboBox on scroll (#9869)
Keep the ComboBox popup at the same position relative to the ComboBox when the view is scrolled. Fixes #5043
Diffstat (limited to 'client')
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VComboBox.java69
1 files changed, 59 insertions, 10 deletions
diff --git a/client/src/main/java/com/vaadin/client/ui/VComboBox.java b/client/src/main/java/com/vaadin/client/ui/VComboBox.java
index bb75385007..784f2b116d 100644
--- a/client/src/main/java/com/vaadin/client/ui/VComboBox.java
+++ b/client/src/main/java/com/vaadin/client/ui/VComboBox.java
@@ -24,6 +24,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import com.google.gwt.animation.client.AnimationScheduler;
import com.google.gwt.aria.client.Roles;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
@@ -55,6 +56,7 @@ import com.google.gwt.i18n.client.HasDirection.Direction;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
@@ -342,9 +344,12 @@ public class VComboBox extends Composite implements Field, KeyDownHandler,
private int popupOuterPadding = -1;
private int topPosition;
+ private int leftPosition;
private final MouseWheeler mouseWheeler = new MouseWheeler();
+ private boolean scrollPending = false;
+
/**
* Default constructor
*/
@@ -410,15 +415,10 @@ public class VComboBox extends Composite implements Field, KeyDownHandler,
// Add TT anchor point
getElement().setId("VAADIN_COMBOBOX_OPTIONLIST");
- final int x = toInt32(WidgetUtil
- .getBoundingClientRect(VComboBox.this.getElement())
- .getLeft());
-
- topPosition = toInt32(WidgetUtil
- .getBoundingClientRect(tb.getElement()).getBottom())
- + Window.getScrollTop();
+ leftPosition = getDesiredLeftPosition();
+ topPosition = getDesiredTopPosition();
- setPopupPosition(x, topPosition);
+ setPopupPosition(leftPosition, topPosition);
int nullOffset = getNullSelectionItemShouldBeVisible() ? 1 : 0;
boolean firstPage = currentPage == 0;
@@ -452,6 +452,17 @@ public class VComboBox extends Composite implements Field, KeyDownHandler,
setPopupPositionAndShow(popup);
}
+ private int getDesiredTopPosition() {
+ return toInt32(WidgetUtil.getBoundingClientRect(tb.getElement())
+ .getBottom()) + Window.getScrollTop();
+ }
+
+ private int getDesiredLeftPosition() {
+ return toInt32(WidgetUtil
+ .getBoundingClientRect(VComboBox.this.getElement())
+ .getLeft());
+ }
+
private native int toInt32(double val)
/*-{
return val | 0;
@@ -660,6 +671,44 @@ public class VComboBox extends Composite implements Field, KeyDownHandler,
handleMouseDownEvent(event);
}
+ @Override
+ protected void onPreviewNativeEvent(NativePreviewEvent event) {
+ // Check all events outside the combobox to see if they scroll the
+ // page. We cannot use e.g. Window.addScrollListener() because the
+ // scrolled element can be at any level on the page.
+
+ // Normally this is only called when the popup is showing, but make
+ // sure we don't accidentally process all events when not showing.
+ if (!scrollPending && isShowing() && !DOM.isOrHasChild(
+ SuggestionPopup.this.getElement(),
+ Element.as(event.getNativeEvent().getEventTarget()))) {
+ if (getDesiredLeftPosition() != leftPosition
+ || getDesiredTopPosition() != topPosition) {
+ updatePopupPositionOnScroll();
+ }
+ }
+
+ super.onPreviewNativeEvent(event);
+ }
+
+ /**
+ * Make the popup follow the position of the ComboBox when the page is
+ * scrolled.
+ */
+ private void updatePopupPositionOnScroll() {
+ if (!scrollPending) {
+ AnimationScheduler.get().requestAnimationFrame(timestamp -> {
+ if (isShowing()) {
+ leftPosition = getDesiredLeftPosition();
+ topPosition = getDesiredTopPosition();
+ setPopupPosition(leftPosition, topPosition);
+ }
+ scrollPending = false;
+ });
+ scrollPending = true;
+ }
+ }
+
/**
* Should paging be enabled. If paging is enabled then only a certain
* amount of items are visible at a time and a scrollbar or buttons are
@@ -2830,7 +2879,7 @@ public class VComboBox extends Composite implements Field, KeyDownHandler,
/**
* Gets the empty selection caption.
- *
+ *
* @since 8.0.7
* @return the empty selection caption
*/
@@ -2844,7 +2893,7 @@ public class VComboBox extends Composite implements Field, KeyDownHandler,
*
* @param emptySelectionCaption
* the empty selection caption
- *
+ *
* @since 8.0.7
*/
public void setEmptySelectionCaption(String emptySelectionCaption) {