AJAX sample implementation for WebSphere Commerce
Assuming the following design requirements:
  • The AJAX handler will be /AjaxPPTGiftCardsBalanceEnquiry
  • The command to serve the AJAX request will be com.ibm.commerce.payment.commands.ajax.DoPPTGiftCardsBalanceEnquiryCmd
  • The equivalent implementation class will be com.ibm.commerce.payment.commands.ajax.DoPPTGiftCardsBalanceEnquiryCmImpl
  • The store id is 10003
  • The AJAX request is required during checkout process and will be added to “OrderSummaryDisplay.jspf”
  • The AJAX call is used to verify GiftCard numbers along with their pin
  • High level implementation is shown in code snippets below with place holders on where to add your implementation

Follow the steps below to add an AJAX call to your site:
  • Add the following lines of code to OrderSummaryDisplay.jspf
    • It is important not to forget the call to e.preventDefault() or you will end up refreshing the whole page.
<form name="giftcardform" method="post" action="VerifyGiftCard" id="giftcardform" class="form_inline">
<label for="gift_card_number1"><span>Gift card no</span></label>
<input name="gift_card_number_1" id="gift_card_number_1" type="text" maxlength="20" />

<label for="gift_card_number_1"><span>Pin no</span></label>
<input name="gift_card_pin_1" id="gift_card_pin_1" type="text" maxlength="20" />
<script type="text/javascript">
function verifyGiftCard(e,num) {
console.debug("verifyGiftCard for Gift Card number: "+num);
giftCardNumber=dojo.byId('gift_card_number_1').value;
giftCardPin=dojo.byId('gift_card_pin_1').value;
console.debug("giftCardNumber: "+giftCardNumber);
console.debug("giftCardPan: "+giftCardPin);
var xhrArgs = {
url: "/webapp/wcs/stores/servlet/AjaxPPTGiftCardsBalanceEnquiry",
content:{
'dcGiftCardNumber':giftCardNumber,
'dcGiftCardPin':giftCardPin
},
handleAs: "json",
load: function(data) {
console.debug("AJAX call successful");
console.debug(data);
handleResponse(data);
},
error: function(error) {
console.debug("An unexpected error occurred: ");
console.debug(error);
}
}

//Call the asynchronous xhrGet
var deferred = dojo.xhrPost(xhrArgs);
e.preventDefault();
}

function handleResponse(data){
//Add business logic here to handle AJAX response
}
</script>
<fmt:message var="brandAccountCode" key="S_ACCOUNT" bundle="${storeFrontText}"/>
<input name="gift_card_verify" id="gift_card_verify" type="image" class="submit_button" alt="Verify Gift card no" src="<c:out value="${jspStoreImgDir}${vfileColor}checkout/btn_apply_nus_code.gif"/>" onclick="verifyGiftCard(event,1);"/>
</form>
  • Add the command class to project WebSphereCommerceServerExtensionsLogic
package com.ibm.commerce.payment.commands.ajax;
import com.ibm.commerce.command.ControllerCommand;
public interface DoPPTGiftCardsBalanceEnquiryCmd extends ControllerCommand{
}
  • Add the associated implementation Class for the command above to project WebSphereCommerceServerExtensionsLogic. The code is chopped off to show the important pieces only. Take the following into consideration:
    • You don't need to specify a view as all AJAX commands are served by one of two JSPs available by default, which are “AjaxActionResponse.jsp” when successful or “AjaxActionErrorResponse.jsp” in case of exception thrown.
    • Even if you tried to set a View, WebSphere commerce will ignore it and goes to the default views set for AJAX responses.
    • All parameters included in request or response are included in JSON response automatically for you
    • If you don't need any request parameter to be available in the response, just make sure to remove them out as shown below
