Browse Source

Allow using ComboBox as a replacement for NativeSelect (#5170)

svn changeset:21288/svn branch:6.7
tags/6.7.0.rc1
Leif Åstrand 12 years ago
parent
commit
4e58d66944

+ 48
- 2
src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java View File

@@ -12,6 +12,7 @@ import java.util.List;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Style.Cursor;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
@@ -767,6 +768,16 @@ public class VFilterSelect extends Composite implements Paintable, Field,
client.handleTooltipEvent(event, VFilterSelect.this);
}
}

@Override
// Overridden to avoid selecting text when text input is disabled
public void setSelectionRange(int pos, int length) {
if (textInputEnabled) {
super.setSelectionRange(pos, length);
} else {
super.setSelectionRange(getValue().length(), 0);
}
};
};

private final SuggestionPopup suggestionPopup = new SuggestionPopup();
@@ -843,6 +854,7 @@ public class VFilterSelect extends Composite implements Paintable, Field,
// shown in unfocused empty field, disappears on focus (e.g "Search here")
private static final String CLASSNAME_PROMPT = "prompt";
private static final String ATTR_INPUTPROMPT = "prompt";
public static final String ATTR_NO_TEXT_INPUT = "noInput";
private String inputPrompt = "";
private boolean prompting = false;

@@ -863,6 +875,12 @@ public class VFilterSelect extends Composite implements Paintable, Field,
private boolean focused = false;
private int horizPaddingAndBorder = 2;

/**
* If set to false, the component should not allow entering text to the
* field even for filtering.
*/
private boolean textInputEnabled = true;

/**
* Default constructor
*/
@@ -894,6 +912,7 @@ public class VFilterSelect extends Composite implements Paintable, Field,
tb.setStyleName(CLASSNAME + "-input");
tb.addFocusHandler(this);
tb.addBlurHandler(this);
tb.addClickHandler(this);
popupOpener.setStyleName(CLASSNAME + "-button");
popupOpener.addClickHandler(this);
}
@@ -972,12 +991,16 @@ public class VFilterSelect extends Composite implements Paintable, Field,
enabled = !uidl.hasAttribute("disabled");

tb.setEnabled(enabled);
tb.setReadOnly(readonly);
tb.setReadOnly(readonly || !textInputEnabled);

if (client.updateComponent(this, uidl, true)) {
return;
}

boolean noTextInput = uidl.hasAttribute(ATTR_NO_TEXT_INPUT)
&& uidl.getBooleanAttribute(ATTR_NO_TEXT_INPUT);
setTextInputEnabled(!noTextInput);

// not a FocusWidget -> needs own tabindex handling
if (uidl.hasAttribute("tabindex")) {
tb.setTabIndex(uidl.getIntAttribute("tabindex"));
@@ -1146,6 +1169,21 @@ public class VFilterSelect extends Composite implements Paintable, Field,
initDone = true;
}

private void setTextInputEnabled(boolean textInputEnabled) {
if (this.textInputEnabled == textInputEnabled) {
return;
}

this.textInputEnabled = textInputEnabled;
tb.setReadOnly(!textInputEnabled);

if (textInputEnabled) {
tb.getElement().getStyle().clearCursor();
} else {
tb.getElement().getStyle().setCursor(Cursor.DEFAULT);
}
}

