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.',
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