diff options
author | Henri Sara <henri.sara@gmail.com> | 2017-08-25 13:49:00 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-25 13:49:00 +0300 |
commit | c67f157e4581610a1efd4208c6f7356cc28f51f6 (patch) | |
tree | 8e9b7576f88121a4c5f7682fbe50de9b13e73973 /client | |
parent | 74e8bd248d54a093314a2858eef65ca81248dacd (diff) | |
download | vaadin-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.java | 69 |
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) { |