diff options
author | Henri Sara <hesara@vaadin.com> | 2013-05-10 16:25:55 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2013-05-14 13:15:22 +0000 |
commit | b8c6a15da87ff6d2a83e7c0d79dd45ee120fe6a2 (patch) | |
tree | d6ad713f9a5d2e10a53df71017ff5b7b3fbbf91e /client | |
parent | 6d7f5e4bc9b16cb5b6bc3ad2503f251977cbb2af (diff) | |
download | vaadin-framework-b8c6a15da87ff6d2a83e7c0d79dd45ee120fe6a2.tar.gz vaadin-framework-b8c6a15da87ff6d2a83e7c0d79dd45ee120fe6a2.zip |
Clear items in ComboBox only if changed (#10924)
Selection is now sent only as a key, removed redundant attribute on the
item.
Change-Id: I882d4ae17a1dc91f7a55a0b4a94e47c078ffc022
Diffstat (limited to 'client')
-rw-r--r-- | client/src/com/vaadin/client/ui/VFilterSelect.java | 21 | ||||
-rw-r--r-- | client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java | 147 |
2 files changed, 110 insertions, 58 deletions
diff --git a/client/src/com/vaadin/client/ui/VFilterSelect.java b/client/src/com/vaadin/client/ui/VFilterSelect.java index 11f89ee232..a3156221b9 100644 --- a/client/src/com/vaadin/client/ui/VFilterSelect.java +++ b/client/src/com/vaadin/client/ui/VFilterSelect.java @@ -168,6 +168,27 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, public void execute() { onSuggestionSelected(this); } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof FilterSelectSuggestion)) { + return false; + } + FilterSelectSuggestion other = (FilterSelectSuggestion) obj; + if ((key == null && other.key != null) + || (key != null && !key.equals(other.key))) { + return false; + } + if ((caption == null && other.caption != null) + || (caption != null && !caption.equals(other.caption))) { + return false; + } + if ((iconUri == null && other.iconUri != null) + || (iconUri != null && !iconUri.equals(other.iconUri))) { + return false; + } + return true; + } } /** diff --git a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java index 7c82db1b00..345bdc0cbb 100644 --- a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java +++ b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java @@ -15,7 +15,9 @@ */ package com.vaadin.client.ui.combobox; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.Paintable; @@ -98,24 +100,6 @@ public class ComboBoxConnector extends AbstractFieldConnector implements getWidget().allowNewItem = uidl.hasAttribute("allownewitem"); getWidget().lastNewItemString = null; - getWidget().currentSuggestions.clear(); - if (!getWidget().waitingForFilteringResponse) { - /* - * Clear the current suggestions as the server response always - * includes the new ones. Exception is when filtering, then we need - * to retain the value if the user does not select any of the - * options matching the filter. - */ - getWidget().currentSuggestion = null; - /* - * Also ensure no old items in menu. Unless cleared the old values - * may cause odd effects on blur events. Suggestions in menu might - * not necessary exist in select at all anymore. - */ - getWidget().suggestionPopup.menu.clearItems(); - - } - final UIDL options = uidl.getChildUIDL(0); if (uidl.hasAttribute("totalMatches")) { getWidget().totalMatches = uidl.getIntAttribute("totalMatches"); @@ -123,54 +107,52 @@ public class ComboBoxConnector extends AbstractFieldConnector implements getWidget().totalMatches = 0; } + List<FilterSelectSuggestion> newSuggestions = new ArrayList<FilterSelectSuggestion>(); + for (final Iterator<?> i = options.getChildIterator(); i.hasNext();) { final UIDL optionUidl = (UIDL) i.next(); final FilterSelectSuggestion suggestion = getWidget().new FilterSelectSuggestion( optionUidl); - getWidget().currentSuggestions.add(suggestion); - if (optionUidl.hasAttribute("selected")) { - if (!getWidget().waitingForFilteringResponse - || getWidget().popupOpenerClicked) { - String newSelectedOptionKey = suggestion.getOptionKey(); - if (!newSelectedOptionKey - .equals(getWidget().selectedOptionKey) - || suggestion.getReplacementString().equals( - getWidget().tb.getText())) { - // 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 - getWidget().setPromptingOff( - suggestion.getReplacementString()); - getWidget().selectedOptionKey = newSelectedOptionKey; - } - } - getWidget().currentSuggestion = suggestion; - getWidget().setSelectedItemIcon(suggestion.getIconUri()); + newSuggestions.add(suggestion); + } + + // only close the popup if the suggestions list has actually changed + boolean suggestionsChanged = !getWidget().initDone + || !newSuggestions.equals(getWidget().currentSuggestions); + + if (suggestionsChanged) { + getWidget().currentSuggestions.clear(); + + if (!getWidget().waitingForFilteringResponse) { + /* + * Clear the current suggestions as the server response always + * includes the new ones. Exception is when filtering, then we + * need to retain the value if the user does not select any of + * the options matching the filter. + */ + getWidget().currentSuggestion = null; + /* + * Also ensure no old items in menu. Unless cleared the old + * values may cause odd effects on blur events. Suggestions in + * menu might not necessary exist in select at all anymore. + */ + getWidget().suggestionPopup.menu.clearItems(); + + } + + for (FilterSelectSuggestion suggestion : newSuggestions) { + getWidget().currentSuggestions.add(suggestion); } } - if ((!getWidget().waitingForFilteringResponse || getWidget().popupOpenerClicked) - && uidl.hasVariable("selected") - && uidl.getStringArrayVariable("selected").length == 0) { - // select nulled - if (!getWidget().waitingForFilteringResponse - || !getWidget().popupOpenerClicked) { - if (!getWidget().focused) { - /* - * client.updateComponent overwrites all styles so we must - * ALWAYS set the prompting style at this point, even though - * we think it has been set already... - */ - getWidget().prompting = false; - getWidget().setPromptingOn(); - } else { - // we have focus in field, prompting can't be set on, - // instead just clear the input - getWidget().tb.setValue(""); - } + // handle selection (null or a single value) + if (uidl.hasVariable("selected")) { + String[] selectedKeys = uidl.getStringArrayVariable("selected"); + if (selectedKeys.length > 0) { + performSelection(selectedKeys[0]); + } else { + resetSelection(); } - getWidget().setSelectedItemIcon(null); - getWidget().selectedOptionKey = null; } if (getWidget().waitingForFilteringResponse @@ -229,6 +211,55 @@ public class ComboBoxConnector extends AbstractFieldConnector implements getWidget().initDone = true; } + private void performSelection(String selectedKey) { + // some item selected + for (FilterSelectSuggestion suggestion : getWidget().currentSuggestions) { + String suggestionKey = suggestion.getOptionKey(); + if (suggestionKey.equals(selectedKey)) { + if (!getWidget().waitingForFilteringResponse + || getWidget().popupOpenerClicked) { + if (!suggestionKey.equals(getWidget().selectedOptionKey) + || suggestion.getReplacementString().equals( + getWidget().tb.getText())) { + // 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 + getWidget().setPromptingOff( + suggestion.getReplacementString()); + getWidget().selectedOptionKey = suggestionKey; + } + } + getWidget().currentSuggestion = suggestion; + getWidget().setSelectedItemIcon(suggestion.getIconUri()); + // only a single item can be selected + break; + } + } + } + + private void resetSelection() { + if (!getWidget().waitingForFilteringResponse + || getWidget().popupOpenerClicked) { + // select nulled + if (!getWidget().focused) { + /* + * client.updateComponent overwrites all styles so we must + * ALWAYS set the prompting style at this point, even though we + * think it has been set already... + */ + getWidget().prompting = false; + getWidget().setPromptingOn(); + } else { + // we have focus in field, prompting can't be set on, instead + // just clear the input + getWidget().tb.setValue(""); + } + getWidget().setSelectedItemIcon(null); + getWidget().selectedOptionKey = null; + } + } + @Override public VFilterSelect getWidget() { return (VFilterSelect) super.getWidget(); |