Browse Source

Fixed Combobox popup positioning problem when located inside a PopupView #9768

Change-Id: I5c256483fcb5050b08eb7c481676385789e96f09
tags/7.0.0.beta8
John Ahlroos 11 years ago
parent
commit
4028718760

+ 60
- 40
client/src/com/vaadin/client/ui/combobox/VFilterSelect.java View File

@@ -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);
}
});
}

/**

+ 42
- 0
uitest/src/com/vaadin/tests/components/combobox/ComboboxInPopupViewWithItems.html View File

@@ -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>

+ 45
- 0
uitest/src/com/vaadin/tests/components/combobox/ComboboxInPopupViewWithItems.java View File

@@ -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;
}
}
}

Loading…
Cancel
Save