Implementing Ajax in ATG applications - ATG White Paper

Page created by Ken Sherman
 
CONTINUE READING
ATG White Paper

    Implementing Ajax in ATG
    applications
          How to guide on implementing rich user experiences in ATG
          applications using Ajax.

                                                       By Barry Coleman

Master the art of customer experience
ATG White Paper 1

Introduction

Ajax (Asynchronous JavaScript And XML) is a web application development technique that was
first pioneered by Microsoft in their Outlook Web Access interface. The Microsoft team
contributed their XMLHTTP code to the Internet Explorer 4.0 code base. The techniques have
been in use since around 1998, but have really only become popular since the beginning on
2005. Jesse James Garrett of Adaptive Path coined the term Ajax in a paper titled “Ajax: A New
Approach to Web Applications”. He describes the technique as:

        “Every user action that normally would generate an HTTP request takes the form of a
        JavaScript call to the Ajax engine instead. Any response to a user action that doesn’t
        require a trip back to the server — such as simple data validation, editing data in
        memory, and even some navigation — the engine handles on its own. If the engine
        needs something from the server in order to respond — if it’s submitting data for
        processing, loading additional interface code, or retrieving new data — the engine makes
        those requests asynchronously, usually using XML, without stalling a user’s interaction
        with the application.”

Ajax is a collection of web technologies: HTML, CSS, Document Object Model (manipulated
through JavaScript) and the XMLHttpRequest object. It is also the development technique of how
to apply them together.

Pros and Cons

The biggest advantage of using Ajax techniques is that data can be manipulated without having
to render the entire page again in the browser. This gives the user a more responsive and
continuous user experience. All of the technologies are available on most browsers (certainly all
the major browsers) and do not require special plug-ins which may not be available across all
platforms. It does require the browser to have JavaScript enabled.

One of the major down sides is that most of the constituent technologies have inconsistencies
between browser implementations and even between versions of the same browser. ATG has
experienced this during the implementation of the ATG Service Suite 2006.1. We spent a
significant amount of time in the Quality Assurance group making sure that the application
behaved consistently across the supported browsers, ultimately eliminating versions of browsers
that could not be made to work consistently. This is something we were comfortable with for that
application as it is designed to be used in a call center environment where the agent desktop is
closely controlled by IT. It would have been an entirely more taxing problem for a customer
facing application.

Basics methodologies for using Ajax with ATG

There are two core approaches to the process and they can both be used simultaneously as
required:

    1. Make HTTP calls to JSP pages passing data as query parameters or post data. The JSP
       renders HTML that is used to replace existing HTML in the documents DOM. In this
       model the content is rendered on the server so the client doesn’t really need to
       manipulate it.
    2. Make HTTP calls to JSP pages or WebServices that return XML. This XML is then
       parsed on the client using JavaScript and rendered into the appropriate DOM
       components directly.

In the ATG Service Suite 2006.1, we have followed primarily the first model. We have created a
simple framework for handling the creation of partial page renderers. A description is beyond the

Implementing Ajax in ATG applications
ATG White Paper 2

scope of this document but if you take a look at the implementation of the Agent application in the
Service Suite you can readily discover how it works.

For this document we will focus on more concise examples. As an example of both
implementation approaches I’m going to implement a simple Add to Cart feature that updates an
inline shopping cart on a product detail page. This example assumes we are using the ATG
Commerce application.

We’ll approach this problem in 2 phases:
   1. We’ll add the inline cart to the product detail page
   2. We’ll add the functionality to add items to the cart

Adding the inline cart into the page

For this we’ll add a  tag to the product detail JSP page:

This will add an empty node to the DOM in the browser that we can manipulate using JavaScript.
Now in the  section of the JSP we need to add some JavaScript to populate this part of
the page. We are going to make a separate request for this information.

Here’s the basic flow:

        1.   Get an XMLHttpRequest object
        2.   Set the URL to be called and the calling method (GET in this case)
        3.   Register a function to handle the response
        4.   Send the request
        5.   Handle method gets called and updates  with the response

The request to the server is designed to be asynchronous in nature; although you can specify that
XMLHTTPRequest operate synchronously this breaks the paradigm. So we register a handler
method to deal with the results from the server. In this case we are going to have the server
render an HTML fragment that we will use as the  tags innerHTML.

