Commerce Reference Store has two pages that render the gift selection options for each gift item: the store.war/cart/gadgets/giftSelection.jsp
page is used when JavaScript is enabled, while store.war/cart/gadgets/noJsGiftSelection.jsp
is used when it is not. Both pages use the atg.commerce.promotion.GiftWithPurchaseSelectionChoicesDroplet
to obtain a list of GiftWithPurchaseSelectionChoice
beans associated with the current gift. Each GiftWithPurchaseSelectionChoice
bean contains a product, and its associated SKUs, that is available for selection for the current gift.
Depending on how a gift is configured in the Business Control Center, it may have a giftType
that consists of a single product or multiple products. The sku
and product
gift types include a single product, hence one GiftWithPurchaseSelectionChoice
bean is returned for this gift type. The category
, skuContentGroup
, and productContentGroup
gift types include multiple products, so multiple GiftWithPurchaseSelectionChoice
beans are returned.
The list of GiftWithPurchaseSelectionChoice
beans is passed to the /atg/commerce/collections/filter/droplet/InventoryFilterDroplet
. This droplet iterates over each bean, using the Commerce Reference Store-specific filter /atg/registry/CollectionFilters/GWPSelectionInventoryFilter
, and checks if the SKUs are available in inventory. Any GiftWithPurchaseSelectionChoice
bean that has no SKUs available in inventory is filtered out.
The gift selection page iterates over the filtered GiftWithPurchaseSelectionChoice
beans and renders a row for each bean that displays the product and SKU choices for that bean. The giftSelection.jsp
gadget renders a JavaScript-based picker similar to what is used on the product detail pages, while the noJsGiftSelection.jsp
gadget renders a drop-down list with each SKU combination. If there is more than one row (that is, more than one GiftWithPurchaseSelectionChoice
bean), a radio button is rendered next to each row so that the customer can pick a SKU and then click the radio button to indicate that this is the SKU she wants to choose. If the customer is making a change to a previous selection, the previous selection is pre-selected on the form. If there is only one row to render, the radio button is omitted.
Note about Selecting Gifts When JavaScript Is Not Enabled
To make gift selection, both the product ID and SKU ID must be submitted within the form. When JavaScript is not enabled, however, selecting the radio button next to the selected product or SKU allows us to only specify one parameter, either the product ID or the SKU ID. The noJsGiftSelection.jsp
gadget includes logic to resolve the unspecified parameter.
When the giftType
of the gift is a SKU content group, the noJsGiftSelection.jsp
gadget renders one SKU per row on the page. Selecting the radio button next to a SKU specifies the SKU ID for the gift. To pass the corresponding product ID, noJsGiftSelection.jsp
specifies an additional parameter of the form promoId_skuId
=
productId
. The atg.projects.store.promotion.StoreGiftWithPurchaseFormHandler.preMakeGiftSelection()
method checks whether the promoId_skuId
request parameter is specified and, if so, it assigns the parameter’s value to the productId
property.
For all other gift types, the storefront displays one product on each row, so selecting the radio button next to the product specifies the product ID. Similarly to the previous case, noJsGiftSelection.jsp
specifies an additional parameter of the form promoId_productId
=
skuId
. The preMakeGiftSelection()
method checks whether the promoId
_
productId
request parameter is specified and, if so, it assigns the parameter’s value to the skuId
property.
Note: In the JavaScript-enabled case, this additional logic is not necessary because when a user clicks a color, size, wood finish, or radio button control in the pop up page, the clickGiftSku()
or clickGiftProduct()
JavaScript functions are called. These functions ensure that all the necessary form parameters are specified.
Error Messages on the Gift Selection Page
The handling of error messages on the gift selection page varies depending on whether JavaScript is enabled or not.
When JavaScript is enabled, an AJAX request is sent to the server when the customer chooses a gift in the popup page. If an error occurs during the request processing, JavaScript retrieves the error messages from a JSON response and injects them into the HTML structure of the popup. To implement this solution, the store.war/cart/gadgets/giftSelection.jsp
gadget specifies the store.war/cart/json/giftErrors.jsp
JSP page as the error URL to use when the gift selection has been made via an AJAX request:
<dsp:input bean="GiftWithPurchaseFormHandler.ajaxMakeGiftSelectionErrorURL" type="hidden" value="${contextroot}/cart/json/giftErrors.jsp"/>
The giftErrors.jsp
page extracts the errors from the /atg/commerce/promotion/GiftWithPurchaseFormHandler.formExceptions
property using the /atg/dynamo/droplet/ErrorMessageForEach
droplet and then creates a JSON object that contains an array of the errors that occurred during request processing. The handleJSON()
JavaScript function from store.war/javascript/picker.js
processes the received JSON object and checks whether it contains any errors. If so, the errors are injected into a special reserved <div>
container inside the gift selection popup. Using this method to render error messages improves the performance of the gift popup page because only a portion of the page is re-rendered when errors occur, not the entire page.
For the case when JavaScript is not enabled, the noJsGiftSelection.jsp
gadget includes the store.war/global/gadgets/errorMessage.jsp
gadget. This gadget renders all of the specified form handler exceptions, wrapped into a single <div>
tag. errorMessage.jsp
uses the ErrorMessageForEach
droplet to retrieve the error messages from the GiftWithPurchaseFormHandler.formExceptions
array.