Google Web Toolkit for Ajax
Authors: Perry B.W
Published year: 2006
Pages: 27-28/29
Buy this book on amazon.com >>

8.14. Finally, The Back Button

The GWT provides a way to restore the functionality of the web browser's back button in an Ajax application. Typically, the state of a single-page Ajax application is not related to the browser's back button.

NOTE

A single-page application is the software version of a one-act play. Since dynamic JavaScript can create web page widgets and change appearances on the fly, the web page, in terms of the physical file that the browser loads from the server, remains the same. The user can log in, manipulate buttons , lists, text fields, and other form elements, and the screen changes accordingly . The XMLHttpRequest object can exchange data invisibly with remote components , but the browser never has to fetch different web page files from the server. The state of the application does change, however, as stored in JavaScript objects and arrays.

In other words, the user changes something in the Ajax application by, say, clicking a button or making a selection-list choice, and he cannot go back to the application's previous state by clicking the browser back button. All he can do is reload the web page and thereby restore the page's initial state.

This is because the Ajax application's state is not associated with a URL in the browser's history list, as it is with conventional web browsing. In the conventional manner, if you surf from the New York Times home page to another web page, for example, the back button will bring the user back to the newspaper's home page. This is not true with the various states of an Ajax application, unless you use GWT's mechanism, which this shortcut introduces for you.



8.15. Teaching History

The GWT uses an iframe tag on the application's HTML page, along with the com.google.gwt. user .client.History class and com.google.gwt.user.client.HistoryListener interface, to provide back-button functionality. This shortcut provides the basics for setting this up in your Ajax application. Here are the steps.

First, make sure the iframe tag is uncommented in your HTML file. As initially generated by the applicationCreator script, as we used in this shortcut, the tag looks like this:

<!-- OPTIONAL: include this if you want history support -->
            <iframe id="__gwt_historyFrame"
style="width:0;height:0;border:0"></iframe>

NOTE

For a brief explanation of how the iframe tag is linked with new history items, see Mark Pruett's Hack #68 in O'Reilly's Ajax Hacks .

Then, create a class that implements the com.google.gwt.user.client.HistoryListener interface, or just have your entry-point class implement the interface. This means that any class implementing the interface, such as my GwtAjax.java class, must define the onHistoryChanged(String string) method.

For example, the code in the demo application can initialize the history or back-button mechanism in the GwtAjax.java class' onModuleLoad() method, as GWT's documentation suggests. Here is the code.

//Set up History or back button functionality
//History.getToken() returns any token appended to the
//page's URL following a hash mark, as in /GwtAjax.html#mytoken
String initialState = History.getToken();
if (initialState.length() == 0)
  initialState = "initialState";

// Call onHistoryChanged() to reflect the initial state,
//Since the GWT does not automatically call this method
//when the browser first loads the Ajax application.
onHistoryChanged(initialState);
// Make this class a history listener
History.addHistoryListener(this);

Our application includes code that adds new items to the browser's list of visited URLs or "history stack." The History.newItem(String item) method adds a URL to the history stack, thus causing the browser to enable the back button.

History.newItem(new Date(timeBox.getText()).getTime()+"");

The newItem() method appends a hash mark, or fragment identifier , and a token to the end of the current URL. So the method call History.newItem("nextState") would generate a URL such as:

http://bwpmacmini.local/~bruceperry/ajax/com.parkerriver.gwt.intro.GwtAjax/GwtAjax.htm
l#nextState

The newItem() method also causes the application to call onHistoryChanged() .

The code distinguishes between the different URLs stored in the history stack by examining the associated token (the hash mark and string at the end of the URL). The string passed into the onHistoryChanged() method represents the current token. Therefore, when the user clicks the back button, your implementation of onHistoryChanged() can examine the token and then, for instance, recreate the state associated with that segment of the history list. All the demo application does is display the current token in a purple label on the page. (See Figure 12.)

public void onHistoryChanged(String string) {
 RpcStatus stat = new RpcStatus();
 stat.setStatusDivId("err_message");
 stat.showStatus(true, "token: "+string, "purple");
}

The application generates a unique token by taking the value of a text field that displays a date and time, and converting that date to a number by calling the java.util.Date.getTime() function. Figure 12 shows what the screen looks like in Firefox, including the frame showing a new list of history items, after the user has created a few new items.

History.newItem(new Date(timeBox.getText()).getTime()+"");

Figure 8-7. Navigating with a back button through a GWT application

Each time the user clicks the "Request Info" button, the code displays the fetched server data in the text fields, creates a new token by using the second field's content, calls History.newItem() with the new token as an argument, and finally, displays the new value in the purple label. The result is that a new URL with the token appended at the end of it (i.e., #1163441320000) is added to the top of the history stack.

The nice thing is that GWT pays attention to when the user clicks the back or forward button, calling your onHistoryChanged() method accordingly .

The demo application's history- related code is, well, a demonstration. A real-world application probably wants to recreate at least a part of the application's state if the user chooses a new item on the history list. For example, your application could use the token as a key in a HashMap . Each HashMap value represents the cached state linked to the key, such as TextBox or TextArea content. Whenever the user clicks the back or forward button to reproduce a saved state, the application could check the token, get the associated value in the Map , then restore the TextBox's or TextArea's content.


Google Web Toolkit for Ajax
Authors: Perry B.W
Published year: 2006
Pages: 27-28/29
Buy this book on amazon.com >>

Similar books on Amazon