Monday, December 15, 2008

Browser History Back Button - History/Remote Plugin

This particular solution applies to the cases when we want to stop any visible page refreshes as the user browses through the website. What we are trying to do basically is to load a new page as the user clicks on a link (navigates via a link) without refreshing the browser - That is, loading the part of the new page in our current page via Ajax by partially rendering the new content in the current page. But because of partial rendering of the page (the fact that the page is never refreshed), the back button gets lost. This plugin solves the back button browser history problem for this scenario using URL fragments.

Step 1: Download the latest jquery library from http://jquery.com/and include it in your project as follows -

<script type="text/javascript" src="<%= ResolveUrl("~/js/jquery-1.2.6.min.js") %>"></script>
(Please remember that this is just an example and the method/filenames etc will change depending on the names used in your web-development language / platform and jquery version etc.

Step 2: Download history/remote plugin js files from http://stilbuero.de/jquery/history/ (this is the website of Mr. Klaus Hartl, the gentleman who came up with this solution) and include it in your project as follows -

<script type="text/javascript" src="<%= ResolveUrl("~/js/jquery.history_remote.js") %>"></script>

Step 3: Add a class named "seolink" to all your links (anchor tags) that needs history management. Please note that this class doesn't exist in your css file and doesn't have any display attributes, it's solely for the purpose of history management.

Step 4: Add the below code (jquery script) in the head tag of the webpage (or the master template if you are using asp.net masterpages) -

$(document).ready(function() {
  createSeoLinks($("#navigation a").add("a.seolink"));
  $.ajaxHistory.initialize(function (){$("#main-content").load(location.href " #main-content > *")});
  });

function createSeoLinks(links) {
  links.unbind('click').remote('#main-content', function() {
 window.createSeoLinks($("#main-content a.seolink"));
  });
}

Step 5 (optional): Ensure that all the links (anchor tags) have title attributes properly set

Step 6 (optional): Add the below code to the $(document).ready(function() section -

document.title = convertLinkToTitle(window.location);

If you don't know what Step 6 means, the final code in Step 4 will look like this -

$(document).ready(function() {
  createSeoLinks($("#navigation a").add("a.seolink"));
  $.ajaxHistory.initialize(function (){$("#main-content").load(location.href " #main-content > *")});
  });

function createSeoLinks(links) {
  links.unbind('click').remote('#main-content', function() {
  window.createSeoLinks($("#main-content a.seolink"));
  document.title = convertLinkToTitle(window.location);
  });
}

And you are done! Yes, it was that easy!

Now, let explain a few things in the above code -

1) main-content : Refers to the div that contains the content that you want to load whenever a link is clicked. Remember that only the contents of main-content div will change as the user navigates through the website, so you will need to organize your content so that the static elements are kept out of main-content div. It doesn't matter a hell lot though but this organization is a good idea in general.

2) What is in addressbar - Remember that, since the page i snever refreshed, the only thing in addressbar that will change is the url fragment. This is picked from the title of anchor tags and that's why Step 5 is needed. It's not an essential component of the history management process though and if you leave it out then it will be "#remote" followed by some number - (like #remote25 for 25th anchor tag etc)

3) convertLinkToTitle - Again since the page is never refreshed, the page title never really changes. So, I figured that I should update the page title programmatically using the information in the browser's addressbar. So this is a javascript / jquery function that will take the link (in the browser's addressbar) and figure out what the title should be, you will be writing the code yourself depending on what you want in url fragment (or the url itself) and how to translate it into page titles. The way, I wrote it is below -

function convertLinkToTitle(linkStr)
{
  var title = new String();
  title = String(linkStr);
  title = title.substr(title.indexOf('#', 0) 1);
  title = title.replace(/_/g, ' ');
  return title;
}

So this is how you implement the History/Remote Plugin.....feel free to suggest improvements, ask questions or comment on the code....And click - to read about another (and in my opinion) better Ajax Browser History Back Button solution called RSH (Really Simple History)

No comments:

Post a Comment