Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

The AjaxCommand strategy for JSF

Update the Command pattern to handle common Ajax requests

  • Print
  • Feedback

Page 4 of 5

AjaxCommand on the front end

That pretty much takes care of the server side, where you catch the Ajax request, process it and fire off a simple response. Now let's take a look at the front end, where you set up the initial Ajax request and then catch the server's response.

Setting up the Ajax request

One of the main motivations for using the AjaxCommand strategy is that you can use a given AjaxCommand from anywhere you can make an Ajax request. So, as long as you can send an Ajax request with how to identify the node, the AjaxCommand flag set to true, and the bean name of the managed bean that implements AjaxCommand, you can use your action. Basically, anywhere you can put JavaScript, you can put a call to an AjaxCommand, and the server-side handler code will handle it -- which is pretty neat.

Now let's look at the steps to set up the initial Ajax request, starting with a call invoking the DeleteCommand.

Listing 8. Ajax Delete call

tools.doDelete = function(domNode, id){
  var confirmation = confirm("Delete this item?");

  if (!(confirmation)){ return; }

  var urlToPost = dojo.dom.getFirstAncestorByTag(domNode, "form").action;

  params = {
    "com.asparity.jsf.AJAX_COMMAND" : "true",
    "ajaxcommand.jsf.AJAX_COMMAND_BEAN" : "DeleteItemCommand",
    "id" :  id
  }

  dojo.io.bind({
    url: urlToPost,
    method: "POST",
    load: function(type, data, evt){ tools.handleDelete(data); },
      mimetype: "text/xml",
      content: params
  });
}

Leveraging Dojo's built-in Ajax ability makes this quick and painless. First, verify that the user really wants to delete. Next, grab the URL you want to submit to from the enclosing form -- this will be your server. To get the form, your function requires a domNode be passed in, but that's OK because it can be any old domNode.

After that, you create an associative array to hold the parameters, which (as noted above) are the AjaxCommand flag, the command bean name, and the means for identifying the node you want to delete.

dojo.io.bind is really a winner --- you can just see how simple it is. Simply tell it what URL to use, and what method, then the rest (although the syntax is compact) just says, tools.handleDelete is the callback function, the mime-type, and hands the parameters over.

Your next step is to set up the Ajax response handler, which will catch the server's response.

Setting up the Ajax response handler

You make the server's response available to your callback handler by passing the "data" callback variable like so:

tools.handleDelete(data)

The callback handler is executed when the Ajax response is sent, and the server's response is passed in as an argument. Here's the handler:

Listing 9. Ajax response handler

treeTools.handleDelete = function(statusXml){
  var status = statusXml.getElementsByTagName("status")[0].childNodes[0].nodeValue;
  var detail = statusXml.getElementsByTagName("detail")[0].childNodes[0].nodeValue;

  var id =
    statusXml.getElementsByTagName("id")[0].childNodes[0].nodeValue;

  if (status=="OK"){

    // ... Remove the object from the UI based on ID

    alert(detail);

  } else { // Error
    //  "Problem deleting item: " + detail);
    alert("Problem deleting: " + detail);
  }
}

The handler grabs values from the XML response and responds appropriately. If everything went okay, you pop up an alert saying so; if not, you give an alert with the server's description of what went awry.

And with that, the request cycle is complete. Anywhere you have a way of identifying an object, you can delete it via an Ajax call.

An obvious improvement that you almost always need in a production system is a way to identify what element on the page made the call, and how it should respond. For instance, if this delete call is made from a detail screen, you would want to clear that screen. If it was made from a list or a tree of items, you'd want to remove the item or the node.

A good way to handle the above requirement is, when you make the request, to add the domNode.id to the parameters. Then, when the server makes its response, add another element to the XML response, called something like ajaxcommand.jsf.AJAX_RESPONSE_ELEMENT_ID. The response handler can then grab that ID, and use getElementById to figure out who made the request and what the appropriate action is.

  • Print
  • Feedback

Resources