Implementing Ajax in ATG applications - ATG White Paper
←
→
Page content transcription
If your browser does not render page correctly, please read the page content below
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