Fork me on GitHub

Keith Pitt

Hi! I'm Keith. I'm a Melbourne based Web/iOS Developer. I am the author of VendorKit and DesksNear.Me. Outside of code, I watch scary movies, perform illusions, and enjoy stand up comedy.

Contact Me

jQuery Address, Ruby on Rails and Will Paginate

Thursday, January 20, 2011

In my previous blog post “The HTML5 History API”, I talked about using the new API to change the URL of a web page, without leaving the page itself. The problem with using the API directly, is that it only works in Google Chrome (at time of writing). I couldn’t find any documenation on whether or not this API will be introduced in IE9, so it would seem, we’re going to need a cross browser solution if we are going to keep our users happy.

Enter jQuery Address. From the jQuery Address website:

The jQuery Address plugin provides powerful deep linking capabilities and allows the creation of unique virtual addresses that can point to a website section or an application state. It enables a number of important capabilities including:

  • Bookmarking in a browser or social website
  • Sending links via email or instant messenger
  • Finding specific content using the major search engines
  • Utilizing browser history and reload buttons

I have expanded on the example I provided in my previous blog post, but I have changed the JavaScript to use jQuery Address, as apposed to the History API directly.

The example can be viewed at: http://ajax-pagination.heroku.com/ and the code can be downloaded at https://github.com/keithpitt/ajax-pagination.

The only changes to the application are the Javascript (that I will go through below) and the inclusion of the jQuery Address plugin.

I start off by setting the base url for the application. For the majority of cases, this will be “/”. But if you are doing something crazy with you app, and the root is actually “/my_application”, then you’ll want to set this value to: “/my_application”.

$.address.state('/');

We now need to define a function that is called when ever the browser state changes. I don’t want to an AJAX request if there are no query parameters in the URL, which is why I test for an empty object.

$.address.change(function(event) {

  if($.isEmptyObject(event.parameters))
    return;

  $('#search').val(event.parameters.q);

  $('#loading').slideToggle('fast', function() {
    $.ajax({
      url: event.path,
      data: event.parameters,
      success: function(html) {
        $('#loading').slideToggle('fast');
        $('#content').html(html);
      }
    })
  });

});

Finally, we need to rewrite the bindings to the form and to the pagination links. Instead of calling history.pushState, we just need to call $.address.value, with the new URL (simple hey!)

$('form').live('submit', function() {
  var action = $(this).attr('action'),
      params = $(this).serialize();

  $.address.value(action + '?' + params);

  return false;
})

$('.pagination a').live('click', function() {
  var href = $(this).attr('href');

  $.address.value(href);
  return false;
})

And thats it! We now have a cross browser, degradable, search engine crawlable solution to the state problem with web applications.