A major issue in AJAX applications is that as they run in a single web page, bookmarking the application URL (or more generally the URI) can only bookmark the application, not an application state. This is a problem for many applications such as product catalogs and forums, in which it would be good to provide links to specific products or messages. Consequently, as browsers remember the browsing history by URI, the history and the button do not normally work. The solution is to use the fragment part of the URI, which is separated from the primary part (address + path + optional query parameters) of the URI with the hash (#) character. For example:
http://example.com/path#myfragment
The exact syntax of the fragment part is defined in RFC 3986 (Internet standard STD 66) that defines the URI syntax. A fragment may only contain the regular URI path characters (see the standard) and additionally the slash and the question mark.
The UriFragmentUtility
is a special-purpose component
that manages the URI fragment; it allows setting the fragment and to handle
user-made changes to it. As it is a regular component, though invisible, you
must add it to a layout in an application window with the
addComponent()
, as usual.
public void init() { Window main = new Window("URI Fragment Example"); setMainWindow(main); // Create the URI fragment utility final UriFragmentUtility urifu = new UriFragmentUtility(); main.addComponent(urifu);
Notice that the utility component can work only when it is attached to the
window, so in practice it must be added in the init()
method of the application and must afterwards always remain in the
application's user interface.
You can set the URI fragment with the setFragment()
method of the UriFragmentUtility
object. The method takes the
fragment as a string parameter. In the following example, we have a menu, from
which the user can select the URI fragment.
// Application state menu final ListSelect menu = new ListSelect("Select a URI Fragment"); menu.addItem("mercury"); menu.addItem("venus"); menu.addItem("earth"); menu.addItem("mars"); menu.setImmediate(true); main.addComponent(menu); // Set the URI Fragment when menu selection changes menu.addListener(new Property.ValueChangeListener() { public void valueChange(ValueChangeEvent event) { String itemid = (String) event.getProperty().getValue(); urifu.setFragment(itemid); } });
The URI fragment and any changes to it are passed to an application as
FragmentChangedEvent
s, which you can handle with a
FragmentChangedListener
. You can get the new fragment
value with the getFragment()
method from the URI
fragment utility component.
// When the URI fragment is given, use it to set menu selection urifu.addListener(new FragmentChangedListener() { public void fragmentChanged(FragmentChangedEvent source) { String fragment = source.getUriFragmentUtility().getFragment(); if (fragment != null) menu.setValue(fragment); } });
Figure 12.10, “Application State Management with URI Fragment Utility” shows an application that allows specifying the menu selection with a URI fragment and correspondingly sets the fragment when the user selects a menu item, as done in the code examples above.