views:

713

answers:

1

I have a page called Orders and a page called OrderDetails. As described in the excellent MVP tutorial I'm working with History (with a central ValueChangeListener) and an "event bus" HandlerManager.

I have a handler registered for the event that someone clicks on an order, which basically creates the OrderDetailPresenter, passes in the order ID (which is contained in the ShowOrderDetailEvent), and then calls History.newItem("orderDetails").

This has a couple major disadvantages: This newly created History step does NOT know which order ID was passed in. So for example, if someone bookmarks the order details page (or goes back then forward in their browser), they'll get an empty page with no order details.

So my question is: Should I instead do something like History.newItem("orderDetails?id="+id), and then parse the history token in my value change listener? If so, is there a best practice, an API, or library for parsing and formatting arguments into a string in this way?

+4  A: 

Yes, that's what you should do. There is, so far as I know, no library for making this easier.

A bit of advice, though: if at all possible, you should avoid using a scheme that requires you to use percent escapes in your history item string. The reason is that what location.hash returns when location.href ends in, say #%3C@%40 varies from browser to browser. For example, Chrome returns #%3C@%40; Firefox returns #<@@. Setting location.hash can have similar browser-specific effects.

GWT's History token mechanism relies on location.hash and doesn't normalize this difference in browser behavior. The end result is that if you use something that requires percent escapes, you will get urls that can't be shared across browsers - this is an issue if on some other page you want to generate links that jump to a particular spot within your GWT app, or if you expect users to share URLs that link to within your GWT app. (or when your user installs Chrome, imports their bookmarks from Firefox that pointed to particular spots inside your webapp, and suddenly the bookmarks don't work as they did before)

For paranoia, I'd avoid putting any ?, #, &, %, <, or > characters in your history token string. However, strings like orderDetails/oid=12313378 should be fine, and cross-browser.

(Edited to clarify that the issue I'm talking about is dealing with having identical URLs work in multiple different browsers, not of having the history token method work at all in each of the various browsers)

Daniel Martin
Actually GWT DOES take into account the differences in browsers. It even works around a number of different issues not mentioned here. So you can use any of the mentioned characters. If you want to check this, just take a look at `com.google.gwt.user.client.impl.HistoryImpl<browser.agent>` classes in the `gwt-user.jar`(gwt 2.0) file. And it also does the de/encoding so you can pass in the `@` and it will take care of it.
Hilbrand
Sounds great. I did notice that GMail does exactly this as well, if I click on a label for example, then the URL changes to "...#inbox/labelname". They URL encode the label name, however, so I'm doing the same with URL.encode and URL.decode.
Epaga
Just to be complete. If you use `History.newItem(..)` you should not decode/encode, because GWT already does this for you. In fact if you do it, it could lead to the problems mentioned about Firefox.
Hilbrand
Ah, good to know. Thanks Hilbrand.
Epaga
Hilbrand: I'll admit that that's the theory, but I'll also note that we've found a great deal of pain in dealing with url encoding in history tokens in GWT. To be fair, I think it was always consistent when staying within a single browser but one of the things we wanted to do was generate hyperlinks to specific parts of our application that could be used by any browser. This we couldn't do consistently - links that worked in Chrome wouldn't work in Firefox and vice versa. We eventually just changed our encoding scheme to steer far away from anything that might end up URL encoded.
Daniel Martin