menu

SFRA / Client-side JS / Source: einsteinCarousel.js

'use strict';

/**
 * Validates and Return the cquotient namespace provided by the commerce cloud platform
 * @returns {Object} - einsteinUtils or null
 */
function getEinsteinUtils() {
    var einsteinUtils = window.CQuotient;
    if (einsteinUtils && (typeof einsteinUtils.getCQUserId === 'function') && (typeof einsteinUtils.getCQCookieId === 'function')) {
        return einsteinUtils;
    }
    return null;
}

/**
 * Renders the einstein response into a given dom element
 * @param {jQuery} $parentElement parent element where recommendations will show.
 */
function showControls($parentElement) {
    var $liTemplate = $parentElement.find('.hidden-indicators-template li');
    var $carouselItems = $parentElement.find('.carousel-item');

    $carouselItems.each(function (index) {
        var $newIndiator = $liTemplate.clone();
        if (index === 0) {
            $parentElement.find('.pd-carousel-indicators').append($newIndiator);
        } else {
            $newIndiator.removeClass('active');
            $parentElement.find('.pd-carousel-indicators').append($newIndiator);
        }
        $parentElement.find('.pd-carousel-indicators li').last().attr('data-position', index);
        $parentElement.removeClass('hide-indicators');
    });
}

/**
 * fills in the carousel with product tile html objects
 * @param {string} einsteinResponse string html for product tiles
 * @param {jQuery} $parentElement parent element where recommendations will show.
 */
function fillDomElement(einsteinResponse, $parentElement) {
    var recommendedProducts = einsteinResponse[$parentElement.data('recommender')].recs;
    if (recommendedProducts && recommendedProducts.length > 0) {
        var template = $parentElement.data('template');
        var swatches = $parentElement.data('swatches');
        var displayRatings = $parentElement.data('displayratings');
        var components = [];
        components = recommendedProducts.map(function (recommendedProduct) {
            var tiledefinition = {};
            tiledefinition.classxs = $parentElement.data('bsxs');
            tiledefinition.classsm = $parentElement.data('bssm');
            tiledefinition.classmd = $parentElement.data('bsmd');
            tiledefinition.template = template;
            tiledefinition.swatches = swatches;
            tiledefinition.displayratings = displayRatings;
            tiledefinition.model = {
                type: 'product',
                id: recommendedProduct.id
            };
            return tiledefinition;
        });

        var url = new URL($parentElement.data('product-load-url'));
        url.searchParams.append('components', JSON.stringify(components));
        url.searchParams.append('limit', $parentElement.data('limit'));
        $.ajax({
            url: url.href,
            type: 'get',
            dataType: 'html',
            success: function (html) {
                $parentElement.find('.carousel-inner').html(html);
                showControls($parentElement);
                $('body').trigger('carousel:setup', {});
            },
            error: function () {
                $parentElement.spinner().stop();
            }
        });
    }
}

 /**
 * Processes a recommendation tile, with an already initialized category specific anchors array
 * @param {jQuery} $parentElement parent element where recommendations will show.
 * @param {Object} einsteinUtils cquotient object
 * @param {Array} anchorsArray array of objects representing anchors
 */
function processRecommendationsTile($parentElement, einsteinUtils, anchorsArray) {
    var recommender = $parentElement.data('recommender');

    var params = {
        userId: einsteinUtils.getCQUserId(),
        cookieId: einsteinUtils.getCQCookieId(),
        ccver: '1.01'
    };

    if (anchorsArray) {
        params.anchors = anchorsArray;
    }

    /**
    * Processes a recommendation responses
    * @param {Object} einsteinResponse cquotient object
    */
    function recommendationsReceived(einsteinResponse) {
        fillDomElement(einsteinResponse, $parentElement);
        $parentElement.spinner().stop();
    }

    if (einsteinUtils.getRecs) {
        einsteinUtils.getRecs(einsteinUtils.clientId, recommender, params, recommendationsReceived);
    } else {
        einsteinUtils.widgets = einsteinUtils.widgets || []; // eslint-disable-line no-param-reassign
        einsteinUtils.widgets.push({
            recommenderName: recommender,
            parameters: params,
            callback: recommendationsReceived
        });
    }
}

/**
 * Processes a recommendation tile, with an already initialized product specific anchors array
 * @param {jQuery} $parentElement parent element where recommendations will show.
 * @returns {Array} - containing an anchor object
 */
function createProductAnchor($parentElement) {
    return [{
        id: $parentElement.data('primaryProductId'),
        sku: $parentElement.data('secondaryProductId'),
        type: $parentElement.data('alternativeGroupType'),
        alt_id: $parentElement.data('alternativeGroupId')
    }];
}

/**
 * Rerieves data attributes from parent element and converts to gretel compatible recommenders array
 * @param {jQuery} $parentElement parent element where recommendations will show.
 * @returns {Array} - containing an anchor object
 */
function createCategoryAnchor($parentElement) {
    return [{ id: $parentElement.data('categoryId') }];
}

/**
 * Gets all placeholder elements, which hold einstein recommendations queries the details from the
 * einstein engine and feeds them back to the dom element
 */
function loadRecommendations() {
    var einsteinUtils = getEinsteinUtils();
    if (einsteinUtils) {
        var $recommendationTiles = $('.einstein-carousel');
        $recommendationTiles.each(function () {
            var $parentElement = $(this);
            $parentElement.spinner().start();
            if ($(this).closest('.experience-einstein-einsteinCarouselProduct').length) {
                return processRecommendationsTile($parentElement, einsteinUtils, createProductAnchor($parentElement));
            } else if ($(this).closest('.experience-einstein-einsteinCarouselCategory').length) {
                return processRecommendationsTile($parentElement, einsteinUtils, createCategoryAnchor($parentElement));
            }
            return processRecommendationsTile($parentElement, einsteinUtils);
        });
    }
}

$(document).ready(function () {
    loadRecommendations();
});

X Privacy Update: We use cookies to make interactions with our websites and services easy and meaningful, to better understand how they are used. By continuing to use this site you are giving us your consent to do this. Privacy Policy.