public class DoPPTGiftCardsBalanceEnquiryCmdImpl
extends ControllerCommandImpl
implements DoPPTGiftCardsBalanceEnquiryCmd{

public void performExecute() throws ECException {
super.performExecute();
TypedProperty prop = getRequestProperties();

try {
String giftCardNumber=prop.getString(“dcGiftCardNumber”)
String giftCardPin=prop.getString(dcGiftCardPin);

//Cleanup - remove request parameters you don't need anymore
prop.remove(“dcGiftCardNumber”);
prop.remove(dcGiftCardPin);

} catch (ParameterNotFoundException e) {
//throw exception and handle situation appropriately
}

//Set the view to render
TypedProperty rspProp = new TypedProperty();
//Add any paramater you need to pass to the client as response

setResponseProperties(rspProp);

}
  • Update struts-config-ext.xml to add an action mapping for “/AjaxPPTGiftCardsBalanceEnquiry” as shown below, where:
    • Action mapping is set to “/AjaxPPTGiftCardsBalanceEnquiry”
    • Type is set to “com.ibm.commerce.struts.AjaxAction”
    • Parameter is set to “com.ibm.commerce.payment.commands.ajax.DoPPTGiftCardsBalanceEnquiryCmd”
 struts-config-ext.xml
 
  • Register the new command by running the following SQL command:
insert into CMDREG (STOREENT_ID, INTERFACENAME, DESCRIPTION, CLASSNAME, TARGET)
values (10003,'com.ibm.commerce.payment.ajax.commands.ajax.DoPPTGiftCardsBalanceEnquiryCmd',
'This is a new controller command for the PPT Gift cards balance verify AJAX command.',
'com.ibm.commerce.payment.commands.ajax.DoPPTGiftCardsBalanceEnquiryCmdImpl','Local');
Take into consideration that 10003 is the parent for other stores, so don't have to repeat this for every store. Or you can just associate it with store 0 which is parent for all in out-of-box WebSphere Commerce installation.
  • Add command access control policy using the Websphere commerce binary command acpload where WC7NEW is database name, username/password are those required to connect to the database and finally WSCADMIN is the schema name in capital letters (and it is usually equivalent to username) :
    • acpload WC7NEW <username> <password> AjaxPPTGiftCardsBalanceEnquiryCmdACPolicy.xml WCSADMIN
  • Sample content for AjaxPPTGiftCardsBalanceEnquiryCmdACPolicy.xml is shown below:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?>
<!DOCTYPE Policies SYSTEM "../dtd/accesscontrolpolicies.dtd">
<Policies>
<Action Name="ExecuteCommand" CommandName="Execute">
</Action>
<ResourceCategory Name="com.ibm.commerce.payment.commands.AjaxPPTGiftCardsBalanceEnquiryCmdResourceCategory"
ResourceBeanClass="com.ibm.commerce.payment.commands.AjaxPPTGiftCardsBalanceEnquiryCmd">
<ResourceAction Name="ExecuteCommand"/></ResourceCategory>
<ResourceGroup Name="AllSiteUserCmdResourceGroup" OwnerID="RootOrganization">
<ResourceGroupResource Name="com.ibm.commerce.payment.commands.AjaxPPTGiftCardsBalanceEnquiryCmdResourceCategory" />
</ResourceGroup>
</Policies>
  • According to infocenter, you have to update struts configuration in the register as shown below. Personlly I don't think it makes a difference but you can do it anyway.

Update registry

  • Restart WebSphere Commerce server
  • Test your new AJAX calls using FF and FireBug plugin to make sure the AJAX call is successful and you get a JSON response back which contains what ever parameters you put in the response back to client.
  • If you wish to implement AJAX model using a normal command of type BaseAction instead of AjaxAction, so you can have different views for different AJAX calls instead of a master view for all of your calls, you need to do those extra steps (high level steps):
    • Change the action type from AjaxAction to BaseAction
    • Define a view in action mappings and global forwards
    • Update your command impl to forward to the new view
    • Add access control policy for the view
    • Make sure that the JSP associated with the view you created, sends the right format back to the client which is usually either JSON or text (which is used if you are sending back HTML fragments to update the DOM)

Comments

Popular posts from this blog

Dataload Utility In WCS

10 Steps to Configure Email – Websphere Commerce Server

WebSphere Commerce