* Further tweaks to ComboBox popup positioning. - Updated a comment and renamed a private method for better clarity. - Blocked unnecessary position updates. - Added a test for #11866 / #11894.tags/8.11.0.alpha1
@@ -902,11 +902,16 @@ public class VComboBox extends Composite implements Field, KeyDownHandler, | |||
int comboBoxLeft = VComboBox.this.getAbsoluteLeft(); | |||
int comboBoxWidth = VComboBox.this.getOffsetWidth(); | |||
if (hasParentWithUnadjustedPositioning()) { | |||
// ComboBox itself may be incorrectly positioned, don't adjust | |||
// popup position yet. Width calculations must be performed | |||
// anyway to avoid flickering. | |||
setPopupPosition(left, top); | |||
if (hasParentWithUnadjustedHorizontalPositioning()) { | |||
// ComboBox itself may be incorrectly positioned, don't try to | |||
// adjust horizontal popup position yet. Earlier width | |||
// calculations must be performed anyway to avoid flickering. | |||
if (top != topPosition) { | |||
// Variable 'left' still contains the original popupLeft, | |||
// 'top' has been updated, thus vertical position needs | |||
// adjusting. | |||
setPopupPosition(left, top); | |||
} | |||
return; | |||
} | |||
if (left > comboBoxLeft | |||
@@ -929,7 +934,10 @@ public class VComboBox extends Composite implements Field, KeyDownHandler, | |||
menu.setWidth(Window.getClientWidth() + "px"); | |||
} | |||
setPopupPosition(left, top); | |||
// Only update the position if it has changed. | |||
if (top != topPosition || left != getPopupLeft()) { | |||
setPopupPosition(left, top); | |||
} | |||
menu.scrollSelectionIntoView(); | |||
} | |||
@@ -941,7 +949,7 @@ public class VComboBox extends Composite implements Field, KeyDownHandler, | |||
* @return {@code true} if unadjusted parents found, {@code false} | |||
* otherwise | |||
*/ | |||
private boolean hasParentWithUnadjustedPositioning() { | |||
private boolean hasParentWithUnadjustedHorizontalPositioning() { | |||
/* | |||
* If there are any VHorizontalLayouts among this VComboBox's | |||
* parents, any spacing or expand ratio may cause incorrect |
@@ -0,0 +1,38 @@ | |||
package com.vaadin.tests.components.combobox; | |||
import java.util.Arrays; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.ui.Alignment; | |||
import com.vaadin.ui.ComboBox; | |||
import com.vaadin.ui.HorizontalLayout; | |||
public class ComboBoxAtBottomEdgeWithinHorizontalLayout extends AbstractTestUI { | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
ComboBox<Integer> comboBox = new ComboBox<>(); | |||
comboBox.setItems(Arrays.asList(100, 200, 300, 400, 500)); | |||
HorizontalLayout horizontalLayout = new HorizontalLayout(); | |||
horizontalLayout.addComponent(comboBox); | |||
getLayout().addComponent(horizontalLayout); | |||
getLayout().setComponentAlignment(horizontalLayout, | |||
Alignment.BOTTOM_RIGHT); | |||
getLayout().setSizeFull(); | |||
getLayout().getParent().setSizeFull(); | |||
} | |||
@Override | |||
protected Integer getTicketNumber() { | |||
return 11866; | |||
} | |||
@Override | |||
protected String getTestDescription() { | |||
return "ComboBox at bottom edge should open popup above " | |||
+ "even when within HorizontalLayout."; | |||
} | |||
} |
@@ -0,0 +1,29 @@ | |||
package com.vaadin.tests.components.combobox; | |||
import org.junit.Test; | |||
import org.openqa.selenium.WebElement; | |||
import com.vaadin.testbench.elements.ComboBoxElement; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
public class ComboBoxAtBottomEdgeWithinHorizontalLayoutTest | |||
extends MultiBrowserTest { | |||
@Test | |||
public void ensurePopupInView() { | |||
openTestURL(); | |||
ComboBoxElement cb = $(ComboBoxElement.class).first(); | |||
cb.openPopup(); | |||
WebElement popup = cb.getSuggestionPopup(); | |||
int cbBottom = cb.getLocation().getY() + cb.getSize().getHeight(); | |||
int popupBottom = popup.getLocation().getY() | |||
+ popup.getSize().getHeight(); | |||
assertGreaterOrEqual(String.format( | |||
"Popup should not open below the ComboBox at the " | |||
+ "bottom edge of the viewport. ComboBox: %s, Popup: %s", | |||
cbBottom, popupBottom), cbBottom, popupBottom); | |||
} | |||
} |