From: John Ahlroos Date: Thu, 1 Nov 2012 07:57:21 +0000 (+0200) Subject: Fixed Combobox popup positioning problem when located inside a PopupView #9768 X-Git-Tag: 7.0.0.beta8~19^2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=refs%2Fchanges%2F91%2F191%2F1;p=vaadin-framework.git Fixed Combobox popup positioning problem when located inside a PopupView #9768 Change-Id: I5c256483fcb5050b08eb7c481676385789e96f09 --- diff --git a/client/src/com/vaadin/client/ui/combobox/VFilterSelect.java b/client/src/com/vaadin/client/ui/combobox/VFilterSelect.java index 4241daca6f..31b240ad80 100644 --- a/client/src/com/vaadin/client/ui/combobox/VFilterSelect.java +++ b/client/src/com/vaadin/client/ui/combobox/VFilterSelect.java @@ -24,6 +24,7 @@ import java.util.Iterator; import java.util.List; import java.util.Set; +import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Style.Display; @@ -234,49 +235,68 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * The total amount of suggestions */ public void showSuggestions( - Collection currentSuggestions, - int currentPage, int totalSuggestions) { - - // Add TT anchor point - getElement().setId("VAADIN_COMBOBOX_OPTIONLIST"); - - menu.setSuggestions(currentSuggestions); - final int x = VFilterSelect.this.getAbsoluteLeft(); - topPosition = tb.getAbsoluteTop(); - topPosition += tb.getOffsetHeight(); - setPopupPosition(x, topPosition); - - int nullOffset = (nullSelectionAllowed && "".equals(lastFilter) ? 1 - : 0); - boolean firstPage = (currentPage == 0); - final int first = currentPage * pageLength + 1 - - (firstPage ? 0 : nullOffset); - final int last = first + currentSuggestions.size() - 1 - - (firstPage && "".equals(lastFilter) ? nullOffset : 0); - final int matches = totalSuggestions - nullOffset; - if (last > 0) { - // nullsel not counted, as requested by user - status.setInnerText((matches == 0 ? 0 : first) + "-" + last - + "/" + matches); - } else { - status.setInnerText(""); - } - // We don't need to show arrows or statusbar if there is only one - // page - if (totalSuggestions <= pageLength || pageLength == 0) { - setPagingEnabled(false); - } else { - setPagingEnabled(true); - } - setPrevButtonActive(first > 1); - setNextButtonActive(last < matches); + final Collection currentSuggestions, + final int currentPage, final int totalSuggestions) { - // clear previously fixed width - menu.setWidth(""); - menu.getElement().getFirstChildElement().getStyle().clearWidth(); + /* + * We need to defer the opening of the popup so that the parent DOM + * has stabilized so we can calculate an absolute top and left + * correctly. This issue manifests when a Combobox is placed in + * another popupView which also needs to calculate the absoluteTop() + * to position itself. #9768 + */ + final SuggestionPopup popup = this; + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + @Override + public void execute() { + // Add TT anchor point + getElement().setId("VAADIN_COMBOBOX_OPTIONLIST"); + + menu.setSuggestions(currentSuggestions); + final int x = VFilterSelect.this.getAbsoluteLeft(); + + topPosition = tb.getAbsoluteTop(); + topPosition += tb.getOffsetHeight(); + + setPopupPosition(x, topPosition); + + int nullOffset = (nullSelectionAllowed + && "".equals(lastFilter) ? 1 : 0); + boolean firstPage = (currentPage == 0); + final int first = currentPage * pageLength + 1 + - (firstPage ? 0 : nullOffset); + final int last = first + + currentSuggestions.size() + - 1 + - (firstPage && "".equals(lastFilter) ? nullOffset + : 0); + final int matches = totalSuggestions - nullOffset; + if (last > 0) { + // nullsel not counted, as requested by user + status.setInnerText((matches == 0 ? 0 : first) + "-" + + last + "/" + matches); + } else { + status.setInnerText(""); + } + // We don't need to show arrows or statusbar if there is + // only one + // page + if (totalSuggestions <= pageLength || pageLength == 0) { + setPagingEnabled(false); + } else { + setPagingEnabled(true); + } + setPrevButtonActive(first > 1); + setNextButtonActive(last < matches); - setPopupPositionAndShow(this); + // clear previously fixed width + menu.setWidth(""); + menu.getElement().getFirstChildElement().getStyle() + .clearWidth(); + setPopupPositionAndShow(popup); + } + }); } /** diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboboxInPopupViewWithItems.html b/uitest/src/com/vaadin/tests/components/combobox/ComboboxInPopupViewWithItems.html new file mode 100644 index 0000000000..1b7b42a4e3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboboxInPopupViewWithItems.html @@ -0,0 +1,42 @@ + + + + + + +New Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
New Test
open/run/com.vaadin.tests.components.combobox.ComboboxInPopupViewWithItems?restartApplication
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboboxInPopupViewWithItems::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VPopupView[0]26,6
mouseClick//input[@type='text']52,13
pressSpecialKey//input[@type='text']down
screenCapturepopup-open
+ + diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboboxInPopupViewWithItems.java b/uitest/src/com/vaadin/tests/components/combobox/ComboboxInPopupViewWithItems.java new file mode 100644 index 0000000000..3aaae7e6dc --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboboxInPopupViewWithItems.java @@ -0,0 +1,45 @@ +package com.vaadin.tests.components.combobox; + +import java.util.Arrays; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Component; +import com.vaadin.ui.PopupView; +import com.vaadin.ui.TextArea; + +public class ComboboxInPopupViewWithItems extends TestBase { + + @Override + protected void setup() { + addComponent(new TextArea("Some component")); + addComponent(new PopupView(new PopupContent())); + + } + + @Override + protected String getDescription() { + return "Combobox popup should be in the correct place even when it is located inside a PopupView"; + } + + @Override + protected Integer getTicketNumber() { + return 9768; + } + + class PopupContent implements PopupView.Content { + + private final ComboBox cb = new ComboBox(null, Arrays.asList("Item 1", + "Item 2", "Item 3")); + + @Override + public String getMinimizedValueAsHTML() { + return "click here"; + } + + @Override + public Component getPopupComponent() { + return cb; + } + } +}