/**
* Sets the text in the text box using a deferred command if on Gecko. This
* is required for performance reasons (see #3663).
@@ -1415,7 +1453,9 @@ public class VFilterSelect extends Composite implements Paintable, Field,
reset();
break;
default:
filterOptions(currentPage);
if (textInputEnabled) {
filterOptions(currentPage);
}
break;
}
}
@@ -1445,6 +1485,12 @@ public class VFilterSelect extends Composite implements Paintable, Field,
* Listener for popupopener
*/
public void onClick(ClickEvent event) {
if (textInputEnabled
&& event.getNativeEvent().getEventTarget().cast() == tb
.getElement()) {
// Don't process clicks on the text field if text input is enabled
return;
}
if (enabled && !readonly) {
// ask suggestionPopup if it was just closed, we are using GWT
// Popup's auto close feature

+ 37
- 0
src/com/vaadin/ui/ComboBox.java View File

@@ -25,6 +25,13 @@ public class ComboBox extends Select {
private String inputPrompt = 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
* field opens the drop down with options
*/
private boolean textInputAllowed = true;
public ComboBox() {
setMultiSelect(false);
setNewItemsAllowed(false);
@@ -84,6 +91,36 @@ public class ComboBox extends Select {
target.addAttribute("prompt", inputPrompt);
}
super.paintContent(target);
if (!textInputAllowed) {
target.addAttribute(VFilterSelect.ATTR_NO_TEXT_INPUT, true);
}
}
/**
* Sets whether it is possible to input text into the field or whether the
* field area of the component is just used to show what is selected.
*
* @see #isTextInputAllowed()
*
* @param textInputAllowed
* true to allow entering text, false to just show the current
* selection
*/
public void setTextInputAllowed(boolean textInputAllowed) {
this.textInputAllowed = textInputAllowed;
requestRepaint();
}
/**
* Returns true if the user can enter text into the field to either filter
* the selections or enter a new value if {@link #isNewItemsAllowed()}
* returns true.
*
* @return
*/
public boolean isTextInputAllowed() {
return textInputAllowed;
}
}

+ 75
- 0
tests/src/com/vaadin/tests/components/combobox/ComboBoxNoTextInput.html View File

@@ -0,0 +1,75 @@
<?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:8080/" />
<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.ComboBoxes2?restartApplication</td>
<td></td>
</tr>
<!--Disabled text input-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentscomboboxComboBoxes2::PID_Smenu#item0</td>
<td>34,8</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentscomboboxComboBoxes2::Root/VOverlay[0]/VMenuBar[0]#item0</td>
<td>21,3</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentscomboboxComboBoxes2::Root/VOverlay[1]/VMenuBar[0]#item8</td>
<td>52,7</td>
</tr>
<!--Check that clicking the text field opens the popup-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentscomboboxComboBoxes2::PID_StestComponent/domChild[0]</td>
<td>37,8</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>vaadin=runcomvaadintestscomponentscomboboxComboBoxes2::Root/VFilterSelect$SuggestionPopup[0]/VFilterSelect$SuggestionMenu[0]#item0</td>
<td></td>
</tr>
<!--Enabled text input again-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentscomboboxComboBoxes2::PID_Smenu#item0</td>
<td>35,5</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentscomboboxComboBoxes2::Root/VOverlay[0]/VMenuBar[0]#item0</td>
<td>14,10</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentscomboboxComboBoxes2::Root/VOverlay[1]/VMenuBar[0]#item8</td>
<td>34,6</td>
</tr>
<!--Check that clicking the text field does not open the popup-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentscomboboxComboBoxes2::PID_StestComponent/domChild[0]</td>
<td>42,9</td>
</tr>
<tr>
<td>assertElementNotPresent</td>
<td>vaadin=runcomvaadintestscomponentscomboboxComboBoxes2::Root/VFilterSelect$SuggestionPopup[0]/VFilterSelect$SuggestionMenu[0]#item0</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>

+ 20
- 0
tests/src/com/vaadin/tests/components/combobox/ComboBoxes2.java View File

@@ -32,6 +32,26 @@ public class ComboBoxes2 extends SelectTest<ComboBox> {
createItemIconSelect(CATEGORY_DATA_SOURCE);
createInputPromptAction(CATEGORY_FEATURES);
createFilteringModeAction(CATEGORY_FEATURES);
createNewItemsAllowedAction(CATEGORY_STATE);
createTextInputAlowedAction(CATEGORY_STATE);
}

private void createTextInputAlowedAction(String category) {
createBooleanAction("Text input allowed", category, true,
new Command<ComboBox, Boolean>() {
public void execute(ComboBox c, Boolean value, Object data) {
c.setTextInputAllowed(value.booleanValue());
}
});
}

private void createNewItemsAllowedAction(String category) {
createBooleanAction("New items allowed", category, false,
new Command<ComboBox, Boolean>() {
public void execute(ComboBox c, Boolean value, Object data) {
c.setNewItemsAllowed(value.booleanValue());
}
});
}

private void createFilteringModeAction(String category) {

Loading…
Cancel
Save