Saturday 2 April 2011

Implement Ajax actions using page slices [Part 2]

Last time I discussed how to implement Ajax browsing using page slices] generated
at server side. If you haven't read that yet, I strongly encourage you to do so, cause there's little chance the rest of this post will make sense to you.

Read Part 1- Implement Ajax browsing using page slices.

This time we're going to apply the same technique, but we'll implement some actions. By actions I mean simple interactions for instance 'vote a comment up', or 'follow a member', 'delete an item' etc.. Any kind of interaction that does not require more than a click from the user in an Ajax interface.

For instance, on libsquare.net, if you are logged in, you can vote up or down any review that appear on the jQuery page:

So how do we implement that?

The pure HTML flow

First let's remember that page slicing is designed to allow us to implement things without JavaScript, so let's just do that. Here's the work flow of the vote up feature without any JavaScript:

The user clicks on vote up, he arrives on a page where the vote up is pre-selected, clicks submit and is redirected to the page review with the vote count updated.

Let's Ajax this!

First let's give a class 'do_vote_up' to our vote up link:

<a href=".../review/111/vote_up" class="do_vote_up">Vote up</a>

Then we need to give an ID and slice the container that contains the voting unit:

<div class="slice_container" id="review_vote_111">
<& /slice.mas , id => 'review_vote_111' &>
 ... Your vote display html code ...
<a href=".../review/111/vote_up" class="do_vote_up">Vote up</a>
 ...
</&>
</div>

Let's assume /review/111 is a page that always display the review with it's voting part.

Now we're only a small bit of Javascript away from the full Ajaxed feature:

$('a.do_vote_up').live('click', function(event){
  event.preventDefault();
  var a = $(event.target);
  var container = a.closest('.slice_container');
  var target_url = a.attr('href');
  var result_url = target_url; result_url.replace('\/vote_up','');
  // Post a vote up query to the voting URL.
  $.ajax({
    type: 'POST',
    url: target_url,
    data: { vote: 1 , vote_submit : 1 },
    success: function(){
       // On success, reload the voting slice that now contains the updated vote.
       container.load(result_url,{ page_slice: container.attr('id') });
    }
  });
});

Et voila, the vote up action is now Ajaxed. Implementing the same thing for the vote down is left as an exercise for the reader :P

Next time I'll be speaking about submitting forms and dealing with redirections in Ajax. Stay tuned and thanks for reading!