Accessint GWT's HIstory Stack

330 views
Skip to first unread message

Lars

unread,
Feb 27, 2012, 1:14:19 PM2/27/12
to google-we...@googlegroups.com
Been searching for an answer to the following problem.... I have an application with 2 Places: "Index" and "Edit" each have representative tokens that carry state information.

My desire:
I want for the user to be able to return to the last "Index" state after many possible "Edit" states, so say these tokens are on the history stack:
1. INDEX:--23--pg1
2. INDEX:--23--pg2
(user sees the document they want to edit and thus enter EDIT place)
3. EDIT:--docFOO
(see anther document from a widget in the EDIT place)
4. EDIT:--docBAR
(and another)
5. EDIT:--docBING

Now arrives the problem... I want the user to be able to go back to the last INDEX state. Right now my solution is to carry the token (in this example "INDEX:--23--pg2") around on the query string as part of the EDIT token. What I don't like about this solution is that if the user bookmarks a particular EDIT token the INDEX token that is part of the EDIT token gets bookmarked as well obviously, and i cannot tell whether the user really came from that INDEX state or not.

Preferred solution: Search the History stack for the last INDEX token.

Alternative solution: Use a cookie with a fairly short expiration time to store the last INDEX token.

Thoughts? Is there a way to loop through the History stack to find particular tokens?

Thanks in advance.

Ovidiu Mihaescu

unread,
Feb 27, 2012, 2:07:47 PM2/27/12
to google-we...@googlegroups.com
Add your own valueChangeHandler that keeps track of the last Index state:

class LastIndexTracker implements ValueChangeHandler<String> {
   Index lastIndex;

   ...
   void onValueChange(ValueChangeEvent<String> event) {
       if (isIndexToken(...)) {
         lastIndex = ....;
       }
   }

   Index getLastIndex() {
      return lastIndex;
   }
}




--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-web-toolkit/-/qq1ghGpQ6oIJ.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Lars

unread,
Feb 27, 2012, 2:54:39 PM2/27/12
to google-we...@googlegroups.com
I like the idea, but I'm finding that the value change event only fires when prefix portion of the token changes.

It does NOT fire when the token changes from:
#INDEX:----/2///$///////
to
#INDEX:----/3///$///////

But it DOES fire when it changes from:
#INDEX:----/2///$///////
to
#EDIT:----FOO

This makes it impossible to keep track of the last INDEX place the user was on this way... I suppose I could track it in the constructor of the INDEX place activity... i.e. make a call to your hypothetical LastIndexTracker class in the Index place activity's constructor...

Thanks for your reply... By the way, am I right that the value change event only fires this way?

Jens

unread,
Feb 27, 2012, 5:38:31 PM2/27/12
to google-we...@googlegroups.com
I like the idea, but I'm finding that the value change event only fires when prefix portion of the token changes.

Thanks for your reply... By the way, am I right that the value change event only fires this way?

History.addValueChangeHandler() always fires a ValueChangeEvent if the history stack changes. Otherwise it wouldn't be possible to switch between places of the same type but with different internal state (e.g. #DetailsPlace:1 and #DetailsPlace:2).

Honestly I wouldn't skip any history tokens when a user hits the back button. When the user edits 3 documents in a row then he maybe wants to switch between them back and forth for some reason. I found it more natural if I would have to hit 3 times the back button to be back at the INDEX place if I have navigated to three different documents. Thats what you would expect from normal web navigation. 
In addition your app can provide a link like "back to index view" so that the user can directly jump back to the INDEX place if I really wants to.

-- J.

Lars

unread,
Feb 29, 2012, 12:59:30 PM2/29/12
to google-we...@googlegroups.com
Thanks for your input.

Regarding History object and the firing of ValueChangeEvents... I've confirmed that the events are not being fired with this:

   
    History.addValueChangeHandler(new ValueChangeHandler<String>() {

      @Override
      public void onValueChange(ValueChangeEvent<String> event) {
        Window.alert("history changed");
      }
     
    });

I am wondering if the use of Places and the MVP framework has something to do with this... The way navigation works in my app is via "clientFactory.getPlaceController().goTo(place);" and if the user stays within the same "Place" (ie same token prefix) no event is fired. However, I am able to detect the user navigation via:

    eventBus.addHandler(PlaceChangeRequestEvent.TYPE, new PlaceChangeRequestEvent.Handler() {

      @Override
      public void onPlaceChangeRequest(PlaceChangeRequestEvent event) {
        Window.alert("new place requested");
       
      }
     
    });

And since what I'm really after is the user navigation not the tokens themselves, this is sufficient for me... Why I'm not getting the ValueChangeEvents from the History object is a mystery to me...

Jens

unread,
Feb 29, 2012, 3:21:18 PM2/29/12
to google-we...@googlegroups.com
Regarding History object and the firing of ValueChangeEvents... I've confirmed that the events are not being fired with this:

    History.addValueChangeHandler(new ValueChangeHandler<String>() {

      @Override
      public void onValueChange(ValueChangeEvent<String> event) {
        Window.alert("history changed");
      }
     
    });


A fresh GWT 2.4 app only containing the following code will always fire a ValueChangeEvent whenever the history stack changes (not tested in IE):

@Override
public void onModuleLoad() {
  History.addValueChangeHandler(new ValueChangeHandler<String>() {
      @Override
      public void onValueChange(final ValueChangeEvent<String> event) {
        RootPanel.get().add(new Label("History changed: " + event.getValue()));
      }
  });
  History.fireCurrentHistoryState();
}


So I am not quite sure how I could make it not work :) I guess it only stops working if the browser does not fire the corresponding native event but that would be a browser issue.



I am wondering if the use of Places and the MVP framework has something to do with this... The way navigation works in my app is via "clientFactory.getPlaceController().goTo(place);" and if the user stays within the same "Place" (ie same token prefix) no event is fired. However, I am able to detect the user navigation via:

    eventBus.addHandler(PlaceChangeRequestEvent.TYPE, new PlaceChangeRequestEvent.Handler() {

      @Override
      public void onPlaceChangeRequest(PlaceChangeRequestEvent event) {
        Window.alert("new place requested");
       
      }
     
    });

PlaceController doesn't do any magic. It knows the current place and does an equals() check with the provided place you want to go to. If the current place and the new place are equal() nothing will happen. If they are not equal() a PlaceChangeRequestEvent will be fired and (unless the user denies it by choosing cancel in the confirmation dialog that appears if any activity returns a warning in Activity.mayStop()) a PlaceChangeEvent will be fired just after it. So you generally should always see both events. Take a look at the source code of PlaceController... its really easy to understand whats going on.

As your problem is somehow dependent on your place token, have you already checked your PlaceTokenizers if they work correctly? You could also activate GWT logging to see some log statements from PlaceController (http://code.google.com/intl/de-DE/webtoolkit/doc/latest/DevGuideLogging.html#Super_Simple_Recipe_for_Adding_Logging)

-- J.
Reply all
Reply to author
Forward
0 new messages