From bdee6749d449ffdf7cf6584d9d67bca6f3d0dd79 Mon Sep 17 00:00:00 2001 From: Marc Englund Date: Mon, 6 Apr 2009 13:27:02 +0000 Subject: [PATCH] (merged from 5.4) Implements "input prompt" for ComboBox and TextField. Also includes Sampler samples. Fixes #1455 svn changeset:7337/svn branch:6.0 --- .../ITMILL/themes/default/select/select.css | 6 +- WebContent/ITMILL/themes/default/styles.css | 18 +++- .../themes/default/textfield/textfield.css | 7 +- .../toolkit/demo/sampler/FeatureSet.java | 4 + .../selects/75-ComboBoxInputPrompt.png | Bin 0 -> 3317 bytes .../features/selects/ComboBoxInputPrompt.java | 44 ++++++++ .../selects/ComboBoxInputPromptExample.java | 39 +++++++ .../features/text/75-TextFieldInputPrompt.png | Bin 0 -> 4911 bytes .../features/text/TextFieldInputPrompt.java | 47 +++++++++ .../text/TextFieldInputPromptExample.java | 49 +++++++++ .../terminal/gwt/client/ui/IFilterSelect.java | 95 ++++++++++++------ .../terminal/gwt/client/ui/ITextField.java | 34 ++++++- src/com/itmill/toolkit/ui/ComboBox.java | 31 ++++-- src/com/itmill/toolkit/ui/RichTextArea.java | 11 +- src/com/itmill/toolkit/ui/TextField.java | 26 +++++ 15 files changed, 358 insertions(+), 53 deletions(-) create mode 100644 src/com/itmill/toolkit/demo/sampler/features/selects/75-ComboBoxInputPrompt.png create mode 100644 src/com/itmill/toolkit/demo/sampler/features/selects/ComboBoxInputPrompt.java create mode 100644 src/com/itmill/toolkit/demo/sampler/features/selects/ComboBoxInputPromptExample.java create mode 100644 src/com/itmill/toolkit/demo/sampler/features/text/75-TextFieldInputPrompt.png create mode 100644 src/com/itmill/toolkit/demo/sampler/features/text/TextFieldInputPrompt.java create mode 100644 src/com/itmill/toolkit/demo/sampler/features/text/TextFieldInputPromptExample.java diff --git a/WebContent/ITMILL/themes/default/select/select.css b/WebContent/ITMILL/themes/default/select/select.css index 52c000998d..5c5d57507a 100644 --- a/WebContent/ITMILL/themes/default/select/select.css +++ b/WebContent/ITMILL/themes/default/select/select.css @@ -102,7 +102,11 @@ outline: 5px auto -webkit-focus-ring-color; outline-offset: -4px; } - +.i-filterselect-prompt .i-filterselect-input { + /* input prompt active, i.e empty select */ + color: #999; + font-style: italic; +} .i-filterselect-button { float: right; width: 25px; diff --git a/WebContent/ITMILL/themes/default/styles.css b/WebContent/ITMILL/themes/default/styles.css index 2e9c637b01..439f4f2aec 100644 --- a/WebContent/ITMILL/themes/default/styles.css +++ b/WebContent/ITMILL/themes/default/styles.css @@ -1384,7 +1384,11 @@ input.i-modified, outline: 5px auto -webkit-focus-ring-color; outline-offset: -4px; } - +.i-filterselect-prompt .i-filterselect-input { + /* input prompt active, i.e empty select */ + color: #999; + font-style: italic; +} .i-filterselect-button { float: right; width: 25px; @@ -2483,6 +2487,12 @@ input.i-modified, border-color: #5daee8; } +input.i-textfield-prompt, +textarea.i-textarea-prompt { + color: #999; + font-style: italic; +} + .i-textfield.i-readonly, .i-textarea.i-readonly { background: transparent; @@ -2490,7 +2500,6 @@ input.i-modified, border: none; } - .i-richtextarea { border: 1px solid #b6b6b6; overflow: hidden; @@ -2651,8 +2660,9 @@ input.i-modified, .i-window-footer { height: 8px; margin-left: 9px; - background: transparent url(window/img/bottom-right.png) no-repeat right top; - /* IE7 bug fix */ + background: transparent url(window/img/bottom-right.png) no-repeat right top; +} +.i-ie7 .i-window-footer { position:relative; } diff --git a/WebContent/ITMILL/themes/default/textfield/textfield.css b/WebContent/ITMILL/themes/default/textfield/textfield.css index 0a91a97b2e..16d36e3256 100644 --- a/WebContent/ITMILL/themes/default/textfield/textfield.css +++ b/WebContent/ITMILL/themes/default/textfield/textfield.css @@ -27,6 +27,12 @@ border-color: #5daee8; } +input.i-textfield-prompt, +textarea.i-textarea-prompt { + color: #999; + font-style: italic; +} + .i-textfield.i-readonly, .i-textarea.i-readonly { background: transparent; @@ -34,7 +40,6 @@ border: none; } - .i-richtextarea { border: 1px solid #b6b6b6; overflow: hidden; diff --git a/src/com/itmill/toolkit/demo/sampler/FeatureSet.java b/src/com/itmill/toolkit/demo/sampler/FeatureSet.java index 6c9da622ac..ec521cbc9b 100644 --- a/src/com/itmill/toolkit/demo/sampler/FeatureSet.java +++ b/src/com/itmill/toolkit/demo/sampler/FeatureSet.java @@ -43,6 +43,7 @@ import com.itmill.toolkit.demo.sampler.features.notifications.NotificationWarnin import com.itmill.toolkit.demo.sampler.features.panels.PanelBasic; import com.itmill.toolkit.demo.sampler.features.panels.PanelLight; import com.itmill.toolkit.demo.sampler.features.selects.ComboBoxContains; +import com.itmill.toolkit.demo.sampler.features.selects.ComboBoxInputPrompt; import com.itmill.toolkit.demo.sampler.features.selects.ComboBoxNewItems; import com.itmill.toolkit.demo.sampler.features.selects.ComboBoxPlain; import com.itmill.toolkit.demo.sampler.features.selects.ComboBoxStartsWith; @@ -70,6 +71,7 @@ import com.itmill.toolkit.demo.sampler.features.text.LabelPreformatted; import com.itmill.toolkit.demo.sampler.features.text.LabelRich; import com.itmill.toolkit.demo.sampler.features.text.RichTextEditor; import com.itmill.toolkit.demo.sampler.features.text.TextArea; +import com.itmill.toolkit.demo.sampler.features.text.TextFieldInputPrompt; import com.itmill.toolkit.demo.sampler.features.text.TextFieldSecret; import com.itmill.toolkit.demo.sampler.features.text.TextFieldSingle; import com.itmill.toolkit.demo.sampler.features.trees.TreeActions; @@ -213,6 +215,7 @@ public class FeatureSet extends Feature { new TwinColumnSelect(), // new NativeSelection(), // new ComboBoxPlain(), // + new ComboBoxInputPrompt(), // new ComboBoxStartsWith(), // new ComboBoxContains(), // new ComboBoxNewItems(), // @@ -368,6 +371,7 @@ public class FeatureSet extends Feature { // new TextFieldSingle(), // new TextFieldSecret(), // + new TextFieldInputPrompt(), // new TextArea(), // new RichTextEditor(), // }); diff --git a/src/com/itmill/toolkit/demo/sampler/features/selects/75-ComboBoxInputPrompt.png b/src/com/itmill/toolkit/demo/sampler/features/selects/75-ComboBoxInputPrompt.png new file mode 100644 index 0000000000000000000000000000000000000000..3ef7a48faa0061db5e55cd30dfa819e42abbe24e GIT binary patch literal 3317 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 literal 0 HcmV?d00001 diff --git a/src/com/itmill/toolkit/demo/sampler/features/selects/ComboBoxInputPrompt.java b/src/com/itmill/toolkit/demo/sampler/features/selects/ComboBoxInputPrompt.java new file mode 100644 index 0000000000..2155f874f9 --- /dev/null +++ b/src/com/itmill/toolkit/demo/sampler/features/selects/ComboBoxInputPrompt.java @@ -0,0 +1,44 @@ +package com.itmill.toolkit.demo.sampler.features.selects; + +import com.itmill.toolkit.demo.sampler.APIResource; +import com.itmill.toolkit.demo.sampler.Feature; +import com.itmill.toolkit.demo.sampler.NamedExternalResource; +import com.itmill.toolkit.demo.sampler.features.text.TextFieldInputPrompt; +import com.itmill.toolkit.ui.ComboBox; + +public class ComboBoxInputPrompt extends Feature { + @Override + public String getName() { + return "Combobox with input prompt"; + } + + @Override + public String getDescription() { + return "ComboBox is a drop-down selection component with single item selection." + + " It can have an input prompt - a textual hint that is shown within" + + " the select when no value is selected.
" + + " You can use an input prompt instead of a caption to save" + + " space, but only do so if the function of the ComboBox is" + + " still clear when a value is selected and the prompt is no" + + " longer visible."; + } + + @Override + public APIResource[] getRelatedAPI() { + return new APIResource[] { new APIResource(ComboBox.class) }; + } + + @Override + public Class[] getRelatedFeatures() { + return new Class[] { ComboBoxStartsWith.class, ComboBoxContains.class, + ComboBoxNewItems.class, TextFieldInputPrompt.class }; + } + + @Override + public NamedExternalResource[] getRelatedResources() { + return new NamedExternalResource[] { new NamedExternalResource( + "UI Patterns, Input Prompt", + "http://ui-patterns.com/pattern/InputPrompt") }; + } + +} diff --git a/src/com/itmill/toolkit/demo/sampler/features/selects/ComboBoxInputPromptExample.java b/src/com/itmill/toolkit/demo/sampler/features/selects/ComboBoxInputPromptExample.java new file mode 100644 index 0000000000..4146614659 --- /dev/null +++ b/src/com/itmill/toolkit/demo/sampler/features/selects/ComboBoxInputPromptExample.java @@ -0,0 +1,39 @@ +package com.itmill.toolkit.demo.sampler.features.selects; + +import com.itmill.toolkit.data.Property; +import com.itmill.toolkit.data.Property.ValueChangeEvent; +import com.itmill.toolkit.ui.ComboBox; +import com.itmill.toolkit.ui.VerticalLayout; + +public class ComboBoxInputPromptExample extends VerticalLayout implements + Property.ValueChangeListener { + + private static final String[] cities = new String[] { "Berlin", "Brussels", + "Helsinki", "Madrid", "Oslo", "Paris", "Stockholm" }; + + public ComboBoxInputPromptExample() { + setMargin(true); // for looks: more 'air' + + // Create & set input prompt + ComboBox l = new ComboBox(); + l.setInputPrompt("Please select a city"); + + // configure & load content + l.setImmediate(true); + l.addListener(this); + for (int i = 0; i < cities.length; i++) { + l.addItem(cities[i]); + } + + // add to the layout + addComponent(l); + } + + /* + * Shows a notification when a selection is made. + */ + public void valueChange(ValueChangeEvent event) { + getWindow().showNotification("Selected city: " + event.getProperty()); + + } +} diff --git a/src/com/itmill/toolkit/demo/sampler/features/text/75-TextFieldInputPrompt.png b/src/com/itmill/toolkit/demo/sampler/features/text/75-TextFieldInputPrompt.png new file mode 100644 index 0000000000000000000000000000000000000000..dc7fbb38f9b7c4bd7160bbecac5dbe7408da5bfa GIT binary patch literal 4911 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 literal 0 HcmV?d00001 diff --git a/src/com/itmill/toolkit/demo/sampler/features/text/TextFieldInputPrompt.java b/src/com/itmill/toolkit/demo/sampler/features/text/TextFieldInputPrompt.java new file mode 100644 index 0000000000..5299916e31 --- /dev/null +++ b/src/com/itmill/toolkit/demo/sampler/features/text/TextFieldInputPrompt.java @@ -0,0 +1,47 @@ +package com.itmill.toolkit.demo.sampler.features.text; + +import com.itmill.toolkit.demo.sampler.APIResource; +import com.itmill.toolkit.demo.sampler.Feature; +import com.itmill.toolkit.demo.sampler.FeatureSet; +import com.itmill.toolkit.demo.sampler.NamedExternalResource; +import com.itmill.toolkit.demo.sampler.features.selects.ComboBoxInputPrompt; +import com.itmill.toolkit.demo.sampler.features.selects.ComboBoxNewItems; +import com.itmill.toolkit.ui.TextField; + +public class TextFieldInputPrompt extends Feature { + @Override + public String getName() { + return "Text field with input prompt"; + } + + @Override + public String getDescription() { + return " The TextField can have an input prompt - a textual hint that is shown within" + + " the field when the field is otherwise empty.
" + + " You can use an input prompt instead of a caption to save" + + " space, but only do so if the function of the TextField is" + + " still clear when a value has been entered and the prompt is no" + + " longer visible."; + } + + @Override + public APIResource[] getRelatedAPI() { + return new APIResource[] { new APIResource(TextField.class) }; + } + + @Override + public Class[] getRelatedFeatures() { + // TODO update CB -ref to 'suggest' pattern, when available + return new Class[] { TextFieldSingle.class, TextFieldSecret.class, + ComboBoxInputPrompt.class, ComboBoxNewItems.class, + FeatureSet.Texts.class }; + } + + @Override + public NamedExternalResource[] getRelatedResources() { + return new NamedExternalResource[] { new NamedExternalResource( + "UI Patterns, Input Prompt", + "http://ui-patterns.com/pattern/InputPrompt") }; + } + +} diff --git a/src/com/itmill/toolkit/demo/sampler/features/text/TextFieldInputPromptExample.java b/src/com/itmill/toolkit/demo/sampler/features/text/TextFieldInputPromptExample.java new file mode 100644 index 0000000000..19f995044a --- /dev/null +++ b/src/com/itmill/toolkit/demo/sampler/features/text/TextFieldInputPromptExample.java @@ -0,0 +1,49 @@ +package com.itmill.toolkit.demo.sampler.features.text; + +import com.itmill.toolkit.data.Property; +import com.itmill.toolkit.data.Property.ValueChangeEvent; +import com.itmill.toolkit.ui.TextField; +import com.itmill.toolkit.ui.VerticalLayout; + +public class TextFieldInputPromptExample extends VerticalLayout implements + Property.ValueChangeListener { + + public TextFieldInputPromptExample() { + // add som 'air' to the layout + setSpacing(true); + setMargin(true); + + // Username field + input prompt + TextField username = new TextField(); + username.setInputPrompt("Username"); + // configure & add to layout + username.setImmediate(true); + username.addListener(this); + addComponent(username); + + // Password field + input prompt + TextField password = new TextField(); + password.setInputPrompt("Password"); + // configure & add to layout + password.setSecret(true); + password.setImmediate(true); + password.addListener(this); + addComponent(password); + + // Comment field + input prompt + TextField comment = new TextField(); + comment.setInputPrompt("Comment"); + // configure & add to layout + comment.setRows(3); + comment.setImmediate(true); + comment.addListener(this); + addComponent(comment); + + } + + public void valueChange(ValueChangeEvent event) { + getWindow().showNotification("Received " + event.getProperty()); + + } + +} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IFilterSelect.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IFilterSelect.java index 3b0fdd7927..f18040d581 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IFilterSelect.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IFilterSelect.java @@ -452,8 +452,7 @@ public class IFilterSelect extends Composite implements Paintable, Field, } if (allowNewItem) { - if (!enteredItemValue.equals(emptyText) - && !enteredItemValue.equals(lastNewItemString)) { + if (!prompting && !enteredItemValue.equals(lastNewItemString)) { /* * Store last sent new item string to avoid double sends */ @@ -469,13 +468,18 @@ public class IFilterSelect extends Composite implements Paintable, Field, } else { if (currentSuggestion != null) { String text = currentSuggestion.getReplacementString(); - tb.setText((text.equals("") ? emptyText : text)); - // TODO add/remove class CLASSNAME_EMPTY + /*- TODO? + if (text.equals("")) { + tb.setText(inputPrompt); + prompting = true; + addStyleDependentName(CLASSNAME_PROMPT); + } else { + tb.setText(text); + prompting = false; + removeStyleDependentName(CLASSNAME_PROMPT); + } + -*/ selectedOptionKey = currentSuggestion.key; - } else { - tb.setText(emptyText); - // TODO add class CLASSNAME_EMPTY - selectedOptionKey = null; } } suggestionPopup.hide(); @@ -546,7 +550,11 @@ public class IFilterSelect extends Composite implements Paintable, Field, private boolean enabled; // shown in unfocused empty field, disappears on focus (e.g "Search here") - private String emptyText = ""; + private static final String CLASSNAME_PROMPT = "prompt"; + private static final String ATTR_INPUTPROMPT = "prompt"; + private String inputPrompt = ""; + private boolean prompting = false; + // Set true when popupopened has been clicked. Cleared on each UIDL-update. // This handles the special case where are not filtering yet and the // selected value has changed on the server-side. See #2119 @@ -555,8 +563,6 @@ public class IFilterSelect extends Composite implements Paintable, Field, private int textboxPadding = -1; private int componentPadding = -1; private int suggestionPopupMinWidth = 0; - // private static final String CLASSNAME_EMPTY = "empty"; - private static final String ATTR_EMPTYTEXT = "emptytext"; /* * Stores the last new item string to avoid double submissions. Cleared on * uidl updates @@ -656,9 +662,11 @@ public class IFilterSelect extends Composite implements Paintable, Field, currentPage = uidl.getIntVariable("page"); - if (uidl.hasAttribute(ATTR_EMPTYTEXT)) { - // "emptytext" changed from server - emptyText = uidl.getStringAttribute(ATTR_EMPTYTEXT); + if (uidl.hasAttribute(ATTR_INPUTPROMPT)) { + // input prompt changed from server + inputPrompt = uidl.getStringAttribute(ATTR_INPUTPROMPT); + } else { + inputPrompt = ""; } suggestionPopup.setPagingEnabled(true); @@ -671,7 +679,7 @@ public class IFilterSelect extends Composite implements Paintable, Field, final UIDL options = uidl.getChildUIDL(0); totalMatches = uidl.getIntAttribute("totalMatches"); - String captions = emptyText; + String captions = inputPrompt; for (final Iterator i = options.getChildIterator(); i.hasNext();) { final UIDL optionUidl = (UIDL) i.next(); @@ -697,9 +705,12 @@ public class IFilterSelect extends Composite implements Paintable, Field, if ((!filtering || popupOpenerClicked) && uidl.hasVariable("selected") && uidl.getStringArrayVariable("selected").length == 0) { // select nulled - tb.setText(emptyText); + if (!filtering || !popupOpenerClicked) { + tb.setText(inputPrompt); + prompting = true; + addStyleDependentName(CLASSNAME_PROMPT); + } selectedOptionKey = null; - // TODO add class CLASSNAME_EMPTY } if (filtering @@ -751,9 +762,17 @@ public class IFilterSelect extends Composite implements Paintable, Field, // normal selection newKey = String.valueOf(suggestion.getOptionKey()); } + String text = suggestion.getReplacementString(); - tb.setText(text.equals("") ? emptyText : text); - // TODO add/remove class CLASSNAME_EMPTY + if ("".equals(newKey)) { + tb.setText(inputPrompt); + prompting = true; + addStyleDependentName(CLASSNAME_PROMPT); + } else { + tb.setText(text); + prompting = false; + removeStyleDependentName(CLASSNAME_PROMPT); + } setSelectedItemIcon(suggestion.getIconUri()); if (!newKey.equals(selectedOptionKey)) { selectedOptionKey = newKey; @@ -844,12 +863,14 @@ public class IFilterSelect extends Composite implements Paintable, Field, case KeyboardListener.KEY_ESCAPE: if (currentSuggestion != null) { String text = currentSuggestion.getReplacementString(); - tb.setText((text.equals("") ? emptyText : text)); - // TODO add/remove class CLASSNAME_EMPTY + tb.setText(text); + prompting = false; + removeStyleDependentName(CLASSNAME_PROMPT); selectedOptionKey = currentSuggestion.key; } else { - tb.setText(emptyText); - // TODO add class CLASSNAME_EMPTY + tb.setText(inputPrompt); + prompting = true; + addStyleDependentName(CLASSNAME_PROMPT); selectedOptionKey = null; } lastFilter = ""; @@ -868,12 +889,14 @@ public class IFilterSelect extends Composite implements Paintable, Field, public void onClick(Widget sender) { if (enabled) { // ask suggestionPopup if it was just closed, we are using GWT - // Popup's - // auto close feature + // Popup's auto close feature if (!suggestionPopup.isJustClosed()) { filterOptions(-1, ""); popupOpenerClicked = true; lastFilter = ""; + } else if (selectedOptionKey == null) { + tb.setText(inputPrompt); + prompting = true; } DOM.eventPreventDefault(DOM.eventGetCurrentEvent()); tb.setFocus(true); @@ -888,13 +911,13 @@ public class IFilterSelect extends Composite implements Paintable, Field, private native int minWidth(String captions) /*-{ if(!captions || captions.length <= 0) - return 0; + return 0; captions = captions.split("|"); var d = $wnd.document.createElement("div"); var html = ""; for(var i=0; i < captions.length; i++) { - html += "
" + captions[i] + "
"; - // TODO apply same CSS classname as in suggestionmenu + html += "
" + captions[i] + "
"; + // TODO apply same CSS classname as in suggestionmenu } d.style.position = "absolute"; d.style.top = "0"; @@ -908,9 +931,9 @@ public class IFilterSelect extends Composite implements Paintable, Field, }-*/; public void onFocus(Widget sender) { - if (emptyText.equals(tb.getText())) { + if (prompting) { tb.setText(""); - // TODO remove class CLASSNAME_EMPTY + removeStyleDependentName(CLASSNAME_PROMPT); } addStyleDependentName("focus"); } @@ -920,14 +943,20 @@ public class IFilterSelect extends Composite implements Paintable, Field, // typing so fast the popup was never opened, or it's just closed suggestionPopup.menu.doSelectedItemAction(); } - if ("".equals(tb.getText())) { - tb.setText(emptyText); - // TODO add CLASSNAME_EMPTY + if (selectedOptionKey == null) { + tb.setText(inputPrompt); + prompting = true; + addStyleDependentName(CLASSNAME_PROMPT); } removeStyleDependentName("focus"); } public void focus() { + if (prompting) { + tb.setText(""); + prompting = false; + removeStyleDependentName(CLASSNAME_PROMPT); + } tb.setFocus(true); } diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITextField.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ITextField.java index 0e342428e8..e21a5fe5b3 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITextField.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/ITextField.java @@ -47,6 +47,11 @@ public class ITextField extends TextBoxBase implements Paintable, Field, private int extraVerticalPixels = -1; private int maxLength = -1; + private static final String CLASSNAME_PROMPT = "prompt"; + private static final String ATTR_INPUTPROMPT = "prompt"; + private String inputPrompt = null; + private boolean prompting = false; + public ITextField() { this(DOM.createInputText()); } @@ -86,6 +91,8 @@ public class ITextField extends TextBoxBase implements Paintable, Field, setReadOnly(false); } + inputPrompt = uidl.getStringAttribute(ATTR_INPUTPROMPT); + setMaxLength(uidl.hasAttribute("maxLength") ? uidl .getIntAttribute("maxLength") : -1); @@ -95,7 +102,15 @@ public class ITextField extends TextBoxBase implements Paintable, Field, setColumns(new Integer(uidl.getStringAttribute("cols")).intValue()); } - setText(uidl.getStringVariable("text")); + String text = uidl.getStringVariable("text"); + prompting = inputPrompt != null && (text == null || text.equals("")); + if (prompting) { + setText(inputPrompt); + addStyleDependentName(CLASSNAME_PROMPT); + } else { + setText(text); + removeStyleDependentName(CLASSNAME_PROMPT); + } valueBeforeEdit = uidl.getStringVariable("text"); } @@ -103,13 +118,13 @@ public class ITextField extends TextBoxBase implements Paintable, Field, if (newMaxLength > 0) { maxLength = newMaxLength; if (getElement().getTagName().toLowerCase().equals("textarea")) { - // NOP no maxlenght property for textarea + // NOP no maxlength property for textarea } else { getElement().setPropertyInt("maxLength", maxLength); } } else if (maxLength != -1) { if (getElement().getTagName().toLowerCase().equals("textarea")) { - // NOP no maxlenght property for textarea + // NOP no maxlength property for textarea } else { getElement().setAttribute("maxlength", ""); } @@ -125,7 +140,8 @@ public class ITextField extends TextBoxBase implements Paintable, Field, public void onChange(Widget sender) { if (client != null && id != null) { String newText = getText(); - if (newText != null && !newText.equals(valueBeforeEdit)) { + if (!prompting && newText != null + && !newText.equals(valueBeforeEdit)) { client.updateVariable(id, "text", getText(), immediate); valueBeforeEdit = newText; } @@ -142,12 +158,22 @@ public class ITextField extends TextBoxBase implements Paintable, Field, public void onFocus(Widget sender) { addStyleDependentName(CLASSNAME_FOCUS); + if (prompting) { + setText(""); + removeStyleDependentName(CLASSNAME_PROMPT); + } focusedTextField = this; } public void onLostFocus(Widget sender) { removeStyleDependentName(CLASSNAME_FOCUS); focusedTextField = null; + String text = getText(); + prompting = inputPrompt != null && (text == null || "".equals(text)); + if (prompting) { + setText(inputPrompt); + addStyleDependentName(CLASSNAME_PROMPT); + } onChange(sender); } diff --git a/src/com/itmill/toolkit/ui/ComboBox.java b/src/com/itmill/toolkit/ui/ComboBox.java index f29b51b7d9..1c251ef0a0 100644 --- a/src/com/itmill/toolkit/ui/ComboBox.java +++ b/src/com/itmill/toolkit/ui/ComboBox.java @@ -7,6 +7,8 @@ package com.itmill.toolkit.ui; import java.util.Collection; import com.itmill.toolkit.data.Container; +import com.itmill.toolkit.terminal.PaintException; +import com.itmill.toolkit.terminal.PaintTarget; /** * A filtering dropdown single-select. Suitable for newItemsAllowed, but it's @@ -18,7 +20,7 @@ import com.itmill.toolkit.data.Container; */ public class ComboBox extends Select { - private String emptyText = null; + private String inputPrompt = null; public ComboBox() { setMultiSelect(false); @@ -51,21 +53,32 @@ public class ComboBox extends Select { super.setMultiSelect(multiSelect); } - /*- TODO enable and test this - client impl exists - public String getEmptyText() { - return emptyText; + /** + * Gets the current input prompt. + * + * @see #setInputPrompt(String) + * @return the current input prompt, or null if not enabled + */ + public String getInputPrompt() { + return inputPrompt; } - public void setEmptyText(String emptyText) { - this.emptyText = emptyText; + /** + * 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 + */ + public void setInputPrompt(String inputPrompt) { + this.inputPrompt = inputPrompt; } public void paintContent(PaintTarget target) throws PaintException { - if (emptyText != null) { - target.addAttribute("emptytext", emptyText); + if (inputPrompt != null) { + target.addAttribute("prompt", inputPrompt); } super.paintContent(target); } - -*/ } diff --git a/src/com/itmill/toolkit/ui/RichTextArea.java b/src/com/itmill/toolkit/ui/RichTextArea.java index 213eb2635b..fad763819d 100644 --- a/src/com/itmill/toolkit/ui/RichTextArea.java +++ b/src/com/itmill/toolkit/ui/RichTextArea.java @@ -8,7 +8,7 @@ import com.itmill.toolkit.terminal.PaintException; import com.itmill.toolkit.terminal.PaintTarget; /** - * A simple RichTextEditor to edit HTML format text. + * A simple RichTextArea to edit HTML format text. * * Note, that using {@link TextField#setMaxLength(int)} method in * {@link RichTextArea} may produce unexpected results as formatting is counted @@ -22,4 +22,13 @@ public class RichTextArea extends TextField { super.paintContent(target); } + /** + * RichTextArea does not support input prompt. + */ + @Override + public void setInputPrompt(String inputPrompt) { + throw new UnsupportedOperationException( + "RichTextArea does not support inputPrompt"); + } + } diff --git a/src/com/itmill/toolkit/ui/TextField.java b/src/com/itmill/toolkit/ui/TextField.java index 0b7336e215..e5572f0b9f 100644 --- a/src/com/itmill/toolkit/ui/TextField.java +++ b/src/com/itmill/toolkit/ui/TextField.java @@ -73,6 +73,8 @@ public class TextField extends AbstractField { */ private boolean nullSettingAllowed = false; + private String inputPrompt = null; + /** * Maximum character count in text field. */ @@ -159,6 +161,10 @@ public class TextField extends AbstractField { target.addAttribute("maxLength", getMaxLength()); } + if (inputPrompt != null) { + target.addAttribute("prompt", inputPrompt); + } + // Adds the number of column and rows final int c = getColumns(); final int r = getRows(); @@ -474,6 +480,26 @@ public class TextField extends AbstractField { this.nullSettingAllowed = nullSettingAllowed; } + /** + * Gets the current input prompt. + * + * @see #setInputPrompt(String) + * @return the current input prompt, or null if not enabled + */ + public String getInputPrompt() { + return inputPrompt; + } + + /** + * Sets the input prompt - a textual prompt that is displayed when the field + * would otherwise be empty, to prompt the user for input. + * + * @param inputPrompt + */ + public void setInputPrompt(String inputPrompt) { + this.inputPrompt = inputPrompt; + } + /** * Gets the value formatter of TextField. * -- 2.39.5