HCL Commerce AJAX framework

The HCL Commerce AJAX framework is an extension of the jQuery AJAX framework. It provides an easy to use framework that meets most AJAX requirements for storefront development, and hides some of the complexity and repetitive code that a storefront developer often encounters.

There are four common scenarios that are involved with the HCL Commerce AJAX framework:

  1. An AJAX call is made to the Transaction server to update a business object. Sections of the page are refreshed with new content if the update is successful. The new content is retrieved by using subsequent AJAX calls to the Transaction server.
  2. An AJAX call is made to refresh a section of the page because of certain customer interactions.
  3. An AJAX call is made to the Transaction server to update a business object. Sections of the page must refresh with new content if the update is successful. The new content is retrieved by using subsequent AJAX calls to the Transaction server. The process is the same as the first scenario, however, instead of making the code modular, a less traffic intensive approach to the server is required.

    In this scenario, an AJAX call is made to the HCL Commerce server to update a business object. Sections of the page are refreshed with new content if the update is successful. All the relevant information to refresh the contents of the page are returned as a JSON object. The client then has the contents of the JSON object. The client uses the DOM manipulation API to modify all the areas of the page that must change as a result of the successful update.

  4. An AJAX call is made to the Transaction server and JSON data is requested. Sections of the page are then updated by using JavaScript and the DOM manipulation API.

The HCL Commerce AJAX framework is not required for the third and fourth scenarios, as these scenarios can be performed directly by using the jQuery AJAX API.

Important: Avoid making concurrent Ajax calls for commands. In particular, avoid concurrent calls that turn a generic user into a new guest user with a user activity token. The concurrent calls result in multiple user activity tokens in the session, which causes undesired results.

You can make concurrent Ajax calls for views.

Scenario 1: Updating a business object in HCL Commerce using AJAX, then refreshing multiple areas by using subsequent AJAX requests to get the refresh contents

There are two parts to this scenario:
  1. An AJAX call is made to an HCL Commerce controller command or HCL Commerce service to update a business object (or multiple business objects).
  2. Subsequent AJAX get requests are made to HCL Commerce views to retrieve the new HTML contents for each area if the update is successful.
The following two diagrams show which interactions occur between the client and the HCL Commerce server in this scenario.

Interaction diagram when you call HCL Commerce controller commands:

Interaction diagram when you call HCL Commerce controller commands

Interaction diagram when you call HCL Commerce services:

Interaction diagram when you call HCL Commerce services

1. Making an AJAX call to an HCL Commerce controller command or service

Before the client is able to call an HCL Commerce controller command or service by using AJAX, the Transaction server must define that the controller command or service can be called by using AJAX (rather than the traditional programming model where the request is made and a new redirect is implied by the HCL Commerce run time).

To define a controller command or service to be available for AJAX type requests, simply define a new struts-action entry in the struts-config XML file that identifies the controller command or service as an AJAX type of action. For example, to create a new struts-action for the InterestItemAdd controller command that can be called by using AJAX, it must be defined it in the struts configuration XML file:

Figure 1. Commands:
<action
  parameter="com.ibm.commerce.interestitems.commands.InterestItemAddCmd"
  path="/AjaxInterestItemAdd"
  type="com.ibm.commerce.struts.AjaxAction">
    <set-property property="authenticate" value="0:0"/>
    <set-property property="https" value="0:1"/>
</action>
<action class="com.ibm.commerce.struts.v2.AjaxAction" name="AjaxInterestItemAdd">
<param name="authenticate">0:0</param>
<param name="https">0:1</param>
<param name="parameter">com.ibm.commerce.interestitems.commands.InterestItemAddCmd</param>
</action>
Figure 2. Services:
<action 
  parameter="order.addOrderItem" 
  path="/AjaxOrderChangeServiceItemAdd" type="com.ibm.commerce.struts.AjaxComponentServiceAction">
    <set-property property="authenticate" value="0:0"/>
    <set-property property="https" value="0:1"/>
</action>
<action class="com.ibm.commerce.struts.v2.AjaxComponentServiceAction" name="AjaxOrderChangeServiceItemAdd">
<param name="authenticate">0:0</param>
<param name="https">0:1</param>
<param name="parameter">order.addOrderItem</param>
</action>
The characteristic of an AjaxAction type URL is that after the execution of the command or service, the HCL Commerce runtime automatically forwards the request to one of two known views to compose a JSON object that contains all the entries in the response back to the client. The two known views map to these JSP files
  • WC_eardir/Stores.war/AjaxActionResponse.jsp (success case)
  • WC_eardir/Stores.war/AjaxActionErrorResponse.jsp (failure case)
  • HCL Commerce Developer workspace_dir/Stores/WebContent/AjaxActionResponse.jsp
  • HCL Commerce Developer workspace_dir/Stores/WebContent/AjaxActionErrorResponse.jsp
Now that AJAX struts-actions are defined, the wcService.declare API is used in the JavaScript code to define a service for each of the required URLs being called in the page. The wcService.declare API declares a JavaScript service object that is able to call HCL Commerce AJAX type struts-actions. This gives the control to the client for when to execute the AJAX call. For example, the following JavaScript code in the client defines a service object for calling InterestItemAdd by using AJAX:
wcService.declare({
  id: "AjaxInterestItemAdd",
  actionId: " AjaxInterestItemAdd",
  url: " AjaxInterestItemAdd",
  formId: "",
successHandler: function(serviceResponse) {
      alert("success");	
    },
failureHandler: function(serviceResponse) {
    if (serviceResponse.errorMessage) {
      alert(serviceResponse.errorMessage);
    }
  } 
});
The definition simply defines an object, and does not yet trigger the AJAX call to the HCL Commerce server. To invoke the AJAX call, the following API is used:

  wcService.invoke("AjaxInterestItemAdd");
