summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonni Nakari <jonni@vaadin.com>2016-03-30 23:22:14 +0300
committerVaadin Code Review <review@vaadin.com>2016-05-31 13:02:42 +0000
commit68784363dca98529286420206b22a9a8881c70dc (patch)
tree4d00913073808eee1e1a935b3e4395c9d8ab7d1b
parent72c067a2d1913642b4cda591c2f76ad87d7279cb (diff)
downloadvaadin-framework-68784363dca98529286420206b22a9a8881c70dc.tar.gz
vaadin-framework-68784363dca98529286420206b22a9a8881c70dc.zip
Suggestion pop-up width API for ComboBox (#19685)
Added API setPopupWidth(String) to ComboBox. The suggestion pop-up now has three different width modes: 1. Legacy "null"-mode: width is determined by the longest item caption for each page. This looks & feels like the old implementation. This is the default mode 2. Relative to the ComboBox. e.g. 100% 3. fixed width using any CSS definition Change-Id: Id60a6996ee82726196b84d50c2d0d18a6cfb5ebf
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VFilterSelect.java174
-rw-r--r--client/src/main/java/com/vaadin/client/ui/combobox/ComboBoxConnector.java38
-rw-r--r--server/src/main/java/com/vaadin/ui/ComboBox.java33
-rw-r--r--themes/src/main/themes/VAADIN/themes/base/select/select.scss24
-rw-r--r--themes/src/main/themes/VAADIN/themes/chameleon/common/common.scss5
-rw-r--r--themes/src/main/themes/VAADIN/themes/liferay/select/select.scss16
-rw-r--r--themes/src/main/themes/VAADIN/themes/reindeer/select/select.scss2
-rw-r--r--themes/src/main/themes/VAADIN/themes/runo/select/select.scss2
-rw-r--r--themes/src/main/themes/VAADIN/themes/valo/components/_combobox.scss24
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidth.java47
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthLegacy.java47
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPercentage.java46
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPixels.java46
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthLegacyTest.java52
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPercentageTest.java52
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPixelsTest.java51
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthTest.java52
17 files changed, 658 insertions, 53 deletions
diff --git a/client/src/main/java/com/vaadin/client/ui/VFilterSelect.java b/client/src/main/java/com/vaadin/client/ui/VFilterSelect.java
index 9fb6d18ac5..a2a7f9a9ee 100644
--- a/client/src/main/java/com/vaadin/client/ui/VFilterSelect.java
+++ b/client/src/main/java/com/vaadin/client/ui/VFilterSelect.java
@@ -31,9 +31,11 @@ import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -658,7 +660,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
debug("VFS.SP: setPosition(" + offsetWidth + ", " + offsetHeight
+ ")");
- int top;
+ int top = topPosition;
int left = getPopupLeft();
// reset menu size and retrieve its "natural" size
@@ -675,27 +677,55 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
+ "]");
Element menuFirstChild = menu.getElement().getFirstChildElement();
- final int naturalMenuWidth = WidgetUtil
- .getRequiredWidth(menuFirstChild);
+ int naturalMenuWidth;
+ if (BrowserInfo.get().isIE()
+ && BrowserInfo.get().getBrowserMajorVersion() < 10) {
+ // On IE 8 & 9 visibility is set to hidden and measuring
+ // elements while they are hidden yields incorrect results
+ String before = menu.getElement().getParentElement().getStyle()
+ .getVisibility();
+ menu.getElement().getParentElement().getStyle()
+ .setVisibility(Visibility.VISIBLE);
+ naturalMenuWidth = WidgetUtil.getRequiredWidth(menuFirstChild);
+ menu.getElement().getParentElement().getStyle()
+ .setProperty("visibility", before);
+ } else {
+ naturalMenuWidth = WidgetUtil.getRequiredWidth(menuFirstChild);
+ }
if (popupOuterPadding == -1) {
popupOuterPadding = WidgetUtil
- .measureHorizontalPaddingAndBorder(getElement(), 2);
+ .measureHorizontalPaddingAndBorder(menu.getElement(), 2)
+ + WidgetUtil.measureHorizontalPaddingAndBorder(
+ suggestionPopup.getElement(), 0);
}
- if (naturalMenuWidth < desiredWidth) {
- menu.setWidth((desiredWidth - popupOuterPadding) + "px");
- menuFirstChild.getStyle().setWidth(100, Unit.PCT);
- }
+ updateMenuWidth(desiredWidth, naturalMenuWidth);
if (BrowserInfo.get().isIE()
&& BrowserInfo.get().getBrowserMajorVersion() < 11) {
// Must take margin,border,padding manually into account for
// menu element as we measure the element child and set width to
// the element parent
- double naturalMenuOuterWidth = WidgetUtil
- .getRequiredWidthDouble(menuFirstChild)
- + getMarginBorderPaddingWidth(menu.getElement());
+
+ double naturalMenuOuterWidth;
+ if (BrowserInfo.get().getBrowserMajorVersion() < 10) {
+ // On IE 8 & 9 visibility is set to hidden and measuring
+ // elements while they are hidden yields incorrect results
+ String before = menu.getElement().getParentElement()
+ .getStyle().getVisibility();
+ menu.getElement().getParentElement().getStyle()
+ .setVisibility(Visibility.VISIBLE);
+ naturalMenuOuterWidth = WidgetUtil
+ .getRequiredWidthDouble(menuFirstChild)
+ + getMarginBorderPaddingWidth(menu.getElement());
+ menu.getElement().getParentElement().getStyle()
+ .setProperty("visibility", before);
+ } else {
+ naturalMenuOuterWidth = WidgetUtil
+ .getRequiredWidthDouble(menuFirstChild)
+ + getMarginBorderPaddingWidth(menu.getElement());
+ }
/*
* IE requires us to specify the width for the container
@@ -756,10 +786,12 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
menu.setHeight(menuHeight + "px");
- final int naturalMenuWidthPlusScrollBar = naturalMenuWidth
- + WidgetUtil.getNativeScrollbarSize();
- if (offsetWidth < naturalMenuWidthPlusScrollBar) {
- menu.setWidth(naturalMenuWidthPlusScrollBar + "px");
+ if (suggestionPopupWidth == null) {
+ final int naturalMenuWidthPlusScrollBar = naturalMenuWidth
+ + WidgetUtil.getNativeScrollbarSize();
+ if (offsetWidth < naturalMenuWidthPlusScrollBar) {
+ menu.setWidth(naturalMenuWidthPlusScrollBar + "px");
+ }
}
}
@@ -769,6 +801,11 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
if (left < 0) {
left = 0;
menu.setWidth(Window.getClientWidth() + "px");
+
+ }
+ if (BrowserInfo.get().isIE()
+ && BrowserInfo.get().getBrowserMajorVersion() < 10) {
+ setTdWidth(menu.getElement(), Window.getClientWidth() - 8);
}
}
@@ -777,6 +814,104 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
}
/**
+ * Adds in-line CSS rules to the DOM according to the
+ * suggestionPopupWidth field
+ *
+ * @param desiredWidth
+ * @param naturalMenuWidth
+ */
+ private void updateMenuWidth(final int desiredWidth,
+ final int naturalMenuWidth) {
+ /**
+ * Three different width modes for the suggestion pop-up:
+ *
+ * 1. Legacy "null"-mode: width is determined by the longest item
+ * caption for each page while still maintaining minimum width of
+ * (desiredWidth - popupOuterPadding)
+ *
+ * 2. relative to the component itself
+ *
+ * 3. fixed width
+ */
+ String width = "auto";
+ if (suggestionPopupWidth == null) {
+ if (naturalMenuWidth < desiredWidth) {
+ width = (desiredWidth - popupOuterPadding) + "px";
+ }
+ } else if (isrelativeUnits(suggestionPopupWidth)) {
+ float mainComponentWidth = desiredWidth - popupOuterPadding;
+ // convert percentage value to fraction
+ int widthInPx = Math.round(mainComponentWidth
+ * asFraction(suggestionPopupWidth));
+ width = widthInPx + "px";
+ } else {
+ // use as fixed width CSS definition
+ width = WidgetUtil.escapeAttribute(suggestionPopupWidth);
+ }
+ menu.setWidth(width);
+
+ // IE8 or 9?
+ if (BrowserInfo.get().isIE()
+ && BrowserInfo.get().getBrowserMajorVersion() < 10) {
+ // using legacy mode?
+ if (suggestionPopupWidth == null) {
+ // set the TD widths manually as these browsers do not
+ // respect display: block; width:100% rules
+ setTdWidth(menu.getElement(), naturalMenuWidth);
+ } else {
+ int compensation = WidgetUtil
+ .measureHorizontalPaddingAndBorder(
+ menu.getElement(), 4);
+ setTdWidth(menu.getElement(), menu.getOffsetWidth()
+ - compensation);
+ }
+
+ }
+ }
+
+ /**
+ * Descends to child elements until finds TD elements and sets their
+ * width in pixels. Can be used to workaround IE8 & 9 TD element
+ * display: block issues
+ *
+ * @param parent
+ * @param width
+ */
+ private void setTdWidth(Node parent, int width) {
+ for (int i = 0; i < parent.getChildCount(); i++) {
+ Node child = parent.getChild(i);
+ if ("td".equals(child.getNodeName().toLowerCase())) {
+ ((Element) child).getStyle().setWidth(width, Unit.PX);
+ } else {
+ setTdWidth(child, width);
+ }
+
+ }
+ }
+
+ /**
+ * Returns the percentage value as a fraction, e.g. 42% -> 0.42
+ *
+ * @param percentage
+ */
+ private float asFraction(String percentage) {
+ String trimmed = percentage.trim();
+ String withoutPercentSign = trimmed.substring(0,
+ trimmed.length() - 1);
+ float asFraction = Float.parseFloat(withoutPercentSign) / 100;
+ return asFraction;
+ }
+
+ /**
+ * @since
+ * @param suggestionPopupWidth
+ * @return
+ */
+ private boolean isrelativeUnits(String suggestionPopupWidth) {
+ return suggestionPopupWidth.trim().endsWith("%");
+ }
+
+ /**
* Was the popup just closed?
*
* @return true if popup was just closed
@@ -932,6 +1067,13 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
isFirstIteration = false;
}
+ if (suggestionPopupWidth != null && BrowserInfo.get().isIE()
+ && BrowserInfo.get().getBrowserMajorVersion() < 10) {
+ // set TD width to a low value so that they won't mandate the
+ // suggestion pop-up width
+ suggestionPopup
+ .setTdWidth(suggestionPopup.menu.getElement(), 1);
+ }
}
/**
@@ -1355,6 +1497,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
/** For internal use only. May be removed or replaced in the future. */
public int suggestionPopupMinWidth = 0;
+ public String suggestionPopupWidth = null;
+
private int popupWidth = -1;
/**
* Stores the last new item string to avoid double submissions. Cleared on
diff --git a/client/src/main/java/com/vaadin/client/ui/combobox/ComboBoxConnector.java b/client/src/main/java/com/vaadin/client/ui/combobox/ComboBoxConnector.java
index 1224a2eaf2..c498f88dde 100644
--- a/client/src/main/java/com/vaadin/client/ui/combobox/ComboBoxConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/combobox/ComboBoxConnector.java
@@ -35,8 +35,8 @@ import com.vaadin.shared.ui.combobox.FilteringMode;
import com.vaadin.ui.ComboBox;
@Connect(ComboBox.class)
-public class ComboBoxConnector extends AbstractFieldConnector implements
- Paintable, SimpleManagedLayout {
+public class ComboBoxConnector extends AbstractFieldConnector
+ implements Paintable, SimpleManagedLayout {
// oldSuggestionTextMatchTheOldSelection is used to detect when it's safe to
// update textbox text by a changed item caption.
@@ -65,15 +65,16 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
// work without additional UIDL messages
boolean noTextInput = uidl
.hasAttribute(ComboBoxConstants.ATTR_NO_TEXT_INPUT)
- && uidl.getBooleanAttribute(ComboBoxConstants.ATTR_NO_TEXT_INPUT);
+ && uidl.getBooleanAttribute(
+ ComboBoxConstants.ATTR_NO_TEXT_INPUT);
getWidget().setTextInputEnabled(!noTextInput);
// not a FocusWidget -> needs own tabindex handling
getWidget().tb.setTabIndex(getState().tabIndex);
if (uidl.hasAttribute("filteringmode")) {
- getWidget().filteringmode = FilteringMode.valueOf(uidl
- .getStringAttribute("filteringmode"));
+ getWidget().filteringmode = FilteringMode
+ .valueOf(uidl.getStringAttribute("filteringmode"));
}
getWidget().immediate = getState().immediate;
@@ -97,6 +98,13 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
getWidget().inputPrompt = "";
}
+ if (uidl.hasAttribute("suggestionPopupWidth")) {
+ getWidget().suggestionPopupWidth = uidl
+ .getStringAttribute("suggestionPopupWidth");
+ } else {
+ getWidget().suggestionPopupWidth = null;
+ }
+
getWidget().suggestionPopup.updateStyleNames(uidl, getState());
getWidget().allowNewItem = uidl.hasAttribute("allownewitem");
@@ -177,8 +185,8 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
&& uidl.hasAttribute("selectedCaption")) {
// scrolling to correct page is disabled, caption is passed as a
// special parameter
- getWidget().tb.setText(uidl
- .getStringAttribute("selectedCaption"));
+ getWidget().tb
+ .setText(uidl.getStringAttribute("selectedCaption"));
} else {
resetSelection();
}
@@ -266,16 +274,16 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
if (!getWidget().waitingForFilteringResponse
|| getWidget().popupOpenerClicked) {
if (!suggestionKey.equals(getWidget().selectedOptionKey)
- || suggestion.getReplacementString().equals(
- getWidget().tb.getText())
+ || suggestion.getReplacementString()
+ .equals(getWidget().tb.getText())
|| oldSuggestionTextMatchTheOldSelection) {
// Update text field if we've got a new
// selection
// Also update if we've got the same text to
// retain old text selection behavior
// OR if selected item caption is changed.
- getWidget().setPromptingOff(
- suggestion.getReplacementString());
+ getWidget()
+ .setPromptingOff(suggestion.getReplacementString());
getWidget().selectedOptionKey = suggestionKey;
}
}
@@ -288,8 +296,8 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
private boolean isWidgetsCurrentSelectionTextInTextBox() {
return getWidget().currentSuggestion != null
- && getWidget().currentSuggestion.getReplacementString().equals(
- getWidget().tb.getText());
+ && getWidget().currentSuggestion.getReplacementString()
+ .equals(getWidget().tb.getText());
}
private void resetSelection() {
@@ -311,8 +319,8 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
// just clear the input if the value has changed from something
// else to null
if (getWidget().selectedOptionKey != null
- || (getWidget().allowNewItem && !getWidget().tb
- .getValue().isEmpty())) {
+ || (getWidget().allowNewItem
+ && !getWidget().tb.getValue().isEmpty())) {
getWidget().tb.setValue("");
}
}
diff --git a/server/src/main/java/com/vaadin/ui/ComboBox.java b/server/src/main/java/com/vaadin/ui/ComboBox.java
index b632cb0d8d..562173a9bf 100644
--- a/server/src/main/java/com/vaadin/ui/ComboBox.java
+++ b/server/src/main/java/com/vaadin/ui/ComboBox.java
@@ -121,6 +121,8 @@ public class ComboBox extends AbstractSelect implements
*/
private boolean scrollToSelectedItem = true;
+ private String suggestionPopupWidth = null;
+
/**
* If text input is not allowed, the ComboBox behaves like a pretty
* NativeSelect - the user can not enter any text and clicking the text
@@ -170,7 +172,7 @@ public class ComboBox extends AbstractSelect implements
/**
* Sets the input prompt - a textual prompt that is displayed when the
* select would otherwise be empty, to prompt the user for input.
- *
+ *
* @param inputPrompt
* the desired input prompt, or null to disable
*/
@@ -230,6 +232,11 @@ public class ComboBox extends AbstractSelect implements
target.addAttribute("pagelength", pageLength);
+ if (suggestionPopupWidth != null) {
+ target.addAttribute("suggestionPopupWidth",
+ suggestionPopupWidth);
+ }
+
target.addAttribute("filteringmode", getFilteringMode().toString());
// Paints the options and create array of selected id keys
@@ -875,6 +882,16 @@ public class ComboBox extends AbstractSelect implements
}
/**
+ * Returns the suggestion pop-up's width as a CSS string.
+ *
+ * @see #setPopupWidth
+ * @since 7.7
+ */
+ public String getPopupWidth() {
+ return suggestionPopupWidth;
+ }
+
+ /**
* Sets the page length for the suggestion popup. Setting the page length to
* 0 will disable suggestion popup paging (all items visible).
*
@@ -887,6 +904,20 @@ public class ComboBox extends AbstractSelect implements
}
/**
+ * Sets the suggestion pop-up's width as a CSS string. By using relative
+ * units (e.g. "50%") it's possible to set the popup's width relative to the
+ * ComboBox itself.
+ *
+ * @see #getPopupWidth()
+ * @since 7.7
+ * @param width the width
+ */
+ public void setPopupWidth(String width) {
+ suggestionPopupWidth = width;
+ markAsDirty();
+ }
+
+ /**
* Sets whether to scroll the selected item visible (directly open the page
* on which it is) when opening the combo box popup or not. Only applies to
* single select mode.
diff --git a/themes/src/main/themes/VAADIN/themes/base/select/select.scss b/themes/src/main/themes/VAADIN/themes/base/select/select.scss
index 69d3c07272..fc097405b7 100644
--- a/themes/src/main/themes/VAADIN/themes/base/select/select.scss
+++ b/themes/src/main/themes/VAADIN/themes/base/select/select.scss
@@ -104,9 +104,33 @@ $select-button-negative-width : -1em;
border-collapse: collapse;
border: none;
vertical-align:top;
+ display: block;
+ width: 100%;
+
+ // float & clear needs to be set so that IE 8 & 9 displays the elements as block
+ float: left;
+ clear: both;
+
+ & > tbody,
+ & > tbody > tr,
+ & > tbody > tr > td {
+ display: block;
+ width: 100%;
+ // float & clear needs to be set so that IE 8 & 9 displays the elements as block
+ float: left;
+ clear: both;
+ overflow-y: hidden;
+ }
}
.v-filterselect-suggestmenu .gwt-MenuItem {
white-space: nowrap;
+ padding-left: 1px;
+ padding-right: 0;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ overflow-x: hidden;
+ text-overflow: ellipsis;
}
.v-filterselect-suggestmenu .gwt-MenuItem .v-icon {
margin-right: 3px;
diff --git a/themes/src/main/themes/VAADIN/themes/chameleon/common/common.scss b/themes/src/main/themes/VAADIN/themes/chameleon/common/common.scss
index 82e0810bc2..86b65f70fb 100644
--- a/themes/src/main/themes/VAADIN/themes/chameleon/common/common.scss
+++ b/themes/src/main/themes/VAADIN/themes/chameleon/common/common.scss
@@ -126,7 +126,10 @@ $chameleon-line-height: 1.4;
-moz-user-select: none;
-ms-user-select: none;
cursor: default;
- }
+ }
+ .v-filterselect-suggestpopup .gwt-MenuItem {
+ padding: 0 .7em;
+ }
.v-contextmenu td.gwt-MenuItem-selected div,
.v-filterselect-suggestpopup td.gwt-MenuItem-selected,
diff --git a/themes/src/main/themes/VAADIN/themes/liferay/select/select.scss b/themes/src/main/themes/VAADIN/themes/liferay/select/select.scss
index 5ae302be9a..9d14b02982 100644
--- a/themes/src/main/themes/VAADIN/themes/liferay/select/select.scss
+++ b/themes/src/main/themes/VAADIN/themes/liferay/select/select.scss
@@ -61,18 +61,16 @@ select {
background-position: -65px -4px;
}
.v-filterselect-suggestmenu .gwt-MenuItem span {
- display: block;
- width: 100%;
height: 18px;
- border: 1px solid #fff;
- border-style: solid none;
-
}
-.v-filterselect-suggestmenu .gwt-MenuItem-selected span {
- color: #000;
- background: #dfe8f6;
- border-color: #a3bae9;
+.v-filterselect-suggestmenu .gwt-MenuItem {
+ border: 1px solid transparent;
+ &.gwt-MenuItem-selected {
+ background-color: #dfe8f6;
+ border: 1px solid #333;
+ color: #000;
+ }
}
.v-filterselect-suggestmenu .gwt-MenuItem .v-icon {
diff --git a/themes/src/main/themes/VAADIN/themes/reindeer/select/select.scss b/themes/src/main/themes/VAADIN/themes/reindeer/select/select.scss
index a15ba4ab87..818c33b460 100644
--- a/themes/src/main/themes/VAADIN/themes/reindeer/select/select.scss
+++ b/themes/src/main/themes/VAADIN/themes/reindeer/select/select.scss
@@ -81,7 +81,7 @@ $select-button-negative-width : -25px;
}
.#{$primaryStyleName}-suggestmenu .gwt-MenuItem {
padding: 1px 8px;
- height: 16px;
+ min-height: 18px;
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
diff --git a/themes/src/main/themes/VAADIN/themes/runo/select/select.scss b/themes/src/main/themes/VAADIN/themes/runo/select/select.scss
index 39eb0c9bde..ac8e22b429 100644
--- a/themes/src/main/themes/VAADIN/themes/runo/select/select.scss
+++ b/themes/src/main/themes/VAADIN/themes/runo/select/select.scss
@@ -77,7 +77,7 @@ $select-button-negative-width: -25px;
.#{$primaryStyleName}-suggestmenu .gwt-MenuItem {
padding: 1px 6px;
cursor: pointer;
- height: 18px;
+ min-height: 21px;
}
.#{$primaryStyleName}-suggestmenu .gwt-MenuItem .v-icon {
margin-right: 3px;
diff --git a/themes/src/main/themes/VAADIN/themes/valo/components/_combobox.scss b/themes/src/main/themes/VAADIN/themes/valo/components/_combobox.scss
index d240be56b8..e9056ef17a 100644
--- a/themes/src/main/themes/VAADIN/themes/valo/components/_combobox.scss
+++ b/themes/src/main/themes/VAADIN/themes/valo/components/_combobox.scss
@@ -358,26 +358,30 @@
[class$="suggestmenu"] {
@include valo-selection-overlay-style($animate-in: false, $animate-out: false);
- @include box-sizing(border-box);
+ @include box-sizing(content-box);
position: relative;
z-index: 1;
-
- &[style*="height"] {
- @include box-sizing(content-box);
- }
+ display: block;
}
- margin-top: ceil($v-unit-size/8) !important;
+ margin-top: ceil($v-unit-size/8) !important;
- table,
- tbody,
- tr,
- td {
+ table, tbody, tr, td {
display: block;
+ width: 100%;
+ overflow-y: hidden;
+
+ // float & clear needs to be set so that IE 8 & 9 displays the elements as block
+ float: left;
+ clear: both;
}
.gwt-MenuItem {
@include valo-selection-item-style;
+ height: $v-selection-item-height;
+ box-sizing: border-box;
+ text-overflow: ellipsis;
+ overflow-x: hidden;
}
.gwt-MenuItem-selected {
diff --git a/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidth.java b/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidth.java
new file mode 100644
index 0000000000..86e5b54cb6
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidth.java
@@ -0,0 +1,47 @@
+package com.vaadin.tests.components.combobox;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.ComboBox;
+
+public class ComboBoxSuggestionPopupWidth extends AbstractTestUI {
+
+ private static List<String> items = Arrays
+ .asList("abc",
+ "cde",
+ "efg",
+ "ghi",
+ "ijk",
+ "more items 1",
+ "more items 2",
+ "more items 3",
+ "Ridicilously long item caption so we can see how the ComboBox displays ridicilously long captions in the suggestion pop-up",
+ "more items 4", "more items 5", "more items 6",
+ "more items 7");
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ ComboBox cb = new ComboBox(
+ "200px wide ComboBox with 100% wide suggestion popup",
+ items);
+ cb.setPopupWidth("100%");
+ cb.setWidth("200px");
+ cb.addStyleName("width-as-percentage");
+ addComponent(cb);
+
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Suggestion pop-up's width should be the same width as the ComboBox itself";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 19685;
+ }
+
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthLegacy.java b/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthLegacy.java
new file mode 100644
index 0000000000..091b5f9aab
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthLegacy.java
@@ -0,0 +1,47 @@
+package com.vaadin.tests.components.combobox;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.ComboBox;
+
+public class ComboBoxSuggestionPopupWidthLegacy extends AbstractTestUI {
+
+ private static List<String> items = Arrays
+ .asList("abc",
+ "cde",
+ "efg",
+ "ghi",
+ "ijk",
+ "more items 1",
+ "more items 2",
+ "more items 3",
+ "Ridicilously long item caption so we can see how the ComboBox displays ridicilously long captions in the suggestion pop-up",
+ "more items 4", "more items 5", "more items 6",
+ "more items 7");
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ ComboBox legacy = new ComboBox(
+ "200px wide ComboBox with legacy mode suggestion popup setPopupWidth(null)",
+ items);
+ legacy.addStyleName("legacy");
+ legacy.setWidth("200px");
+ legacy.setPopupWidth(null);
+ addComponent(legacy);
+
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Suggestion pop-up's width should respect the item captions width";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 19685;
+ }
+
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPercentage.java b/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPercentage.java
new file mode 100644
index 0000000000..1ddc666a44
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPercentage.java
@@ -0,0 +1,46 @@
+package com.vaadin.tests.components.combobox;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.ComboBox;
+
+public class ComboBoxSuggestionPopupWidthPercentage extends AbstractTestUI {
+
+ private static List<String> items = Arrays
+ .asList("abc",
+ "cde",
+ "efg",
+ "ghi",
+ "ijk",
+ "more items 1",
+ "more items 2",
+ "more items 3",
+ "Ridicilously long item caption so we can see how the ComboBox displays ridicilously long captions in the suggestion pop-up",
+ "more items 4", "more items 5", "more items 6",
+ "more items 7");
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ ComboBox percentage = new ComboBox(
+ "200px wide ComboBox with 200% wide suggestion popup", items);
+ percentage.addStyleName("percentage");
+ percentage.setWidth("200px");
+ percentage.setPopupWidth("200%");
+ addComponent(percentage);
+
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Suggestion pop-up's width should be 200% of the ComboBox itself (400px)";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 19685;
+ }
+
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPixels.java b/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPixels.java
new file mode 100644
index 0000000000..623f4c904f
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPixels.java
@@ -0,0 +1,46 @@
+package com.vaadin.tests.components.combobox;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.ComboBox;
+
+public class ComboBoxSuggestionPopupWidthPixels extends AbstractTestUI {
+
+ private static List<String> items = Arrays
+ .asList("abc",
+ "cde",
+ "efg",
+ "ghi",
+ "ijk",
+ "more items 1",
+ "more items 2",
+ "more items 3",
+ "Ridicilously long item caption so we can see how the ComboBox displays ridicilously long captions in the suggestion pop-up",
+ "more items 4", "more items 5", "more items 6",
+ "more items 7");
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ ComboBox pixels = new ComboBox(
+ "200px wide ComboBox with 300px wide suggestion popup", items);
+ pixels.addStyleName("pixels");
+ pixels.setWidth("200px");
+ pixels.setPopupWidth("300px");
+ addComponent(pixels);
+
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Suggestion pop-up's width should 300px";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 19685;
+ }
+
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthLegacyTest.java b/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthLegacyTest.java
new file mode 100644
index 0000000000..d18dd68bd5
--- /dev/null
+++ b/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthLegacyTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.combobox;
+
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.ComboBoxElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class ComboBoxSuggestionPopupWidthLegacyTest extends MultiBrowserTest {
+
+ @Test
+ public void suggestionPopupLegacyWidthTest() throws Exception {
+ openTestURL();
+
+ waitForElementVisible(By.className("legacy"));
+
+ WebElement selectTextbox = $(ComboBoxElement.class).first()
+ .findElement(By.vaadin("#textbox"));
+ selectTextbox.click();
+
+ CustomComboBoxElement cb = $(CustomComboBoxElement.class).first();
+ cb.openPopup();
+ WebElement popup = cb.getSuggestionPopup();
+
+ int width = popup.getSize().getWidth();
+ assertGreater("Legacy mode popup should be quite wide", width, 600);
+ assertLessThan(
+ "Even legacy mode popup should not be over 1000px wide with the set item captions ",
+ width, 1000);
+
+ }
+
+};
diff --git a/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPercentageTest.java b/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPercentageTest.java
new file mode 100644
index 0000000000..2e5dcb380e
--- /dev/null
+++ b/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPercentageTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.combobox;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.ComboBoxElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class ComboBoxSuggestionPopupWidthPercentageTest extends
+ MultiBrowserTest {
+
+ @Test
+ public void suggestionPopupPersentageWidthTest() throws Exception {
+ openTestURL();
+
+ waitForElementVisible(By.className("percentage"));
+
+ WebElement selectTextbox = $(ComboBoxElement.class).first()
+ .findElement(By.vaadin("#textbox"));
+ selectTextbox.click();
+
+ CustomComboBoxElement cb = $(CustomComboBoxElement.class).first();
+ cb.openPopup();
+ WebElement popup = cb.getSuggestionPopup();
+
+ int width = popup.getSize().getWidth();
+ assertTrue(width == 400);
+
+ }
+
+};
diff --git a/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPixelsTest.java b/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPixelsTest.java
new file mode 100644
index 0000000000..f5a0d9dc52
--- /dev/null
+++ b/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPixelsTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.combobox;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.ComboBoxElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class ComboBoxSuggestionPopupWidthPixelsTest extends MultiBrowserTest {
+
+ @Test
+ public void suggestionPopupFixedWidthTest() throws Exception {
+ openTestURL();
+
+ waitForElementVisible(By.className("pixels"));
+
+ WebElement selectTextbox = $(ComboBoxElement.class).first()
+ .findElement(By.vaadin("#textbox"));
+ selectTextbox.click();
+
+ CustomComboBoxElement cb = $(CustomComboBoxElement.class).first();
+ cb.openPopup();
+ WebElement popup = cb.getSuggestionPopup();
+
+ int width = popup.getSize().getWidth();
+ assertTrue(width == 300);
+
+ }
+
+};
diff --git a/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthTest.java b/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthTest.java
new file mode 100644
index 0000000000..11e7629b2d
--- /dev/null
+++ b/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.combobox;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.ComboBoxElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class ComboBoxSuggestionPopupWidthTest extends MultiBrowserTest {
+
+ @Test
+ public void suggestionPopupWidthTest() throws Exception {
+ openTestURL();
+
+ waitForElementVisible(By
+ .className("width-as-percentage"));
+
+ WebElement selectTextbox = $(ComboBoxElement.class).first()
+ .findElement(By.vaadin("#textbox"));
+ selectTextbox.click();
+
+ CustomComboBoxElement cb = $(CustomComboBoxElement.class).first();
+ cb.openPopup();
+ WebElement popup = cb.getSuggestionPopup();
+
+ int width = popup.getSize().getWidth();
+ assertTrue(width == 200);
+
+ }
+
+};