RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Restoring Conventional Browser Navigation to AJAX Applications : Page 2

Find out how to give AJAX applications better browser navigation functionality and allow users to set bookmarks.

Enter the URL Hash
A URL hash is the portion of a URL that follows a number sign (#). URL hashes usually refer to specific locations within a page rather than to some other page, so they're typically used in links to let users move easily to specific locations within long pages. But you don't have to use them that way. Instead, you can use URL hashes to store information about the DOM manipulations in AJAX applications—essentially giving each AJAX request a unique URL.

URL hashes have two huge built-in advantages for creating AJAX history. The first is that changing the hash in the current URL won't trigger a page reload, which provides a way to create a unique URL without changing pages. The second is that browsers already treat URL hashes as part of the page history; in other words, navigating to a URL hash adds an entry to the browser's history list. If you add a distinct entry to the current URL after a hash mark, you can create a historical trail useful for re-enabling standard backward and forward navigation and bookmarking capability in AJAX applications. For example, you might use these URL hashes to refer to the two result pages in the search application:

The preceding URL hashes (the page=1 and page=2 portions) refer to the search page the user is currently viewing.

Really Simple History (RSH)
Several frameworks are targeting the AJAX UI issues to try to maintain the browser's default behavior in AJAX-based applications. The Really Simple History (RSH) framework is one example. This simple framework consists of two open source JavaScript classes, DhtmlHistory and HistoryStorage. These two classes make it possible for AJAX applications to support bookmarking and the Back and Forward buttons.

The DhtmlHistory class provides a history abstraction for AJAX applications. AJAX pages use the add() method to add history events to the browser, specifying new locations and associated history data. The DhtmlHistory class updates the browser's current URL using an anchor hash, such as #new-location, and associates history data with this new URL. AJAX applications register themselves as history listeners; as the user navigates with the Back and Forward buttons, the browser fires history events that provide the browser's new location and any history data that was persisted with an add() call.

The second class, HistoryStorage, gives developers a way to store an arbitrary amount of history data. In normal web pages when a user navigates to a new web site, the browser unloads and clears out all application and JavaScript state on the web page it's leaving; if the user later returns to that page using the Back button, all the data is lost. The HistoryStorage class solves this problem by exposing an API containing simple hash table methods such as put(), get(), and hasKey(). Developers can use these methods to store an arbitrary amount of data that persists even after a user has left a web page. If the user later returns by clicking the Back button, code in the page can access the stored data through the HistoryStorage class. Internally, the data storage can be achieved by using a hidden form field, taking advantage of the fact that browsers autosave form field values even after a user has left the page.

Dojo to the Rescue
Dojo provides another possible solution to the AJAX navigational issues, allowing web applications to capture Back and Forward button clicks, and set a unique URL in the browser's location field for bookmarking.

Dojo is an Open Source DHTML toolkit written in JavaScript that gives you an easy way to build dynamic capabilities into web pages (or other environments that support JavaScript). You can use Dojo's components to make web sites more usable, responsive, and functional. With Dojo you can build complex user interfaces easily, prototype interactive widgets quickly, and animate transitions. Dojo's low-level APIs and compatibility layers promote writing portable JavaScript and simplify complex scripts, while its event system, I/O APIs, and generic language enhancement form the basis of a powerful programming environment.

The included dojo.undo.browser module provides access to the browser history, making it possible for users to click Back and Forward without leaving your AJAX application. The toolkit fires callback messages when Back and Forward events occur, giving developers an opportunity to update the web application appropriately. Dojo generates browser history by using a hidden IFRAME and/or by adding a unique value to the hash portion of the page URL.

Remember that changing the application state identifier in the form of a URL hash does not cause the page to refresh, so URL hashes are ideal for maintaining application state. The Dojo-generated unique hash values already support bookmarking, but you can specify more meaningful values for the application state identifier to improve bookmark readability. The Dojo state object represents the state of the page. This state object gets callbacks when users click the Back or Forward buttons. In addition to registering state objects with dojo.undo.browser directly, you can pass the state object to dojo.io.bind(), which will bind the events for you.

Configuring Dojo
To use dojo.undo.browser:

  • Define the preventBackButtonFix property as false in djConfig. This property allows Dojo to add a hidden IFRAME to the current page via a document.write() command. If you do not do this, dojo.undo.browser will not work correctly.
  • Add the appropriate require statement: dojo.require("dojo.undo.browser");
  • Register the initial state of the page by calling dojo.undo.browser.setInitialState(state); In that code, state is the state object that will be notified when the user clicks Back—all the way back to the start of the web application. (If users click Back once more, the browser navigates to the page that preceded the application, if any.)
The state object should have the following functions defined:

  • For receiving Back notifications: back(), backButton(), or handle(type), where type is the string "back."
  • For receiving Forward notifications: forward(), forwardButton(), or handle(type), where type is the string "forward."
Here's an example of a very simple state object:

   var state = {   
      back: function() { 
         alert("Back was clicked!"); 
      forward: function() { 
         alert("Forward was clicked!"); 
To register a state object that represents the result of a user action, use the following call:

Alternatively, if you are using dojo.io.bind(), and the state object contains the function back() or backButton(), or the property changeUrl, then dojo.io.bind() will handle the calls to dojo.undo.browser for you (this only works with XMLHTTPTransport and ScriptSrcTransport).

To change the URL in the browser's location bar, include a changeUrl property on the state object. If this property is set to true, dojo.undo.browser will generate a unique value for the fragment identifier. If it is set to any other value (except undefined, null, zero, or an empty string), then that value will be used as the fragment identifier. In other words, developers can let Dojo pick a hash value or set a custom hash value. In either case, this feature lets users bookmark the page in such a way that code can rebuild the current page state.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date