Here’s the JavaScript:

        function getHTTPRequest() {
          var xmlhttp = false;
          try {
            xmlhttp = new ActiveXObject(“Msxml2.XMLHTTP”);
          } catch (e) {
            try {
              xmlhttp = new ActiveXObject(“Microsoft.XMLHTTP”);
            } catch (E) {
              xmlhttp = false;
            }
          }
          if (!xmlhttp && typeof XMLHttpRequest!=’undefined’) {
            xmlhttp = new XMLHttpRequest();
          }
          return xmlhttp;
        }

        function updateQuickCart()
        {
          var xmlhttp = getHTTPRequest();
          xmlhttp.open(“GET”,”/PioneerCycling/en/inline/QuickCartFragment.jsp”);
          xmlhttp.onreadystatechange = function()
          {

Implementing Ajax in ATG applications
ATG White Paper 3

            if (xmlhttp.readyState == 4) {
              var quickCart = document.getElementById(“quickCart”);
              quickCart.innerHTML = xmlhttp.responseText;
            }
          }
          xmlhttp.send(null);
        }
        
The getHTTPRequest() function accounts for the differences between browser implementations,
it handles both new and old version of IE as well as the Mozilla based browsers.

On the server side we simply implement QuickCartFragment.jsp as we would any JSP page. It
should not have any of the ,  and  tags though. Here’s an example:

              ProductQuantityPrice
          
            cart empty
          
Only one thing remains and that is to call the updateQuickCart() method when the page loads.
This can either be done using the “onload” attribute of the  tag or registering a function
for the window.onload event:

or
        
          window.onload = function() {
            updateQuickCart();
          }
        
Now anytime we need to update the view of the cart on this page we can call the
updateQuickCart() method in JavaScript and it will replace the current contents of that section of
the page without refreshing the entire page.

Implementing Ajax in ATG applications
ATG White Paper 4

Adding an item to the cart

In the common Product Details page of an ATG Commerce site you will see a  of
an addToCart.jsp page fragment. This page fragment usually contains a  that
references the CartModifierFormHandler. In this form you’ll find something like the following line:

This will cause the browser to package up the form data in a post, submit it to the server with a
request for the form’s action URI. The server will then process this and return an entire new page
(often the cart page or an updated version of the current page). Our new desired behavior is to
have the item added to the cart without the page refresh. We’ve already seen how to update the
page with the content of the cart, now we just need to add the item to the cart.

To achieve this we can use the addItemToOrder WebService that is provided as part of the ATG
Commerce implementation (enable this by starting your ATG instance with the module
DCS.WebServices). We’ll discuss alternatives after the example.

First, we replace the Submit button with a link (probably put a nice image here with mouse over
effects and so on). Register a JavaScript method with the onclick attribute of the  tag:

Now the JavaScript simply need to pull the values of the Sku id, Product id, Order id and Quantity
from the elements on the page. Fortunately, the out of the box addToCart.jsp page in
PioneerCycling has these available. The following code assume that it can see the previous
JavaScript functions:

          function addToCart()
          {
            /* First accumulate the values from the form */
            var addToCartForm = document.getElementById(“addToCartForm”);
            var orderId = addToCartForm.orderId.value;
            var productId = addToCartForm.productId.value;

            /* Skus can be presented differently so account for the different elements */
            var skuId = “”;
            if (document.getElementById(“SkuGroup”)==null)
            {
              skuId = addToCartForm.skuSelectField.value;
            }
            else
            {
              skuId = addToCartForm.SkuGroup.value;
            }
            var quantity = addToCartForm.quantityField.value;

            /* Now build the request and send it */
            var xmlhttp = getHTTPRequest();

            xmlhttp.open(“POST”,”/commerce/order/addItemToOrder/addItemToOrder”);

            /* implement a function to receive the response */
            xmlhttp.onreadystatechange = function()
            {
              if (xmlhttp.readyState == 4)
              {
                /* we are receiving XML this time not text/html */
                var rXML = xmlhttp.responseXML;
                var rNodes = rXML.getElementByTagName(“return”);

                 /* response is either a commerce item id or an exception

Implementing Ajax in ATG applications
ATG White Paper 5

                         if it’s an exception then rNodes will be empty */

                    if (rNodes == null)
                     {
                       alert(“Problem adding item to cart”);
                    }
                    else
                    {
                       /* check that the contents of the node are not “null” */
                       var rText = rNodes[0].firstChild.nodeValue;

                        if (rText != “null”)
                        {
                          updateQuickCart();
                        }
                        else
                        {
                          alert(Problem adding item to cart”);
                        }
                    }
                }
            }

           xmlhttp.setRequestHeader(“Man”, “POST
       /commerce/order/addItemToOrder/addItemToOrder HTTP/1.1”);
           xmlhttp.setRequestHeader(“MessageType”,”CALL”);
           xmlhttp.setRequestHeader(“Content-Type”,”text/xml”);

           /* Now construct the SOAP packet to send to the web service */
           xmlhttp.send(“"+"\n\n"+
              ''+
                ''+
                ''+
                  ''+orderId+''+
                  ''+productId+''+
                  ''+skuId+''+
                  ''+quantity+''+
                ''+
              '');
         }
       
