aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenri Sara <hesara@vaadin.com>2015-11-11 10:50:11 +0200
committerHenri Sara <hesara@vaadin.com>2016-01-15 14:42:58 +0200
commitdbe6b5b266571f223bffd0354dbce651a5650411 (patch)
tree749277336c3db2dc1d00cc1dd33136385147de8e
parentdca930baca68ec965407b7ab113eb0ef674452b5 (diff)
downloadvaadin-framework-dbe6b5b266571f223bffd0354dbce651a5650411.tar.gz
vaadin-framework-dbe6b5b266571f223bffd0354dbce651a5650411.zip
Use a separate data received handler in VFilterSelect (#19929)
Move parts of the request handling to a separate handler class that keeps track of the current communication state etc. This is an intermediate change. Later changes should move waitingForFilteringResponse etc. to the handler. Change-Id: I762d15cc4b54ead3003e6d9d913e2a975256644c
-rw-r--r--client/src/com/vaadin/client/ui/VFilterSelect.java181
-rw-r--r--client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java94
2 files changed, 156 insertions, 119 deletions
diff --git a/client/src/com/vaadin/client/ui/VFilterSelect.java b/client/src/com/vaadin/client/ui/VFilterSelect.java
index 888c66bb87..525e5b3432 100644
--- a/client/src/com/vaadin/client/ui/VFilterSelect.java
+++ b/client/src/com/vaadin/client/ui/VFilterSelect.java
@@ -925,7 +925,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
/**
* Send the current selection to the server. Triggered when a selection
- * is made or on a blur event.
+ * is made with the ENTER key.
*/
public void doSelectedItemAction() {
debug("VFS.SM: doSelectedItemAction()");
@@ -946,22 +946,30 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
return;
}
- setUpdateSelectionWhenReponseIsReceived(isWaitingForFilteringResponse());
- if (!isWaitingForFilteringResponse()) {
+ doPostFilterWhenReady();
+ }
+
+ /**
+ * Perform the post-filter action either now (if not waiting for a
+ * server response) or when a response is received.
+ */
+ private void doPostFilterWhenReady() {
+ if (isWaitingForFilteringResponse()) {
+ dataReceivedHandler.setUpdateOnDataReceived(true);
+ } else {
+ dataReceivedHandler.setUpdateOnDataReceived(false);
doPostFilterSelectedItemAction();
}
}
/**
- * Triggered after a selection has been made
+ * Triggered after a selection has been made.
*/
public void doPostFilterSelectedItemAction() {
debug("VFS.SM: doPostFilterSelectedItemAction()");
final MenuItem item = getSelectedItem();
final String enteredItemValue = tb.getText();
- setUpdateSelectionWhenReponseIsReceived(false);
-
// check for exact match in menu
int p = getItems().size();
if (p > 0) {
@@ -1163,6 +1171,128 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
}
+ /**
+ * Handler receiving notifications from the connector and updating the
+ * widget state accordingly.
+ *
+ * This class is still subject to change and should not be considered as
+ * public stable API.
+ *
+ * @since
+ */
+ public class DataReceivedHandler {
+
+ private Runnable navigationCallback = null;
+ /**
+ * 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
+ * <p>
+ * For internal use only. May be removed or replaced in the future.
+ */
+ private boolean popupOpenerClicked = false;
+ private boolean updateOnDataReceived = false;
+
+ /**
+ * Called by the connector when new data for the last requested filter
+ * is received from the server.
+ */
+ public void dataReceived() {
+ suggestionPopup.showSuggestions(currentSuggestions, currentPage,
+ totalMatches);
+
+ setWaitingForFilteringResponse(false);
+
+ if (!popupOpenerClicked) {
+ navigateItemAfterPageChange();
+ }
+
+ if (updateOnDataReceived) {
+ updateOnDataReceived = false;
+ suggestionPopup.menu.doPostFilterSelectedItemAction();
+ }
+
+ popupOpenerClicked = false;
+ }
+
+ /*
+ * This method navigates to the proper item in the combobox page. This
+ * should be executed after setSuggestions() method which is called from
+ * vFilterSelect.showSuggestions(). ShowSuggestions() method builds the
+ * page content. As far as setSuggestions() method is called as
+ * deferred, navigateItemAfterPageChange method should be also be called
+ * as deferred. #11333
+ */
+ private void navigateItemAfterPageChange() {
+ if (navigationCallback != null) {
+ // pageChangeCallback is not reset here but after any server
+ // request in case you are in between two requests both changing
+ // the page back and forth
+
+ // we're paging w/ arrows
+ Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+ @Override
+ public void execute() {
+ if (navigationCallback != null) {
+ navigationCallback.run();
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Called by the connector when any request has been sent to the server,
+ * before waiting for a reply.
+ */
+ public void anyRequestSentToServer() {
+ navigationCallback = null;
+ }
+
+ /**
+ * Set a callback that is invoked when a page change occurs if there
+ * have not been intervening requests to the server. The callback is
+ * reset when any additional request is made to the server.
+ *
+ * @param callback
+ */
+ public void setNavigationCallback(Runnable callback) {
+ navigationCallback = callback;
+ }
+
+ /**
+ * Record that the popup opener has been clicked and the popup should be
+ * opened on the next request.
+ *
+ * This handles the special case where are not filtering yet and the
+ * selected value has changed on the server-side. See #2119. The flag is
+ * cleared on each UIDL reply.
+ */
+ public void popupOpenerClicked() {
+ popupOpenerClicked = true;
+ }
+
+ /**
+ * 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;
+ }
+
+ public void setUpdateOnDataReceived(boolean update) {
+ updateOnDataReceived = update;
+ }
+
+ /**
+ * Called by the connector when it has finished handling any reply from
+ * the server, regardless of what was updated.
+ */
+ public void serverReplyHandled() {
+ popupOpenerClicked = false;
+ }
+ }
+
@Deprecated
public static final FilteringMode FILTERINGMODE_OFF = FilteringMode.OFF;
@Deprecated
@@ -1245,9 +1375,6 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
private boolean waitingForFilteringResponse = false;
/** For internal use only. May be removed or replaced in the future. */
- private boolean updateSelectionWhenReponseIsReceived = false;
-
- /** For internal use only. May be removed or replaced in the future. */
public boolean initDone = false;
/** For internal use only. May be removed or replaced in the future. */
@@ -1313,6 +1440,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
*/
private boolean textInputEnabled = true;
+ private final DataReceivedHandler dataReceivedHandler = new DataReceivedHandler();
+
/**
* Default constructor.
*/
@@ -1587,7 +1716,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
debug("VFS: onSuggestionSelected(" + suggestion.caption + ": "
+ suggestion.key + ")");
}
- setUpdateSelectionWhenReponseIsReceived(false);
+ dataReceivedHandler.setUpdateOnDataReceived(false);
currentSuggestion = suggestion;
String newKey;
@@ -1858,7 +1987,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
private void selectPrevPage() {
if (currentPage > 0) {
filterOptions(currentPage - 1, lastFilter);
- connector.setNavigateAfterPageReceivedCallback(new Runnable() {
+ dataReceivedHandler.setNavigationCallback(new Runnable() {
@Override
public void run() {
suggestionPopup.selectLastItem();
@@ -1873,7 +2002,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
private void selectNextPage() {
if (hasNextPage()) {
filterOptions(currentPage + 1, lastFilter);
- connector.setNavigateAfterPageReceivedCallback(new Runnable() {
+ dataReceivedHandler.setNavigationCallback(new Runnable() {
@Override
public void run() {
suggestionPopup.selectFirstItem();
@@ -1969,7 +2098,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
boolean immediate = focused
|| !connector.hasEventListener(EventId.FOCUS);
filterOptions(-1, "", immediate);
- connector.popupOpenerClicked();
+ dataReceivedHandler.popupOpenerClicked();
lastFilter = "";
}
DOM.eventPreventDefault(DOM.eventGetCurrentEvent());
@@ -2330,29 +2459,13 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
}
/**
- * For internal use only - this method will be removed in the future.
- *
- * This flag should not be set when not waiting for a reply from the server.
- *
- * @return true if the selection should be updated when a server response is
- * received
- */
- public boolean isUpdateSelectionWhenReponseIsReceived() {
- return updateSelectionWhenReponseIsReceived;
- }
-
- /**
- * For internal use only - this method will be removed in the future.
- *
- * This flag should not be set when not waiting for a reply from the server.
+ * Returns a handler receiving notifications from the connector about
+ * communications.
*
- * @param updateSelectionWhenReponseIsReceived
- * true if the selection should be updated when a server response
- * is received
+ * @return the dataReceivedHandler
*/
- public void setUpdateSelectionWhenReponseIsReceived(
- boolean updateSelectionWhenReponseIsReceived) {
- this.updateSelectionWhenReponseIsReceived = updateSelectionWhenReponseIsReceived;
+ public DataReceivedHandler getDataReceivedHandler() {
+ return dataReceivedHandler;
}
}
diff --git a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java
index df6e800893..e367834d1e 100644
--- a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java
+++ b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java
@@ -19,8 +19,6 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.Paintable;
import com.vaadin.client.Profiler;
@@ -54,17 +52,6 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
private boolean immediate;
- private Runnable pageChangeCallback;
-
- /**
- * 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
- * <p>
- * For internal use only. May be removed or replaced in the future.
- */
- private boolean popupOpenerClicked;
-
@Override
protected void init() {
super.init();
@@ -215,31 +202,16 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
}
}
+ // TODO even this condition should probably be moved to the handler
if ((getWidget().isWaitingForFilteringResponse() && getWidget().lastFilter
.toLowerCase().equals(uidl.getStringVariable("filter")))
|| popupOpenAndCleared) {
-
- getWidget().suggestionPopup.showSuggestions(
- getWidget().currentSuggestions, getWidget().currentPage,
- getWidget().totalMatches);
-
- getWidget().setWaitingForFilteringResponse(false);
-
- if (!popupOpenerClicked) {
- navigateItemAfterPageChange();
- }
-
- if (getWidget().isUpdateSelectionWhenReponseIsReceived()) {
- getWidget().suggestionPopup.menu
- .doPostFilterSelectedItemAction();
- }
+ getWidget().getDataReceivedHandler().dataReceived();
}
// Calculate minimum textarea width
getWidget().updateSuggestionPopupMinWidth();
- popupOpenerClicked = false;
-
/*
* if this is our first time we need to recalculate the root width.
*/
@@ -255,32 +227,9 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
}
getWidget().initDone = true;
- }
- /*
- * This method navigates to the proper item in the combobox page. This
- * should be executed after setSuggestions() method which is called from
- * vFilterSelect.showSuggestions(). ShowSuggestions() method builds the page
- * content. As far as setSuggestions() method is called as deferred,
- * navigateItemAfterPageChange method should be also be called as deferred.
- * #11333
- */
- private void navigateItemAfterPageChange() {
- if (pageChangeCallback != null) {
- // pageChangeCallback is not reset here but after any server request
- // in case you are in between two requests both changing the page
- // back and forth
-
- // we're paging w/ arrows
- Scheduler.get().scheduleDeferred(new ScheduledCommand() {
- @Override
- public void execute() {
- if (pageChangeCallback != null) {
- pageChangeCallback.run();
- }
- }
- });
- }
+ // TODO this should perhaps be moved to be a part of dataReceived()
+ getWidget().getDataReceivedHandler().serverReplyHandled();
}
private void performSelection(String selectedKey) {
@@ -291,7 +240,8 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
continue;
}
if (!getWidget().isWaitingForFilteringResponse()
- || popupOpenerClicked) {
+ || getWidget().getDataReceivedHandler()
+ .isPopupOpenerClicked()) {
if (!suggestionKey.equals(getWidget().selectedOptionKey)
|| suggestion.getReplacementString().equals(
getWidget().tb.getText())
@@ -320,7 +270,8 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
}
private void resetSelection() {
- if (!getWidget().isWaitingForFilteringResponse() || popupOpenerClicked) {
+ if (!getWidget().isWaitingForFilteringResponse()
+ || getWidget().getDataReceivedHandler().isPopupOpenerClicked()) {
// select nulled
if (!getWidget().focused) {
/*
@@ -478,19 +429,6 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
}
}
- /**
- * Set a callback that is invoked when a page change occurs if there have
- * not been intervening requests to the server. The callback is reset when
- * any additional request is made to the server.
- *
- * @since
- * @param callback
- */
- public void setNavigateAfterPageReceivedCallback(Runnable callback) {
- pageChangeCallback = callback;
-
- }
-
/*
* Anything that should be set after the client updates the server.
*/
@@ -498,21 +436,7 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
// We need this here to be consistent with the all the calls.
// Then set your specific selection type only after
// a server request method call.
- pageChangeCallback = null;
- }
-
- /**
- * Record that the popup opener has been clicked and the popup should be
- * opened on the next request.
- *
- * This handles the special case where are not filtering yet and the
- * selected value has changed on the server-side. See #2119. The flag is
- * cleared on each UIDL reply.
- *
- * @since
- */
- public void popupOpenerClicked() {
- popupOpenerClicked = true;
+ getWidget().getDataReceivedHandler().anyRequestSentToServer();
}
}