The successHandler function that is defined in the service declaration is executed and if the request completes successfully, it will publish an event with the actionId of the service. For more information about subscribe and publish listeners, see the details in wcTopic.

2. Making AJAX calls to HCL Commerce views to get refresh contents

The HCL Commerce AJAX framework provides a JavaScript object called WCRefreshController. Any HTML element of a page can be designated as a refresh area. The content within the HTML tag is replaced by new content from the HCL Commerce server whenever the refresh controller that is associated with the refresh area triggers the refresh request. This sample code defines a refresh area in the page:

<div wcType="RefreshArea"
   id="WishlistSelect_Widget" 
   declareFunction="declareRefreshArea()"
   refreshurl="<c:out value="${WishListSelectAreaView}"/>">
</div>
In the HTML where the refresh area is defined, it must specify an attribute wcType with the value "RefreshArea". There is also a second mandatory attribute called declareFunction that specifies where the refresh controller is defined in the declareFunction attribute. The refreshurl attribute defines the Transaction server URL to call and get the new HTML contents for the refresh area that the refresh controller is associated to. The refresh controllers are automatically registered to listen to modelChanged and renderContextChanged events. Therefore, they are notified when these events occur. They then evaluate the model changes and/or render context changes and decide whether the refresh areas that it manages must be refreshed or not. The following sample code shows how to define a refresh controller:

function declareRefreshArea () {
   var myWidgetObj = $("#WishlistSelect_Widget")
   var myRCProperties = wcRenderContext.getRenderContextProperties("WishlistSelect_Context");
   
   var renderContextChangedHandler = function() {
   };

   // model change
   wcTopic.subscribe(order_updated, function() {
   myWidgetObj.refreshWidget("refresh", myRCProperties);
   });

   // post refresh handler
   var postRefreshHandler = function() {
   };

   // initialize widget with properties
   $("#"+divId).refreshWidget({
      renderContextChangedHandler: renderContextChangedHandler,
      postRefreshHandler: postRefreshHandler
   });

}
The wcTopic.subscribe function is executed by the HCL Commerce AJAX framework as soon as there is a publish event that is triggered by successful wcService.invoke() actions. The wcTopic.subscribe function listens to changes of a specific actionId that is of interest to the refresh area. The refresh widget ("refresh") is the code that makes an AJAX call to the Transaction server for the URL specified in the refresh controller. Once the new HTML fragment returns from the server, the framework destroys anything that exists in the current refresh area and replaces its contents with the new HTML fragment returned by the view.
Another useful function is the postRefreshHandler function of the refresh controller, as it is the last function that the framework calls after a refresh area is successfully refreshed with new contents. It can be used to unblock the user interface if it was blocked during the AJAX calls.
Note: If the render context is not used, it is not necessary to define it.

Scenario 2: Refreshing an area of the page by using an AJAX request to get the refresh contents

Areas of the page must refresh with new content when users interact with the user interface. This scenario uses the render context, refresh area and refresh controllers API from the HCL Commerce AJAX framework.

A render context object keeps track of context information of the client and it can trigger renderContextChanged events whenever updates occur to any of the properties in the render context object. The refresh controllers are automatically registered to listen to all the renderContextChanged events. The refresh controller logic determines whether the context change must trigger an update of a refresh area widget. Therefore, in the refresh controller's renderContextChangedHandler, the API is used to compare the context properties testForChangedRC to determine whether the context property is changed and then trigger the refresh of the refresh area.

Scenario 3: Updating a business object in HCL Commerce using AJAX and returning all relevant update information by using JSON

This scenario can be achieved by using the jQuery API directly. Therefore, there is no need to use the HCL Commerce AJAX framework if this scenario is of relevant interest. The dojo.xhrPost API is used with the traditional HCL Commerce runtime programming model, where a request is made to a controller command or a service, and after execution, the HCL Commerce run time redirects the request to whatever is specified in the URL or errorViewName parameters in the original request. For example,
var parameters = {};
  parameters.storeId = storeId;
  parameters.langId=langId;
  parameters.catalogId=catalogId;
  parameters.catentryId=productId;	
  parameters.URL="MiniCartContentsJSON";
parameters.errorViewName="MiniCartContentsJSON";
  $.ajax({
    url: "OrderChangeServiceItemAdd",
    method: "post",				
    dataType: "json",
    data: parameters,
    success: refreshMiniCart,
    error: function(jqXHR,textStatus, err) {
    }
  });
This code snippet makes an AJAX request to the OrderChangeServiceItemAdd service and then redirects to the MiniCartContentsJSON view, which is mapped to a JSP file that creates a JSON object with its content. In this scenario, the assumptions are that the same JSP file handles the error scenario as the errorViewName is set to the same MiniCartContentsJSON view. The client then gains control back and either the load or error function is called depending on the respective success or failure.
Note: The error scenario is only called when there are difficulties in communicating with the Transaction server. Otherwise, a success or exception from the HCL Commerce code executes the load function. The load function determines from the JSON object whether the request was successful or it failed.

The load function uses the JSON object and DOM manipulation API to replace all the elements in the page that must be updated with new data that resulted from the server update. URLs do not need to be registered as AjaxAction, as this scenario does not use any of the new HCL Commerce AJAX frameworks.

Scenario 4: Calling Transaction server by using AJAX to gather new data as a JSON object and refreshing the page contents

This scenario can be achieved by using the jQuery API directly. Therefore, there is no need to use the HCL Commerce AJAX framework if this scenario is of relevant interest. The jQuery API is used with the traditional HCL Commerce runtime programming model, where a request is made to a view that maps to a JSP file that creates a JSON object. On the load function of the AJAX API, the DOM manipulation API is used to put the JSON contents in the web page elements.