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: Id60a6996ee82726196b84d50c2d0d18a6cfb5ebftags/7.7.0.alpha3
import com.google.gwt.dom.client.Document; | import com.google.gwt.dom.client.Document; | ||||
import com.google.gwt.dom.client.Element; | import com.google.gwt.dom.client.Element; | ||||
import com.google.gwt.dom.client.NativeEvent; | 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; | ||||
import com.google.gwt.dom.client.Style.Display; | import com.google.gwt.dom.client.Style.Display; | ||||
import com.google.gwt.dom.client.Style.Unit; | 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.BlurEvent; | ||||
import com.google.gwt.event.dom.client.BlurHandler; | import com.google.gwt.event.dom.client.BlurHandler; | ||||
import com.google.gwt.event.dom.client.ClickEvent; | import com.google.gwt.event.dom.client.ClickEvent; | ||||
debug("VFS.SP: setPosition(" + offsetWidth + ", " + offsetHeight | debug("VFS.SP: setPosition(" + offsetWidth + ", " + offsetHeight | ||||
+ ")"); | + ")"); | ||||
int top; | |||||
int top = topPosition; | |||||
int left = getPopupLeft(); | int left = getPopupLeft(); | ||||
// reset menu size and retrieve its "natural" size | // reset menu size and retrieve its "natural" size | ||||
+ "]"); | + "]"); | ||||
Element menuFirstChild = menu.getElement().getFirstChildElement(); | 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) { | if (popupOuterPadding == -1) { | ||||
popupOuterPadding = WidgetUtil | 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() | if (BrowserInfo.get().isIE() | ||||
&& BrowserInfo.get().getBrowserMajorVersion() < 11) { | && BrowserInfo.get().getBrowserMajorVersion() < 11) { | ||||
// Must take margin,border,padding manually into account for | // Must take margin,border,padding manually into account for | ||||
// menu element as we measure the element child and set width to | // menu element as we measure the element child and set width to | ||||
// the element parent | // 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 | * IE requires us to specify the width for the container | ||||
menu.setHeight(menuHeight + "px"); | 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"); | |||||
} | |||||
} | } | ||||
} | } | ||||
if (left < 0) { | if (left < 0) { | ||||
left = 0; | left = 0; | ||||
menu.setWidth(Window.getClientWidth() + "px"); | menu.setWidth(Window.getClientWidth() + "px"); | ||||
} | |||||
if (BrowserInfo.get().isIE() | |||||
&& BrowserInfo.get().getBrowserMajorVersion() < 10) { | |||||
setTdWidth(menu.getElement(), Window.getClientWidth() - 8); | |||||
} | } | ||||
} | } | ||||
menu.scrollSelectionIntoView(); | menu.scrollSelectionIntoView(); | ||||
} | } | ||||
/** | |||||
* 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? | * Was the popup just closed? | ||||
* | * | ||||
isFirstIteration = false; | 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); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
/** For internal use only. May be removed or replaced in the future. */ | /** For internal use only. May be removed or replaced in the future. */ | ||||
public int suggestionPopupMinWidth = 0; | public int suggestionPopupMinWidth = 0; | ||||
public String suggestionPopupWidth = null; | |||||
private int popupWidth = -1; | private int popupWidth = -1; | ||||
/** | /** | ||||
* Stores the last new item string to avoid double submissions. Cleared on | * Stores the last new item string to avoid double submissions. Cleared on |
import com.vaadin.ui.ComboBox; | import com.vaadin.ui.ComboBox; | ||||
@Connect(ComboBox.class) | @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 | // oldSuggestionTextMatchTheOldSelection is used to detect when it's safe to | ||||
// update textbox text by a changed item caption. | // update textbox text by a changed item caption. | ||||
// work without additional UIDL messages | // work without additional UIDL messages | ||||
boolean noTextInput = uidl | boolean noTextInput = uidl | ||||
.hasAttribute(ComboBoxConstants.ATTR_NO_TEXT_INPUT) | .hasAttribute(ComboBoxConstants.ATTR_NO_TEXT_INPUT) | ||||
&& uidl.getBooleanAttribute(ComboBoxConstants.ATTR_NO_TEXT_INPUT); | |||||
&& uidl.getBooleanAttribute( | |||||
ComboBoxConstants.ATTR_NO_TEXT_INPUT); | |||||
getWidget().setTextInputEnabled(!noTextInput); | getWidget().setTextInputEnabled(!noTextInput); | ||||
// not a FocusWidget -> needs own tabindex handling | // not a FocusWidget -> needs own tabindex handling | ||||
getWidget().tb.setTabIndex(getState().tabIndex); | getWidget().tb.setTabIndex(getState().tabIndex); | ||||
if (uidl.hasAttribute("filteringmode")) { | if (uidl.hasAttribute("filteringmode")) { | ||||
getWidget().filteringmode = FilteringMode.valueOf(uidl | |||||
.getStringAttribute("filteringmode")); | |||||
getWidget().filteringmode = FilteringMode | |||||
.valueOf(uidl.getStringAttribute("filteringmode")); | |||||
} | } | ||||
getWidget().immediate = getState().immediate; | getWidget().immediate = getState().immediate; | ||||
getWidget().inputPrompt = ""; | getWidget().inputPrompt = ""; | ||||
} | } | ||||
if (uidl.hasAttribute("suggestionPopupWidth")) { | |||||
getWidget().suggestionPopupWidth = uidl | |||||
.getStringAttribute("suggestionPopupWidth"); | |||||
} else { | |||||
getWidget().suggestionPopupWidth = null; | |||||
} | |||||
getWidget().suggestionPopup.updateStyleNames(uidl, getState()); | getWidget().suggestionPopup.updateStyleNames(uidl, getState()); | ||||
getWidget().allowNewItem = uidl.hasAttribute("allownewitem"); | getWidget().allowNewItem = uidl.hasAttribute("allownewitem"); | ||||
&& uidl.hasAttribute("selectedCaption")) { | && uidl.hasAttribute("selectedCaption")) { | ||||
// scrolling to correct page is disabled, caption is passed as a | // scrolling to correct page is disabled, caption is passed as a | ||||
// special parameter | // special parameter | ||||
getWidget().tb.setText(uidl | |||||
.getStringAttribute("selectedCaption")); | |||||
getWidget().tb | |||||
.setText(uidl.getStringAttribute("selectedCaption")); | |||||
} else { | } else { | ||||
resetSelection(); | resetSelection(); | ||||
} | } | ||||
if (!getWidget().waitingForFilteringResponse | if (!getWidget().waitingForFilteringResponse | ||||
|| getWidget().popupOpenerClicked) { | || getWidget().popupOpenerClicked) { | ||||
if (!suggestionKey.equals(getWidget().selectedOptionKey) | if (!suggestionKey.equals(getWidget().selectedOptionKey) | ||||
|| suggestion.getReplacementString().equals( | |||||
getWidget().tb.getText()) | |||||
|| suggestion.getReplacementString() | |||||
.equals(getWidget().tb.getText()) | |||||
|| oldSuggestionTextMatchTheOldSelection) { | || oldSuggestionTextMatchTheOldSelection) { | ||||
// Update text field if we've got a new | // Update text field if we've got a new | ||||
// selection | // selection | ||||
// Also update if we've got the same text to | // Also update if we've got the same text to | ||||
// retain old text selection behavior | // retain old text selection behavior | ||||
// OR if selected item caption is changed. | // OR if selected item caption is changed. | ||||
getWidget().setPromptingOff( | |||||
suggestion.getReplacementString()); | |||||
getWidget() | |||||
.setPromptingOff(suggestion.getReplacementString()); | |||||
getWidget().selectedOptionKey = suggestionKey; | getWidget().selectedOptionKey = suggestionKey; | ||||
} | } | ||||
} | } | ||||
private boolean isWidgetsCurrentSelectionTextInTextBox() { | private boolean isWidgetsCurrentSelectionTextInTextBox() { | ||||
return getWidget().currentSuggestion != null | return getWidget().currentSuggestion != null | ||||
&& getWidget().currentSuggestion.getReplacementString().equals( | |||||
getWidget().tb.getText()); | |||||
&& getWidget().currentSuggestion.getReplacementString() | |||||
.equals(getWidget().tb.getText()); | |||||
} | } | ||||
private void resetSelection() { | private void resetSelection() { | ||||
// just clear the input if the value has changed from something | // just clear the input if the value has changed from something | ||||
// else to null | // else to null | ||||
if (getWidget().selectedOptionKey != null | if (getWidget().selectedOptionKey != null | ||||
|| (getWidget().allowNewItem && !getWidget().tb | |||||
.getValue().isEmpty())) { | |||||
|| (getWidget().allowNewItem | |||||
&& !getWidget().tb.getValue().isEmpty())) { | |||||
getWidget().tb.setValue(""); | getWidget().tb.setValue(""); | ||||
} | } | ||||
} | } |
*/ | */ | ||||
private boolean scrollToSelectedItem = true; | private boolean scrollToSelectedItem = true; | ||||
private String suggestionPopupWidth = null; | |||||
/** | /** | ||||
* If text input is not allowed, the ComboBox behaves like a pretty | * If text input is not allowed, the ComboBox behaves like a pretty | ||||
* NativeSelect - the user can not enter any text and clicking the text | * NativeSelect - the user can not enter any text and clicking the text | ||||
/** | /** | ||||
* Sets the input prompt - a textual prompt that is displayed when the | * Sets the input prompt - a textual prompt that is displayed when the | ||||
* select would otherwise be empty, to prompt the user for input. | * select would otherwise be empty, to prompt the user for input. | ||||
* | |||||
* | |||||
* @param inputPrompt | * @param inputPrompt | ||||
* the desired input prompt, or null to disable | * the desired input prompt, or null to disable | ||||
*/ | */ | ||||
target.addAttribute("pagelength", pageLength); | target.addAttribute("pagelength", pageLength); | ||||
if (suggestionPopupWidth != null) { | |||||
target.addAttribute("suggestionPopupWidth", | |||||
suggestionPopupWidth); | |||||
} | |||||
target.addAttribute("filteringmode", getFilteringMode().toString()); | target.addAttribute("filteringmode", getFilteringMode().toString()); | ||||
// Paints the options and create array of selected id keys | // Paints the options and create array of selected id keys | ||||
return pageLength; | return pageLength; | ||||
} | } | ||||
/** | |||||
* 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 | * Sets the page length for the suggestion popup. Setting the page length to | ||||
* 0 will disable suggestion popup paging (all items visible). | * 0 will disable suggestion popup paging (all items visible). | ||||
markAsDirty(); | markAsDirty(); | ||||
} | } | ||||
/** | |||||
* 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 | * 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 | * on which it is) when opening the combo box popup or not. Only applies to |
border-collapse: collapse; | border-collapse: collapse; | ||||
border: none; | border: none; | ||||
vertical-align:top; | 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 { | .v-filterselect-suggestmenu .gwt-MenuItem { | ||||
white-space: nowrap; | 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 { | .v-filterselect-suggestmenu .gwt-MenuItem .v-icon { | ||||
margin-right: 3px; | margin-right: 3px; |
-moz-user-select: none; | -moz-user-select: none; | ||||
-ms-user-select: none; | -ms-user-select: none; | ||||
cursor: default; | cursor: default; | ||||
} | |||||
} | |||||
.v-filterselect-suggestpopup .gwt-MenuItem { | |||||
padding: 0 .7em; | |||||
} | |||||
.v-contextmenu td.gwt-MenuItem-selected div, | .v-contextmenu td.gwt-MenuItem-selected div, | ||||
.v-filterselect-suggestpopup td.gwt-MenuItem-selected, | .v-filterselect-suggestpopup td.gwt-MenuItem-selected, |
background-position: -65px -4px; | background-position: -65px -4px; | ||||
} | } | ||||
.v-filterselect-suggestmenu .gwt-MenuItem span { | .v-filterselect-suggestmenu .gwt-MenuItem span { | ||||
display: block; | |||||
width: 100%; | |||||
height: 18px; | 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 { | .v-filterselect-suggestmenu .gwt-MenuItem .v-icon { |
} | } | ||||
.#{$primaryStyleName}-suggestmenu .gwt-MenuItem { | .#{$primaryStyleName}-suggestmenu .gwt-MenuItem { | ||||
padding: 1px 8px; | padding: 1px 8px; | ||||
height: 16px; | |||||
min-height: 18px; | |||||
user-select: none; | user-select: none; | ||||
-moz-user-select: none; | -moz-user-select: none; | ||||
-webkit-user-select: none; | -webkit-user-select: none; |
.#{$primaryStyleName}-suggestmenu .gwt-MenuItem { | .#{$primaryStyleName}-suggestmenu .gwt-MenuItem { | ||||
padding: 1px 6px; | padding: 1px 6px; | ||||
cursor: pointer; | cursor: pointer; | ||||
height: 18px; | |||||
min-height: 21px; | |||||
} | } | ||||
.#{$primaryStyleName}-suggestmenu .gwt-MenuItem .v-icon { | .#{$primaryStyleName}-suggestmenu .gwt-MenuItem .v-icon { | ||||
margin-right: 3px; | margin-right: 3px; |
[class$="suggestmenu"] { | [class$="suggestmenu"] { | ||||
@include valo-selection-overlay-style($animate-in: false, $animate-out: false); | @include valo-selection-overlay-style($animate-in: false, $animate-out: false); | ||||
@include box-sizing(border-box); | |||||
@include box-sizing(content-box); | |||||
position: relative; | position: relative; | ||||
z-index: 1; | 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; | 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 { | .gwt-MenuItem { | ||||
@include valo-selection-item-style; | @include valo-selection-item-style; | ||||
height: $v-selection-item-height; | |||||
box-sizing: border-box; | |||||
text-overflow: ellipsis; | |||||
overflow-x: hidden; | |||||
} | } | ||||
.gwt-MenuItem-selected { | .gwt-MenuItem-selected { |
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; | |||||
} | |||||
} |
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; | |||||
} | |||||
} |
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; | |||||
} | |||||
} |
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; | |||||
} | |||||
} |
/* | |||||
* 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); | |||||
} | |||||
}; |
/* | |||||
* 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); | |||||
} | |||||
}; |
/* | |||||
* 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); | |||||
} | |||||
}; |
/* | |||||
* 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); | |||||
} | |||||
}; |