diff options
author | Henri Sara <hesara@vaadin.com> | 2015-11-11 12:27:03 +0200 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2016-08-08 11:36:35 +0000 |
commit | 7774ca67931f4c947e6b0ac12cbf652c9f76c546 (patch) | |
tree | 05d5875538d146ddcff9e3f8a398ee064de44c3e /client | |
parent | 0b4dba5214b9b55a20763e3384a86cfbb074ead2 (diff) | |
download | vaadin-framework-7774ca67931f4c947e6b0ac12cbf652c9f76c546.tar.gz vaadin-framework-7774ca67931f4c947e6b0ac12cbf652c9f76c546.zip |
Move combo box selection update logic to handler (#19929)
Move logic related to updating the selection to the handler and
VFilterSelect.
Change-Id: I399c1ab2ceaceb1132aabeb11fff4c5ac7bf7ebc
Diffstat (limited to 'client')
-rw-r--r-- | client/src/main/java/com/vaadin/client/ui/VFilterSelect.java | 133 | ||||
-rw-r--r-- | client/src/main/java/com/vaadin/client/ui/combobox/ComboBoxConnector.java | 113 |
2 files changed, 142 insertions, 104 deletions
diff --git a/client/src/main/java/com/vaadin/client/ui/VFilterSelect.java b/client/src/main/java/com/vaadin/client/ui/VFilterSelect.java index bf59b5bf2b..af8d9f782a 100644 --- a/client/src/main/java/com/vaadin/client/ui/VFilterSelect.java +++ b/client/src/main/java/com/vaadin/client/ui/VFilterSelect.java @@ -1488,14 +1488,6 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, } /** - * Returns true if the popup opener has been clicked. This method is for - * internal use only and will most likely be removed in the future. - */ - public boolean isPopupOpenerClicked() { - return popupOpenerClicked; - } - - /** * Cancel a pending request to perform post-filtering actions. */ private void cancelPendingPostFiltering() { @@ -1540,6 +1532,47 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, suggestionPopup.menu.doPostFilterSelectedItemAction(); } } + + /** + * Perform selection (if appropriate) based on a reply from the server. + * When this method is called, the suggestions have been reset if new + * ones (different from the previous list) were received from the + * server. + * + * @param selectedKey + * new selected key or null if none given by the server + * @param selectedCaption + * new selected item caption if sent by the server or null - + * this is used when the selected item is not on the current + * page + * @param oldSuggestionTextMatchTheOldSelection + * true if the old filtering text box contents matched + * exactly the old selection + */ + public void updateSelectionFromServer(String selectedKey, + String selectedCaption, + boolean oldSuggestionTextMatchTheOldSelection) { + // when filtering with empty filter, server sets the selected key + // to "", which we don't select here. Otherwise we won't be able to + // reset back to the item that was selected before filtering + // started. + if (selectedKey != null && !selectedKey.equals("")) { + performSelection(selectedKey, + oldSuggestionTextMatchTheOldSelection, + !isWaitingForFilteringResponse() || popupOpenerClicked); + setSelectedCaption(null); + } else if (!isWaitingForFilteringResponse() + && selectedCaption != null) { + // scrolling to correct page is disabled, caption is passed as a + // special parameter + setSelectedCaption(selectedCaption); + } else { + if (!isWaitingForFilteringResponse() || popupOpenerClicked) { + resetSelection(popupOpenerClicked); + } + } + } + } @Deprecated @@ -2050,6 +2083,90 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, } } + /** + * Perform selection based on a message from the server. + * + * This method is called when the server gave a non-empty selected item key, + * whereas null selection is handled by {@link #resetSelection()} and the + * special case where the selected item is not on the current page is + * handled separately by the caller. + * + * @param selectedKey + * non-empty selected item key + * @param oldSuggestionTextMatchTheOldSelection + * true if the suggestion box text matched the previous selection + * before the message from the server updating the selection + * @param updatePromptAndSelectionIfMatchFound + */ + private void performSelection(String selectedKey, + boolean oldSuggestionTextMatchTheOldSelection, + boolean updatePromptAndSelectionIfMatchFound) { + // some item selected + for (FilterSelectSuggestion suggestion : currentSuggestions) { + String suggestionKey = suggestion.getOptionKey(); + if (!suggestionKey.equals(selectedKey)) { + continue; + } + // at this point, suggestion key matches the new selection key + if (updatePromptAndSelectionIfMatchFound) { + if (!suggestionKey.equals(selectedOptionKey) + || suggestion.getReplacementString().equals( + tb.getText()) + || oldSuggestionTextMatchTheOldSelection) { + // 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 + // OR if selected item caption is changed. + setPromptingOff(suggestion.getReplacementString()); + selectedOptionKey = suggestionKey; + } + } + currentSuggestion = suggestion; + setSelectedItemIcon(suggestion.getIconUri()); + // only a single item can be selected + break; + } + } + + /** + * Reset the selection of the combo box to an empty string if focused, the + * input prompt if not. + * + * This method also clears the current suggestion and the selected option + * key. + */ + private void resetSelection(boolean useSelectedCaption) { + // select nulled + if (!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... + */ + setPromptingOff(""); + if (enabled && !readonly) { + setPromptingOn(); + } + } else { + // we have focus in field, prompting can't be set on, + // instead just clear the input if the value has changed from + // something else to null + if (selectedOptionKey != null + || (allowNewItem && !tb.getValue().isEmpty())) { + if (useSelectedCaption && getSelectedCaption() != null) { + tb.setValue(getSelectedCaption()); + tb.selectAll(); + } else { + tb.setValue(""); + } + } + } + currentSuggestion = null; // #13217 + setSelectedItemIcon(null); + selectedOptionKey = null; + } + private void forceReflow() { WidgetUtil.setStyleTemporarily(tb.getElement(), "zoom", "1"); } diff --git a/client/src/main/java/com/vaadin/client/ui/combobox/ComboBoxConnector.java b/client/src/main/java/com/vaadin/client/ui/combobox/ComboBoxConnector.java index 176d8b87c9..f0c71d76a2 100644 --- a/client/src/main/java/com/vaadin/client/ui/combobox/ComboBoxConnector.java +++ b/client/src/main/java/com/vaadin/client/ui/combobox/ComboBoxConnector.java @@ -47,10 +47,6 @@ public class ComboBoxConnector extends AbstractFieldConnector implements protected FocusAndBlurServerRpc focusAndBlurRpc = RpcProxy.create( FocusAndBlurServerRpc.class, this); - // oldSuggestionTextMatchTheOldSelection is used to detect when it's safe to - // update textbox text by a changed item caption. - private boolean oldSuggestionTextMatchTheOldSelection; - private boolean immediate; @Override @@ -152,10 +148,12 @@ public class ComboBoxConnector extends AbstractFieldConnector implements // popup. Popup needs to be repopulated with suggestions from UIDL. boolean popupOpenAndCleared = false; - oldSuggestionTextMatchTheOldSelection = false; + // oldSuggestionTextMatchTheOldSelection is used to detect when it's + // safe to update textbox text by a changed item caption. + boolean oldSuggestionTextMatchesTheOldSelection = false; if (suggestionsChanged) { - oldSuggestionTextMatchTheOldSelection = isWidgetsCurrentSelectionTextInTextBox(); + oldSuggestionTextMatchesTheOldSelection = isWidgetsCurrentSelectionTextInTextBox(); getWidget().currentSuggestions.clear(); if (!getDataReceivedHandler().isWaitingForFilteringResponse()) { @@ -191,28 +189,21 @@ public class ComboBoxConnector extends AbstractFieldConnector implements // ) { + // single selected key (can be empty string) or empty array for null + // selection String[] selectedKeys = uidl.getStringArrayVariable("selected"); - - // when filtering with empty filter, server sets the selected key - // to "", which we don't select here. Otherwise we won't be able to - // reset back to the item that was selected before filtering - // started. - if (selectedKeys.length > 0 && !selectedKeys[0].equals("")) { - performSelection(selectedKeys[0]); - // if selected key is available, assume caption is know based on - // it as well and clear selected caption - getWidget().setSelectedCaption(null); - - } else if (!getDataReceivedHandler() - .isWaitingForFilteringResponse() - && uidl.hasAttribute("selectedCaption")) { - // scrolling to correct page is disabled, caption is passed as a - // special parameter - getWidget().setSelectedCaption(uidl - .getStringAttribute("selectedCaption")); - } else { - resetSelection(); + String selectedKey = null; + if (selectedKeys.length == 1) { + selectedKey = selectedKeys[0]; } + // selected item caption in case it is not on the current page + String selectedCaption = null; + if (uidl.hasAttribute("selectedCaption")) { + selectedCaption = uidl.getStringAttribute("selectedCaption"); + } + + getDataReceivedHandler().updateSelectionFromServer(selectedKey, + selectedCaption, oldSuggestionTextMatchesTheOldSelection); } // TODO even this condition should probably be moved to the handler @@ -245,82 +236,12 @@ public class ComboBoxConnector extends AbstractFieldConnector implements getDataReceivedHandler().serverReplyHandled(); } - private void performSelection(String selectedKey) { - // some item selected - for (FilterSelectSuggestion suggestion : getWidget().currentSuggestions) { - String suggestionKey = suggestion.getOptionKey(); - if (!suggestionKey.equals(selectedKey)) { - continue; - } - if (!getDataReceivedHandler().isWaitingForFilteringResponse() - || getDataReceivedHandler().isPopupOpenerClicked()) { - if (!suggestionKey.equals(getWidget().selectedOptionKey) - || suggestion.getReplacementString().equals( - getWidget().tb.getText()) - || oldSuggestionTextMatchTheOldSelection) { - // 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 - // OR if selected item caption is changed. - getWidget().setPromptingOff( - suggestion.getReplacementString()); - getWidget().selectedOptionKey = suggestionKey; - } - } - getWidget().currentSuggestion = suggestion; - getWidget().setSelectedItemIcon(suggestion.getIconUri()); - // only a single item can be selected - break; - } - } - private boolean isWidgetsCurrentSelectionTextInTextBox() { return getWidget().currentSuggestion != null && getWidget().currentSuggestion.getReplacementString().equals( getWidget().tb.getText()); } - private void resetSelection() { - if (!getDataReceivedHandler().isWaitingForFilteringResponse() - || getDataReceivedHandler().isPopupOpenerClicked()) { - // 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().setPromptingOff(""); - if (getWidget().enabled && !getWidget().readonly) { - getWidget().setPromptingOn(); - } - } else { - // we have focus in field, prompting can't be set on, instead - // just clear the input if the value has changed from something - // else to null - if (getWidget().selectedOptionKey != null - || (getWidget().allowNewItem - && !getWidget().tb.getValue().isEmpty())) { - - boolean openedPopupWithNonScrollingMode = (getWidget() - .getDataReceivedHandler().isPopupOpenerClicked() && getWidget() - .getSelectedCaption() != null); - if (!openedPopupWithNonScrollingMode) { - getWidget().tb.setValue(""); - } else { - getWidget().tb - .setValue(getWidget().getSelectedCaption()); - getWidget().tb.selectAll(); - } - } - } - getWidget().currentSuggestion = null; // #13217 - getWidget().setSelectedItemIcon(null); - getWidget().selectedOptionKey = null; - } - } - @Override public VFilterSelect getWidget() { return (VFilterSelect) super.getWidget(); |