From 4e58d66944ff8167b368646f9281d7c754ddf4c7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leif=20=C3=85strand?= Date: Mon, 26 Sep 2011 08:20:18 +0000 Subject: [PATCH] Allow using ComboBox as a replacement for NativeSelect (#5170) svn changeset:21288/svn branch:6.7 --- .../terminal/gwt/client/ui/VFilterSelect.java | 50 ++++++++++++- src/com/vaadin/ui/ComboBox.java | 37 +++++++++ .../combobox/ComboBoxNoTextInput.html | 75 +++++++++++++++++++ .../components/combobox/ComboBoxes2.java | 20 +++++ 4 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 tests/src/com/vaadin/tests/components/combobox/ComboBoxNoTextInput.html diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java index ae58ec4618..2aec9d3bd0 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java @@ -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 diff --git a/src/com/vaadin/ui/ComboBox.java b/src/com/vaadin/ui/ComboBox.java index 688f750e2b..f32a8bb5ff 100644 --- a/src/com/vaadin/ui/ComboBox.java +++ b/src/com/vaadin/ui/ComboBox.java @@ -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; } } diff --git a/tests/src/com/vaadin/tests/components/combobox/ComboBoxNoTextInput.html b/tests/src/com/vaadin/tests/components/combobox/ComboBoxNoTextInput.html new file mode 100644 index 0000000000..2066da47c1 --- /dev/null +++ b/tests/src/com/vaadin/tests/components/combobox/ComboBoxNoTextInput.html @@ -0,0 +1,75 @@ + + + + + + +New Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
New Test
open/run/com.vaadin.tests.components.combobox.ComboBoxes2?restartApplication
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboBoxes2::PID_Smenu#item034,8
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboBoxes2::Root/VOverlay[0]/VMenuBar[0]#item021,3
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboBoxes2::Root/VOverlay[1]/VMenuBar[0]#item852,7
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboBoxes2::PID_StestComponent/domChild[0]37,8
assertElementPresentvaadin=runcomvaadintestscomponentscomboboxComboBoxes2::Root/VFilterSelect$SuggestionPopup[0]/VFilterSelect$SuggestionMenu[0]#item0
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboBoxes2::PID_Smenu#item035,5
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboBoxes2::Root/VOverlay[0]/VMenuBar[0]#item014,10
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboBoxes2::Root/VOverlay[1]/VMenuBar[0]#item834,6
mouseClickvaadin=runcomvaadintestscomponentscomboboxComboBoxes2::PID_StestComponent/domChild[0]42,9
assertElementNotPresentvaadin=runcomvaadintestscomponentscomboboxComboBoxes2::Root/VFilterSelect$SuggestionPopup[0]/VFilterSelect$SuggestionMenu[0]#item0
+ + diff --git a/tests/src/com/vaadin/tests/components/combobox/ComboBoxes2.java b/tests/src/com/vaadin/tests/components/combobox/ComboBoxes2.java index f41176c6ca..8befbb4612 100644 --- a/tests/src/com/vaadin/tests/components/combobox/ComboBoxes2.java +++ b/tests/src/com/vaadin/tests/components/combobox/ComboBoxes2.java @@ -32,6 +32,26 @@ public class ComboBoxes2 extends SelectTest { 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() { + 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() { + public void execute(ComboBox c, Boolean value, Object data) { + c.setNewItemsAllowed(value.booleanValue()); + } + }); } private void createFilteringModeAction(String category) { -- 2.39.5