diff options
author | John Ahlroos <john@vaadin.com> | 2012-11-01 09:57:21 +0200 |
---|---|---|
committer | John Ahlroos <john@vaadin.com> | 2012-11-01 09:57:21 +0200 |
commit | 4028718760ec3a6e2a73f56cfa72de08efc1250c (patch) | |
tree | ca8defed22115b410263d4447f90494748134951 | |
parent | 8cf6a76827818f7fa32a3d0981f45d10cc0db2db (diff) | |
download | vaadin-framework-4028718760ec3a6e2a73f56cfa72de08efc1250c.tar.gz vaadin-framework-4028718760ec3a6e2a73f56cfa72de08efc1250c.zip |
Fixed Combobox popup positioning problem when located inside a PopupView #9768
Change-Id: I5c256483fcb5050b08eb7c481676385789e96f09
3 files changed, 147 insertions, 40 deletions
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<FilterSelectSuggestion> 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<FilterSelectSuggestion> 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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="http://localhost:8888/" /> +<title>New Test</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">New Test</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.combobox.ComboboxInPopupViewWithItems?restartApplication</td> + <td></td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentscomboboxComboboxInPopupViewWithItems::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VPopupView[0]</td> + <td>26,6</td> +</tr> +<tr> + <td>mouseClick</td> + <td>//input[@type='text']</td> + <td>52,13</td> +</tr> +<tr> + <td>pressSpecialKey</td> + <td>//input[@type='text']</td> + <td>down</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>popup-open</td> +</tr> + +</tbody></table> +</body> +</html> 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; + } + } +} |