# Tuesday, June 30, 2009

Ajax History - a how to - Part 1

Part 1 - Introduction
Part 2 - Basic Example
Part 3 - Complex Example
Part 4 - Final Notes
Bonus - Ajax History and the Memento Pattern
Extra Bonus - Issues with Opera

One of the most exciting prospects with .net 3.5 is the ability to handle Ajax History.

Ajax, for those of you who may be only vaguely familiar, is a way to do partial postbacks of web pages. This allows you to modify only a portion of the screen rather than updating the entire transaction. This increases the potential speed exponentially. One form are CallBacks, another used by the UpdatePanel is a full PostBack but only a redrawing of the appropriate sections of the page.

However, there are three main problems with Ajax when using controls like the UpdatePanel:

  1. Hitting the “Back” button loads the page that was loaded BEFORE the ajax page
  2. Refreshing the page has the effect of losing whatever Ajax calls have been made (ie the page itself is reloaded from the start).
  3. There is no effective method to ‘link’ to the page resulting from ajax calls. All links lose any Ajax calls because the URL does not display the necessary information to recreate the page at the appropriate place.

All of these can be resolved (as we shall see) by using Ajax History.

This first blog entry will lay out the problems in greater detail and the general means by which Ajax History resolves them. Later entries will go more into detail on how to do Ajax History (yes, there is some additional work, but not very much).

Hitting the “Back” button loads the page that was loaded BEFORE the ajax page

The issue here is caused by two factors:

  1. The "Back" button loads the last entry in url history
  2. Ajax does not automatically change the url history

An example of what I am talking about can be seen in my (non-artistic) image below.

Hitting the "Back" button after doing regular Postbacks will take you to the most recent page of information. However, hitting the "Back" button after doing CallBacks takes you all the way back to the page that was loaded BEFORE you even got to the Ajax page.

The reason for this lies in the way that the href property of the Html Document Object Model is handled. By default whenever a full PostBack occurs or a modification to the hash in the URI (such as an internal link), the URI of the new entry is stored in the location history. This is handled by the browser behind the scenes and has been since the early days. However, since Ajax calls are not full PostBacks the browser mechanism does not, by default, record their entry.

To get around this, a rather ingenious method is used. Because modifications to the URI’s hash portion is included in the history but DOES NOT require full PostBack (think internal anchor links) .net 3.5 writes to the hash portion of the page to trigger the entry being recorded, by the browser, in the href history. Pretty slick, hunh?

For those of you unfamiliar with the hash concept of the URI, consider the following quick example:

<html>
<head></head>
<body>
<a name=’Up’></a>
<a href=’upsidedown.html#Down’>Go Down</a>
<p>&nbsp;</p>
<a name=’Down’></a>
<a href=’upsidedown.html#Up’>Go Up</a>
</body>
</html>

I have posted this basic page to my site. Note that there are anchor tags (<a…) that have names and others that have a hash sign (#) in them that refer to that name. These are commonly used to enable users to just to a particular portion of the page without having to scroll and are known as Internal Links (because they link to an internal portion of the page and not to an external page).

When the page first loads you can see that the URI is simply http://www.myfriedmind.com/updown.html. There is one link visible (the other would be visible if you scrolled but I shrunk the browser window to give an idea of what internal links are generally used for.

Once the link is clicked it moves the page down to where the “named” anchor is. In other words, clicking on the anchor tag that references #Down (<a href=’upsidedown.html#Down’>Go Down</a>) moves the page to the anchor that contains the name that matches the one after the hash sign – so you are moved WITHIN the page (to <a name=’Down’></a>). This is very important – note that the URI has changed, it is now showing the hash. Also critical to note is that THE PAGE DID NOT POSTBACK!

Clicking on the link that has the hash entry for Up (<a href=’upsidedown.html#Up’>Go Up</a>) results in moving to the anchor tag that has the name (Up) that matches what was after the hash mark. Again, the URI is updated to a new hash display and THE PAGE DID NOT POSTBACK!!!

It is critical that you understand that when this takes place the browser records the change in its href history. In other words, modifications to the hash are RECORDED in the browser’s href history. Thus hitting the “Back” button means that we move back to the previous entry, which is NOT http://www.myfriedmind.com/updown.html, but http://www.myfriedmind.com/updown.html#Down (see below)

Thus the elegant solution – to store Ajax postbacks, record the entries in the hash of the URI (like you are doing an internal link) and the updated URI will be recorded in the browser history for you. Any clicks on the “Back” button will load the previous entry. See the basic example below. Note that the change after CallBack to the URL (adding a hash entry).

I must note here that the adding to the hash is not automatic. You do need to do code but very, very little. Your code mostly deals with how to effectively package the info and unpackage when required. If you are curious take a looksee at my (fascinating) blog on how this is similar to the Memento pattern ->  http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx.

Once you grasp this concept – that the Ajax History is stored in the URI’s hash, the solutions to both of problems #2 and #3 (page refresh and linking) are resolved.

  • Refreshing  the page refreshes the URI, INCLUDING the hash. Thus the page that gets returned is the page that has had the Ajax modifications done
  • Sending a link to this page, INCLUDES the URI’s hash, and thus the page will be able to return the point in its Ajax modifications that a person wants

There are a number of very useful examples of how this is used today (Ajax History is not new with 3.5 but it DOES make it a whole lot simpler). The most commonly used are mapping websites. One can hunt around (using Ajax) until one gets to the exact display one desires and then save/send/whatever that display. Without the hash entry one would always end up at the very beginning and the desired display would be lost. I can use bing to zoom into the street view of Dunn Bros (the BEST coffee) by my old alma mater in Saint Paul and shoot that url to a friend.( shortened for display - http://www.bing.com/maps/#JnE9eX...zMTI1)

But this is not limited to mapping sites. Imagine that you have a Ajax based site that enables users to filter/sort/etc on a GridView display customer accounts. “Ah ha,” says the manager (they say things like that when no one is listening) “this is precisely the display I am looking for. I will just save it into my favorites. And I will also email it to the big boss.” Without the hash they would be exceedingly frustrated as would the big boss. With proper Ajax history coding the sun shines, the wind blows, and gas prices drop. Everyone is happy.

;)

Next blog: What exactly is involved in doing Ajax History, the concepts….

Comments are closed.