Customizing the Free Gift Selection rendering

Abstract

Overview of the Free Gift rendering Scriban template, which you can customize by modifying the code.

The Free Gift Selection rendering includes a rendering variant in the form of a Scriban template. The Free Gift Selection rendering has its own default rendering variant root and default rendering variant (/sitecore/Content/<tenant>/<site>/Presentation/Rendering Variants/Free Gift Selection), which uses a Scriban template for generating the markup and an AJAX call to the CD to trigger the Add-to-cart event when the Claim gifts button is clicked. Free gifts are added to the cart lines using the API and the IsFreeGift property is set to true.

While you can modify the Scriban template, it is best to create a new custom rendering variant in this case so that the customization does not get overridden during software upgrades. You can also change the labels for the rendering.

The following code shows the Scriban template for the Free Gift Selection rendering defined within the default rendering variant. The list of sellable items from which a shopper can select their free gifts is passed to the Scriban template using the embedded item o_model.

{{ # The hidden <div> element contains serialized data in JSON format. }}
<div class="freegiftselection-data" style="display: none;">
    {{ sc_xc_serialize o_model.free_gift_selections | html.escape }}
</div>

{{ ## The hidden <div> element contains texts related to the component.
      These values are populated from data model and datasource. ## }}
<div class="freegiftselection-messages" style="display: none;">
    <span data-type="heading-text">{{ sc_raw i_datasource 'Heading Text' | html.escape }}</span>
    <span data-type="no-selection-message">{{ sc_raw i_datasource 'No Selection Message' | html.escape }}</span>
    <span data-type="exceed-max-count-message">{{ sc_raw i_datasource 'Exceed Maximum Count Message' | html.escape }}</span>
    <span data-type="error-claim-message">{{ sc_raw i_datasource 'Error Claim Message' | html.escape }}</span>
    <span data-type="invalid-variant-message">{{ sc_raw i_datasource 'Invalid Variant Message' | html.escape }}</span>
</div>

{{ # The <div> element shows a list of multiple free gift selections based on various qualifications. }}
<div data-bind="visible: isVisible, foreach: freeGiftSelectionGroups" style="display: none;">
    <div class="freegiftselection-group" data-bind="css: { 'no-selection-item': !hasSelectionItem() }">

        {{ ## The <div> element displays the selected free gift that has been chosen and the maximum number
              of free gifts that a shopper can choose from the free gift selection. ## }}
        <div class="freegiftselection-header">
            <span class="freegiftselection-header-title" data-bind="text: headingText"></span>
            <div class="freegiftselection-header-claimed-text" data-bind="visible: hasClaimedItem()">
                <span class="freegiftselection-header-selectedtext">
                    <span>{{ sc_field i_datasource 'Free Gift Chosen Text' }}</span>
                    <span data-bind="text: claimedItemName"></span>
                </span>
                <span class="freegiftselection-header-changeselectiontext">{{ sc_field i_datasource 'Free Gift Selection Text' }}</span>
            </div>
        </div>

        {{ # The <div> element contains a checkbox, product image, display name, description, stock status, variant combinations for each free gift. }}
        <div class="freegiftselection-body" data-bind="foreach: selectionItems">

            {{ # The <div> element displays each item as free gift selection in the list populated from data model. }}
            <div class="freegiftselection-item">

                {{ # The <div> element shows whether a free gift is already included in the free gift selection. }}
                <div class=" freegiftselection-checkbox">
                    <input type="checkbox" data-bind="checked: isSelected, disable: isClaimed || isNotClaimable" />
                </div>
                {{ # The <div> element display product image. }}
                <div class="freegiftselection-image">
                    <a data-bind="attr: { href: productLink }">
                        <img data-bind="attr: { src: displayImage }" />
                    </a>
                </div>
                {{ # The <div> element displays product display name, description, valid variant combinations. }}
                <div class="freegiftselection-info">
                    <a data-bind="attr: { href: productLink }">
                        <h5 class="freegiftselection-info-displayname" data-bind="text: displayName"></h5>
                    </a>
                    <span class="freegiftselection-info-description" data-bind="text: productDescription"></span>
                    <div data-bind="visible: hasOnlyOneVariantCombination(), foreach: variantSelections">

                        {{ # The <div> element displays the variant combination when there is only one valid variant combination. }}
                        <div class="variant-information">
                            {{ # The <span> element displays the variant name. }}
                            <span class="variant-property-name" data-bind="text: propertyName"></span><span>:</span>
                            {{ # The <span> element displays the variant value. }}
                            <span class="variant-value" data-bind="text: firstOptionDisplayValue()"></span>
                        </div>

                    </div>
                </div>
                {{ # The <div> element contains the selections for variant properties. }}
                <div class="freegiftselection-variant">

                    <div data-bind="visible: hasMultipleVariantCombinations(), foreach: variantSelections">

                        <div class="variant-selection-group">
                            {{ # The <label> element contains the display name of the variant. }}
                            <label class="variant-property-name" data-bind="text: propertyName"></label>
                            <select class="variant-selection-selector" data-bind="value: currentSelection, options: options, optionsText: 'propertyDisplayValue', optionsValue: 'propertyValue', event: { change: onSelectionChange }"></select>
                        </div>

                    </div>
                </div>
                {{ # The <div> element displays stock status of the free gift. }}
                <div class="freegiftselection-stockstatus" data-bind="text: stockStatusName"></div>
                {{ # The <div> element displays the sale and list prices of the free gift. }}
                <div class="freegiftselection-total">
                    <span class="freegiftselection-sellprice" data-bind="text: sellPriceWithCurrency"></span>
                    <span class="freegiftselection-listprice" data-bind="text: listPriceWithCurrency"></span>
                </div>
            </div>

        </div>
        {{ # The <div> element contains the button to claim the free gift. The text of the button is populated from the datasource. }}
        <div class="freegiftselection-buttons">
            <span class="error-message" data-bind="text: errorMessage"></span>
            <button type="submit" class="claim-gift-btn" data-bind="click: claimSelectedFreeGiftItems, enable: isValidToClaim ">
                {{ sc_field i_datasource 'Button Text' }}
            </button>
        </div>
    </div>
</div>

In the Scriban template for the Free Gift Selection, you access the properties and objects contained in the FreeGiftSelectionRenderingModel model through the embedded item o_model as shown in the following figure.

Diagram of the Free Gift Selection rendering model

The following sequence diagram shows a high-level view of the calls made when the shopper selects and claims their free gifts. Only one call is used to retrieve the latest cart details so that the Free Gift selection rendering is automatically updated whenever the shopper makes changes.

Free Gift Selection sequence diagram