Using the ATG Web Services documentation, and following this example, you should be able to
figure out the SOAP packet for the other web services. For instance, this is the XML for the
getInventory Web Service:

               sku123456
               sku234567
             
Implementing Ajax in ATG applications
ATG White Paper 6

Things to watch out for

There is one big gotcha: posting to FormHandlers. The ATG FormHandler mechanism has a built
in security system. Whenever a form page is rendered the ATG server creates a list of all the
elements that were on the page. These are the only elements it will allow to be posted back to
the form. This poses a problem because the JavaScript code might not have requested a form
page from the server at all. This means that the server won’t accept an unsolicited post of data to
a FormHandler.

This is why I used the web service as it operates directly on the order objects without going
through the FormHandlers. As a general pattern it is a good idea to separate as much business
logic from Form Handlers as possible. You can then easily set up web services to call the
business logic directly (see the ATG Web Service documentation for more details on creating
web services from Nucleus components).

Most of the major browsers (Internet Explorer, Firefox, Mozilla, Safari, etc.) will send and cookies
received with the original response back to the server with each XMLHttpRequest. This ensures
that you get back to the same session objects on the ATG server. Other implementations may
not do this. If you discover a browser that doesn’t and you need to support it, you should add the
jsessionid to the URL in the XMLHttpRequest.open() method call. You can retrieve the session id
from the SessionCookie using this JavaScript:

        function getSessionIdFromCookie()
        {
          if (document.cookie == "") return null;

            var cookies = document.cookie.split(";");

            for(var i=0;i
ATG White Paper 7

(Direct Web Remoting) available at http://dwr.dev.java.net. This simple toolkit is easy to integrate
with ATG and provides access to components of all scopes (see separate paper “Ajax
development of ATG applications using DWR”).

Partial Page Rendering allows you to break the page up into zones or regions and have those
refreshed using Ajax. These are usually JSP tag libraries that help you minimize the amount of
JavaScript code that you need to write by hand. A good example is AjaxAnywhere –
http://ajaxanywhere.sourceforge.net.

Complete UI frameworks focus mainly on the client side and introduce nothing (or at least very
little) on the server side. Open source examples are: Prototype (http://prototype.conio.net) and
Dojo (http://dojotoolkit.org). There are also much more complete commercial toolkits available
from companies such as BackBase (http://www.backbase.com), JackBe (http://www.jackbe.com),
and Isomorphic SmartClient (http://www.isomorphic.com). There are also frameworks that
include server components as well, such as Nexaweb (http://www.nexaweb.com) and Casabac
(http://www.oisoft.com/index.pl/casabac).

All of these tool kits have their merits and their drawbacks. Some of the commercial ones include
GUI design tools to aid in layout. They all integrate with the ATG server infrastructure using the
techniques outlined in this paper.

Bibliography

Ajax: A New Approach to Web Applications by Jesse James Garrett
http://www.adaptivepath.com/publications/essays/archives/000385.php

ATG Web Service Documentation
http://www.atg.com/repositories/ContentCatalogRepository_en/manuals/ATG7.1/intframe/index.ht
ml

ATG Commerce Web Service Documentation
http://www.atg.com/repositories/ContentCatalogRepository_en/manuals/ATG7.1/commprog/com
mprog1901.html

Implementing Ajax in ATG applications
You can also read