/******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var PageTypeMap = __webpack_require__(1); var events = __webpack_require__(3); var utils = __webpack_require__(4); __webpack_require__(5); //Global variable used by analytics window['dataLayer'] = window['dataLayer'] || []; window.bata_com_ns = window.bata_com_ns || {}; window.bata_com_ns.analytics = window.bata_com_ns.analytics || {}; /** * @description launch the product (PDP) impression */ function triggerProductsImpressions(pageType) { var products; var ga4Products; if (pageType === 'product') { products = utils.getProductDataPDP(); ga4Products = utils.ga4GetProducts(products); var value = ga4Products && ga4Products.length > 0 ? ga4Products[0].price : 0; utils.promoImpressionHelper(); events.ga4ViewItem(window.bata_com_ns.analytics.currency, ga4Products, parseFloat(value)); } else if (pageType === 'cart') { products = utils.getProductsCartData(pageType); ga4Products = utils.ga4GetProducts(products); var cartPageData = utils.ga4GetCartData(); events.ga4ViewCart(window.bata_com_ns.analytics.currency, ga4Products, cartPageData.couponNames, parseFloat(cartPageData.value)); } else { products = utils.getProductsData(); ga4Products = utils.ga4GetProducts(products); // track GA4 product views only if not empty if (ga4Products && ga4Products.length > 0) { events.ga4ViewItemList(window.bata_com_ns.analytics.currency, ga4Products); } } // track UA product views only if not empty if (products && products.length > 0) { events.trackProductImpression(window.bata_com_ns.analytics.currency, products); } utils.trackRecommendationsLists(); } /** * @description when editorial products on PDP, handle the data and trigger view_item_list GA4 event */ function triggerEditorialProducts() { var productsList = []; var currentProductId = utils.getProductDataPDP()[0].id || 'undefined product'; var editorialProducts = $('.js-editorial-pdp .product-tile.js-tileWrapper'); var sectionTitle = $('.js-editorial-pdp .cc-recommended-slider__title-link').text().trim() || 'Editorial PDP'; if (editorialProducts.length > 0) { editorialProducts.each(function () { var analyticsProduct = $(this).find('.analytics-product'); if (analyticsProduct.data('name') && analyticsProduct.data('id')) { var productData = utils.getProductClickTileData(analyticsProduct); productData.list_name = 'PDP - ' + currentProductId + ' - ' + sectionTitle; productsList.push(productData); } }); if (productsList.length > 0) { var ga4ProductsList = utils.ga4GetProducts(productsList); events.ga4ViewItemList(window.bata_com_ns.analytics.currency, ga4ProductsList); } } } /** * @description get all the global information form the DOM, then eventually, lauch the various impressions */ function pushPageData() { var $user = $('#analytics-user'); var pageType = utils.getPageType(); var customerEmailMarketing = $user.data('email-marketing').toString(); var customerEmail = $user.data('email'); var customerCrmId = $user.data('customer-crm-id'); var customerGender = $user.data('user-gender'); var customerId = $user.data('customerid'); var customerType = $user.data('order-count') > 0 ? 'existing' : 'new'; var currency = $('#analyticsCurrencyCode').data('currency'); var countryCode = $('#analytics-countryCode').data('content'); // pageType should always be set at least to 'other' pageType = pageType && pageType.length > 0 ? pageType : 'other'; //saves useful information in window object to improve the performances window.bata_com_ns.analytics.currency = currency; window.bata_com_ns.analytics.pageType = pageType; window.bata_com_ns.analytics.country = countryCode; window.bata_com_ns.abTests = { callAbTestInteraction: utils.callAbTestInteraction }; // businessHours event events.businessHours(utils.getBusinessHours()); // abTests data pushing into the dataLayer utils.callAbTestInteraction({ 'pageType': pageType }); //If the pageType is detected, track the page impression if (pageType) { events.pageImpression(customerCrmId, pageType, window.location.href, customerEmail); var ga4CrmId = customerCrmId && customerCrmId !== 'guest' ? customerCrmId : null; var ga4Email = customerEmail && customerEmail !== 'guest' ? customerEmail : null; events.ga4PageView({ pageType: pageType, pageURL: window.location.origin, pagePath: window.location.pathname, country: countryCode, emailMarketing: customerEmailMarketing, email: ga4Email || undefined, internalClientId: customerId, loginStatus: ga4CrmId ? 'true' : 'false', gender: customerGender, userID: ga4CrmId || undefined, userType: ga4CrmId ? customerType : "guest" }); utils.PageDesignerPromoImpressionHelper(); } //if the pageType can contains products to track the impressions, trigger the event if (PageTypeMap.PRODUCT_IMPRESSION_MAPPING[pageType]) { triggerProductsImpressions(pageType); if (pageType === 'product') { triggerEditorialProducts(); } } //if it is a category or brand page, try to get search data if (pageType === 'category' || pageType === 'brands') { utils.searchHelper(); } else if (pageType === 'purchase') { //if the user lands on purchase page, launch checkout events utils.orderConfirmHelper(); } // At cart page check for removed items due to unavailability if (pageType === 'cart' && $('#unavailableProductsModal').length > 0) { utils.removeFromCartByUnavailabilityModal(); } window.dataLayer.push({ 'event': 'basicAppEventsInitialized' }); } /** * Observe lazy-loaded product components and track them in analytics */ function observeLazyLoadedProducts() { // Create a mutation observer to watch for added product lists var observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.addedNodes && mutation.addedNodes.length) { for (var i = 0; i < mutation.addedNodes.length; i++) { var node = mutation.addedNodes[i]; // Skip non-element nodes, they can't contain product lists // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType if (node.nodeType !== 1) { continue; } // Check if this node is a product list or contains product lists var $productLists = $(node).hasClass('analytics-ProductList') ? $(node) : $(node).find('.analytics-ProductList'); if ($productLists.length) { // Process products in the list var products = utils.getProductsData(); if (products && products.length > 0) { var ga4Products = utils.ga4GetProducts(products); if (ga4Products && ga4Products.length > 0) { events.ga4ViewItemList(window.bata_com_ns.analytics.currency, ga4Products); } events.trackProductImpression(window.bata_com_ns.analytics.currency, products); } // Process any recommendation lists utils.trackRecommendationsLists(); } } } }); }); // Start observing the document for changes observer.observe(document.body, { childList: true, subtree: true }); } $(document).ready(function () { pushPageData(); observeLazyLoadedProducts(); }); /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; //link the information extracted from pdic.action (or other location) to the analytics pages var pageMetaDataUtils = __webpack_require__(2); var PAGE_MAPPING = pageMetaDataUtils.getPageMappingFromMetaDataElement('data-analytics-page-type-mapping'); //specifies the pages where the event for addToCart needs further information var CART_MAPPING = { "category": "category", "wishlist": "wishlist view", "product": "product detail page" }; //specifies the pages where the event for add/remove from wishlist needs further information var WISHLIST_MAPPING = { "category": "catalog", "wishlist": "wishlist page", "product": "product detail page" }; //specifies in which pages products impression are tracked (the pages that can contain products) var PRODUCT_IMPRESSION_MAPPING = { "account": false, "billing": false, "brands": false, "cart": true, "category": true, "checkoutlogin": false, "content": false, "home": true, "ordeConfirmation": false, "product": true, "shipping": false, "wishlist": true, "storelocator": false }; module.exports = { PAGE_MAPPING: PAGE_MAPPING, CART_MAPPING: CART_MAPPING, WISHLIST_MAPPING: WISHLIST_MAPPING, PRODUCT_IMPRESSION_MAPPING: PRODUCT_IMPRESSION_MAPPING }; /***/ }), /* 2 */ /***/ (function(module, exports) { 'use strict'; //link the information extracted from pdic.action (or other location) to the analytics pages var getOrSetPageMetaDataAttrElement = function getOrSetPageMetaDataAttrElement(dataAttrName, val) { var metaData = document.getElementsByClassName('page-meta-data'); metaData = metaData && metaData.length > 0 ? metaData[0] : null; if (!metaData) { return null; } if (!dataAttrName) { return null; } // get if (typeof val === 'undefined') { metaData = metaData.getAttribute(dataAttrName); } // set else { metaData.setAttribute(dataAttrName, val); } return metaData; }; var getPageMappingFromMetaDataElement = function getPageMappingFromMetaDataElement(dataAttrName) { var metaData = getOrSetPageMetaDataAttrElement(dataAttrName); var mapping; if (metaData) { try { mapping = JSON.parse(metaData); if (!mapping) { // eslint-disable-next-line no-console console.log('Error - there was an empty page meta data element on the page !!'); } } catch (e) { // eslint-disable-next-line no-console console.log('Error - while parsing a JSON attribute of a page meta data !!'); // eslint-disable-next-line no-console console.log(e); } } else { // eslint-disable-next-line no-console console.log('Error - there was a missing page meta data element on the page !!'); } return mapping; }; var PAGE_MAPPING = getPageMappingFromMetaDataElement('data-page-type-mapping'); module.exports = { PAGE_MAPPING: PAGE_MAPPING, getOrSetPageMetaDataAttrElement: getOrSetPageMetaDataAttrElement, getPageMappingFromMetaDataElement: getPageMappingFromMetaDataElement }; /***/ }), /* 3 */ /***/ (function(module, exports) { 'use strict'; /** * Send GA4 event to GTM * @param {Object} object GA4 data object */ function ga4EventPush(object) { if (!object || !object.event) { return; } object.timestamp = Date.now(); // Clear the previous ecommerce object as suggested by google window.dataLayer.push({ ecommerce: null }); // Send data to GTM window.dataLayer.push(object); // eslint-disable-next-line no-console console.table(window.dataLayer); } /** * @description push in the data layer the impression of the page * @param visitorStatus {String} the status of the user: if it is logged is the customerID, guest if not * @param pageType {String} the type of the page, look at analytics-mapping for more information * @param url {String} the url of the page * @param userEmail {String} the user's email if logged, empty otherwhise */ function pageImpression(visitorStatus, pageType, url, userEmail) { window.dataLayer.push({ 'event': 'basicPageData', 'visitorStatus': visitorStatus || 'guest', 'pageType': pageType, 'pageURL': url, 'email': userEmail || '' }); } /** * @description push in the data layer the business hours data * @param businessHours object is a json that should have a structure like that: * {'freshchat': {'on': { 'days': {'mo': '7-12, 12:30-17', 'tu': '8-16', ...}}, 'off': { 'days': [ '14.5', '24.12', '11.4:: 7-18' ] }}} */ function businessHours(businessHours) { if (businessHours) { window.dataLayer.push({ 'event': 'businessHours', 'businessHours': businessHours }); } } /** * @description track the search data * @param isCategorySearch {Boolean} set true only if the user has landed on page by clicking a category * @param keyWord {String} the argoument of the search (could be the category name or the keyword inserted in the searchBar) * @param categoryID {String} the id of the category clicked (set null if it is not a category search) * @param numberOfResults {Int} the number of results (only if it is not a category search) */ function search(isCategorySearch, keyWord, categoryID, numberOfResults) { if (isCategorySearch) { window.dataLayer.push({ 'event': 'search', 'categoryID': categoryID, 'categoryName': keyWord, 'ecommerce': { 'search_term': keyWord } }); } else { window.dataLayer.push({ 'event': 'search', 'searchKeyword': keyWord, 'numberResults': numberOfResults, 'searchType': 'site search', 'ecommerce': { 'search_term': keyWord } }); } } /** * @description push in the data layer the impression of products * @param currencyCode {String} The unicode of the currency used * @param products {Object} contains collection of the products */ function trackProductImpression(currencyCode, products) { window.dataLayer.push({ 'event': 'ecommerceTrack', 'ecommerce': { 'currencyCode': currencyCode, 'impressions': products } }); } /** * @description push in the data layer the product variant data * @param currencyCode {String} The currency code used * @param products {Object} contains collection products */ function variantSelected(currencyCode, products) { window.dataLayer.push({ 'event': 'variantSelection', 'ecommerce': { 'currencyCode': currencyCode, 'impressions': products, 'detail': products } }); } /** * @description track the event addToCart * @param currencyCode {String} The currency code used * @param products {Object} contains collection products * @param pageType {String} the current page type, null if the function is invoked inside the PDP * @param customerEmail {String} the customer email if logged * @param customerPhone {String} the customer phone if logged * @param arTryonInfo {arTryonInfo} object with the tryon flags */ function addToCart(currencyCode, products, pageType, customerEmail, customerPhone, arTryonInfo) { var eventData = { 'event': 'addToCart', 'email': customerEmail, 'phone': customerPhone, 'ecommerce': { 'currencyCode': currencyCode, 'add': { 'products': products } } }; //IN-AR TRY ON if (arTryonInfo) { eventData.tryOnDesktopClick = arTryonInfo.tryOnDesktopClick; eventData.tryOnMobileRedirect = arTryonInfo.tryOnMobileRedirect; } if (pageType) { eventData.ecommerce.actionField = {}; eventData.ecommerce.actionField.list = pageType; eventData.ecommerce.actionField.action = 'add'; } window.dataLayer.push(eventData); } /** * @description track the remove from cart * @param products {List} contains collection products */ function removeFromCart(products) { window.dataLayer.push({ 'event': 'removeFromCart', 'ecommerce': { 'remove': { 'products': products } } }); } /** * @description push into the datalayer the checkout step data * @param step {int} The checkout's step * @param option {String} checkout's information, based on the steps * @param products {List} the products in the basket during the checkout */ function pushCheckoutData(step, option, products, customerEmail, customerPhone) { if (step === 1 && customerEmail && customerPhone) { window.dataLayer.push({ 'event': 'ecommerceTrack', 'email': customerEmail, 'phone': customerPhone, 'ecommerce': { 'checkout': { 'actionField': { 'step': step, 'option': option, 'action': 'checkout' }, 'products': products } } }); } else { window.dataLayer.push({ 'event': 'ecommerceTrack', 'ecommerce': { 'checkout': { 'actionField': { 'step': step, 'option': option, 'action': 'checkout' }, 'products': products } } }); } } /** * @description the standalone event for purchase, is launched always with the sixth checkout's step * @param purchaseData {Object} Purchase data: * id {String} the id of the order * revenue {Number} the revenue of the order * tax {Number} the tax total * shipping {Number} the order shipping cost * coupon {String} the name of the order coupon * products {List} a list of all products purchased * customerEmail {String} the customer email * customerPhone {String} the customer phone * adjustedMerchandizeTotalNetPrice {Decimal} order total net price * adjustedMerchandizeTotalTax {Decimal} order total tax */ function purchase(purchaseData) { window.dataLayer.push({ 'event': 'ecommerceTrack', 'email': purchaseData.customerEmail, 'phone': purchaseData.customerPhone, 'ecommerce': { 'purchase': { 'actionField': { 'id': purchaseData.id, 'affiliation': 'Bata', 'revenue': purchaseData.revenue, 'adjustedMerchandizeTotalNetPrice': purchaseData.adjustedMerchandizeTotalNetPrice, 'adjustedMerchandizeTotalTax': purchaseData.adjustedMerchandizeTotalTax, 'tax': purchaseData.tax, 'shipping': purchaseData.shipping, 'coupon': purchaseData.coupon.couponCodeName, 'action': 'purchase' }, 'products': purchaseData.products } } }); } /** * @description registration of new user into the Bata club * @param userId {String} the id of the user * @param accountType {String} the type of account used by the user, regular user as default value * @param socialNetwork {String} The social network used by the user to sign up, empty string as default value */ function registration(userId, email, phone, accountType, socialNetwork) { window.dataLayer.push({ 'event': 'customerContact', 'customerID': userId, 'email': email, 'phone': phone, 'accountType': accountType || 'regular user', 'socialNetwork': socialNetwork || '' }); } /** * @description login user into the Bata club * @param userCrmId {String} the crm id of the user * @param accountType {String} the type of account used by the user, regular user as default value * @param socialNetwork {String} The social network used by the user to sign up, empty string as default value */ function login(customerCrmId, email, accountType, socialNetwork) { window.dataLayer.push({ 'event': 'loggedIn', 'customerCrmId': customerCrmId, 'email': email, 'accountType': accountType || 'regular user', 'socialNetwork': socialNetwork || '' }); } /** * @description a product link is clicked from the user (exept from minicart) * @param currencyCode {String} The currency code used * @param pageType {String} the type of the page, look at analytics-mapping for more information * @param products {List} the list that contains the product clicked */ function productClick(currencyCode, pageType, products) { window.dataLayer.push({ 'event': 'productClick', 'ecommerce': { 'currencyCode': currencyCode, 'click': { 'actionField': { 'list': pageType, 'action': 'click' }, 'products': products } } }); } /** * @description register the impression of the promotions in PDP * @param promotions {List} A list of all the promotions displayed */ function promoImpression(promotions) { window.dataLayer.push({ 'event': 'promoView', 'ecommerce': { 'promoView': { 'promotions': promotions } } }); } /** * @description register the impression of a promotional banner */ function PageDesignerPromoImpression(promotions) { window.dataLayer.push({ 'event': 'ecommerceTrack', 'ecommerce': { 'promoView': { 'promotions': promotions } } }); } /** * @description register the click on a promotional banner */ function PageDesignerPromoClick(promotions) { window.dataLayer.push({ 'event': 'promotionClick', 'ecommerce': { 'promoClick': { 'promotions': promotions } } }); } /** * @description the generic GAevent, take a look into the official documentation to understand his scope */ function trackGAEvent(category, action, label, eventValue, notInteraction) { window.dataLayer.push({ 'event': 'GAevent', 'eventCategory': category || '', 'eventAction': action || '', 'eventLabel': label || '', 'eventValue': eventValue || 0, 'eventNotInteraction': notInteraction || false }); } // // Google Analytics 4 /** * GA4 add_payment_info event * @param {Object} checkoutData Checkout data * @param {Array.} items items Order items */ function ga4AddPaymentInfo(checkoutData, items) { ga4EventPush({ 'event': 'add_payment_info', 'ecommerce': { 'currency': checkoutData.currency, 'payment_type': checkoutData.paymentType, 'coupon': checkoutData.coupon, 'payment_method_saved': checkoutData.paymentMethodSaved, 'value': checkoutData.value, 'items': items } }); } /** * GA4 select_proceed_to_purchase * @param {Object} order order data */ function ga4SelectProceedPurchase(order) { ga4EventPush({ 'event': 'select_proceed_to_purchase', 'payment_type': order.defaultPaymentMethod, 'shipping_tier': order.shipping[0].selectedShippingMethod.displayName }); } function ga4SelectExpressCheckout(data) { ga4EventPush({ 'event': 'select_express_method', 'payment_type': data.paymentType }); } /** * GA4 add_shipping_info event * @param {Object} checkoutData Checkout data * @param {Array.} items items Order items */ function ga4AddShippingInfo(checkoutData, items) { ga4EventPush({ 'event': 'add_shipping_info', 'ecommerce': { 'currency': checkoutData.currency, 'shipping': checkoutData.shipping, 'shipping_tier': checkoutData.shippingTier, 'coupon': checkoutData.coupon, 'value': checkoutData.value, 'items': items } }); } /** * GA4 add_to_cart event * @param {String} currencyCode Two-letters currency code * @param {Number} value Product price * @param {Array.} items Products */ function ga4AddToCart(currencyCode, items, value) { ga4EventPush({ 'event': 'add_to_cart', 'ecommerce': { 'currency': currencyCode, 'value': value, 'items': items } }); } /** * GA4 add_to_wishlist event * @param {String} currencyCode Two-letters currency code * @param {Number} value Product price * @param {Array.} items Products */ function ga4AddToWishlist(currencyCode, items, value) { ga4EventPush({ 'event': 'add_to_wishlist', 'ecommerce': { 'currency': currencyCode, 'value': value, 'items': items } }); } /** * GA4 remove_from_wishlist event * @param {String} currencyCode Two-letters currency code * @param {Number} value Product price * @param {Array.} items Products */ function ga4RemoveFromWishlist(currencyCode, items, value) { ga4EventPush({ 'event': 'remove_from_wishlist', 'ecommerce': { 'currency': currencyCode, 'value': value, 'items': items } }); } /** * GA4 begin_checkout event * @param {String} currencyCode Two-letters currency code * @param {String} coupon List of used order-level coupons separated by | * @param {Number} value Product price * @param {Array.} items Cart items */ function ga4BeginCheckout(currencyCode, items, coupon, value) { ga4EventPush({ 'event': 'begin_checkout', 'ecommerce': { 'currency': currencyCode, 'coupon': coupon, 'value': value, 'items': items } }); } /** * GA4 checkout_progress event * @param {Object} checkoutData Checkout data object * @param {Array.} items Cart items */ function ga4CheckoutProgress(checkoutData, items) { ga4EventPush({ 'event': 'checkout_progress', 'step_label': checkoutData.stepLabel, 'step_number': checkoutData.stepNumber, 'ecommerce': { 'currency': checkoutData.currencyCode, 'coupon': checkoutData.coupon, 'value': checkoutData.value, 'items': items } }); } /** * GA4 clear_search event */ function ga4ClearSearch() { ga4EventPush({ 'event': 'clear_search' }); } /** * GA4 Save credit card information */ function ga4SaveCreditCard() { ga4EventPush({ 'event': 'save_credit_card' }); } /** * GA4 login event * @param {Object} loginData Login data */ function ga4Login(loginData) { ga4EventPush({ 'event': 'login', 'method': loginData.method, 'login_type': loginData.loginType, 'ecommerce': { 'customerCrmId': loginData.customerCrmId } }); } /** * GA4 purchase event * @param {Object} purchaseData Purchase related data * @param {Array.} items Order items */ function ga4Purchase(purchaseData, items) { ga4EventPush({ 'event': 'purchase', 'ecommerce': { 'currency': purchaseData.currency, 'payment_type': purchaseData.paymentType, 'shipping': purchaseData.shipping, 'shipping_tier': purchaseData.shippingTier, 'tax': purchaseData.tax, 'transaction_id': purchaseData.transactionId, 'coupon': purchaseData.coupon, 'value': purchaseData.value, 'adjustedMerchandizeTotalNetPrice': purchaseData.adjustedMerchandizeTotalNetPrice, 'adjustedMerchandizeTotalTax': purchaseData.adjustedMerchandizeTotalTax, 'bata_store': purchaseData.bataStore, 'cart_id': purchaseData.cartId, 'transaction_type': purchaseData.transactionType, 'email': purchaseData.email, 'items': items } }); } /** * GA4 remove_from_cart event * @param {String} currencyCode Two-letters currency code * @param {Number} value Product price * @param {Array.} items Cart items */ function ga4RemoveFromCart(currencyCode, items, value) { ga4EventPush({ 'event': 'remove_from_cart', 'ecommerce': { 'currency': currencyCode, 'value': value, 'items': items } }); } /** * GA4 select_item event * @param {String} currencyCode Two-letters currency code * @param {Array.} items Products */ function ga4SelectItem(currencyCode, items) { ga4EventPush({ 'event': 'select_item', 'ecommerce': { 'currency': currencyCode, 'items': items } }); } /** * GA4 select_colour event */ function ga4SelectColor(id, variant) { ga4EventPush({ 'event': 'select_color', 'item_id': id, 'item_variant': variant ? variant.toString() : "" }); } /** * GA4 select_size event */ function ga4SelectSize(id, variant) { ga4EventPush({ 'event': 'select_size', 'item_id': id, 'item_variant': variant ? variant.toString() : "" }); } /** * GA4 select_size_guide event */ function ga4SelectSizeGuide() { window.dataLayer.push({ 'event': 'select_size_guide' }); } /** * GA4 select_content event * @param {Object} contentData Content related data */ function ga4SelectContent(contentData) { ga4EventPush({ 'event': 'select_content', 'content_id': contentData.contentId, 'content_type': contentData.contentType, 'content_name': contentData.contentName }); } /** * GA4 select_promotion event * @param {Object} promotionData promotion related data */ function ga4SelectPromotion(promotionData) { ga4EventPush({ 'event': 'select_promotion', 'items': [{ 'creative_name': promotionData.promotionName, 'creative_slot': promotionData.index, 'location_id': promotionData.promotionId, 'promotion_id': promotionData.promotionId, 'promotion_name': promotionData.promotionName }] }); } /** * GA4 view_next_image_pdp event */ function ga4ViewNextImagePDP(imageData) { ga4EventPush({ 'event': 'view_next_image_pdp', 'item_id': imageData.itemId, 'item_variant': imageData.colorVariant }); } /** * GA4 select_size_wishlist event */ function ga4SelectWishlist() { window.dataLayer.push({ 'event': 'select_wishlist' }); } /** * GA4 start search event */ function ga4StartSearch() { ga4EventPush({ 'event': 'start_search' }); } /** * GA4 select_size_wishlist event */ function ga4SearchProduct(searchData) { ga4EventPush({ 'event': 'search', 'search_term': searchData.searchTerm, 'search_type': searchData.searchType }); } /** * GA4 share event * @param {Object} shareData Product */ function ga4Share(shareData) { ga4EventPush({ 'event': 'share', 'ecommerce': { 'method': shareData.method, 'content_type': shareData.contentType, 'item_id': shareData.itemId, 'element_id': shareData.elementId, 'element_text': shareData.elementText, 'link_url': shareData.linkUrl, 'link_domain': shareData.linkDomain, 'type': shareData.type } }); } /** * GA4 sign_up event * @param {Object} registrationData data */ function ga4SignUp(registrationData) { ga4EventPush({ 'event': 'sign_up', 'signup_form_type': registrationData.signupType, 'ecommerce': { 'customerCrmId': registrationData.customerCrmId } }); } /** * GA4 sign_up event in checkout * @param {Object} registrationData data */ function ga4SignUpCheckout(registrationData) { ga4EventPush({ 'event': 'sign_up', 'signup_form_type': registrationData.signupType }); } /** * GA4 view_cart event * @param {String} currencyCode Two-letters currency code * @param {String} coupon List of used order-level coupons separated by | * @param {Number} value Product price * @param {Array.} items Cart items */ function ga4ViewCart(currencyCode, items, coupon, value) { ga4EventPush({ 'event': 'view_cart', 'ecommerce': { 'currency': currencyCode, 'coupon': coupon, 'value': value, 'items': items } }); } /** * GA4 view_item event * @param {String} currencyCode Two-letters currency code * @param {Array.} items Products */ function ga4ViewItem(currencyCode, items, value) { ga4EventPush({ 'event': 'view_item', 'ecommerce': { 'currency': currencyCode, 'value': value, 'items': items } }); } /** * GA4 view_item_list event * @param {String} currencyCode Two-letters currency code * @param {Array.} items Products */ function ga4ViewItemList(currencyCode, items) { ga4EventPush({ 'event': 'view_item_list', 'ecommerce': { 'currency': currencyCode, 'items': items, "results_number": items.length } }); } /** * GA4 view_promotion event * @param {Array.} items Products */ function ga4ViewPromotion(items) { ga4EventPush({ 'event': 'view_promotion', 'ecommerce': { 'items': items } }); } /** * GA4 page_view event * @param {Object} pageData Page data */ function ga4PageView(pageData) { ga4EventPush({ 'event': 'page_view_ga4', 'page_type': pageData.pageType, 'page_url': pageData.pageURL, 'page_path': pageData.pagePath, 'country': pageData.country, 'email_marketing': pageData.emailMarketing, 'email': pageData.email, 'internal_client_id': pageData.internalClientId, 'login_status': pageData.loginStatus, 'user_gender': pageData.gender, 'user_id': pageData.userID, 'user_type': pageData.userType }); } /** * GA4 click_menu_nav event * @param {Number} menuLevel Menu level * @param {String} menuSelection Selected menu item name */ function ga4ClickMenuNav(menuLevel, menuSelection) { ga4EventPush({ 'event': 'click_menu_nav', 'menu_level': menuLevel, 'menu_selection': menuSelection }); } /** * GA4 click_filter event * @param {String} filterCategory Input type (Checkbox or Slider or ...) * @param {String} filterName Filter name * @param {String} filterValue Filter selected value */ function ga4ClickFilter(filterCategory, filterName, filterValue) { ga4EventPush({ 'event': 'click_filter', 'filter_category': filterCategory, 'filter_name': filterName, 'filter_value': filterValue }); } /** * GA4 scroll event * @param {Number} percent Screen scrolled in percent */ function ga4Scroll(percent) { ga4EventPush({ 'event': 'scroll', 'percent': percent }); } /** * GA4 subscribe event * @param {String} subscription_type Subscription type (newsletter) */ function ga4Subscribe(subscriptionType) { ga4EventPush({ 'event': 'subscribe', 'subscription_type ': subscriptionType }); } /** * GA4 open_pdp_image event */ function ga4OpenPdpImage() { ga4EventPush({ 'event': 'open_pdp_image' }); } function ga4SuccessfulSearch(searchData) { ga4EventPush({ 'event': 'successful_search', 'results_number': searchData.resultsNumber, 'search_method': searchData.searchMethod, 'search_term': searchData.searchTerm }); } function ga4UnsuccessfulSearch(searchData) { ga4EventPush({ 'event': 'unsuccessful_search', 'results_number': searchData.resultsNumber, 'search_method': searchData.searchMethod, 'search_term': searchData.searchTerm }); } function ga4ClickBackInStock(clickBackInStockData) { ga4EventPush({ 'event': 'click_email', 'element_id': clickBackInStockData.elementId, 'element_text': clickBackInStockData.elementText, 'link_url': clickBackInStockData.linkUrl }); } function ga4ClickDiscoverBrand(discoverBrandData) { ga4EventPush({ 'event': 'click_menu_nav', 'menu_level': discoverBrandData.menuLevel, 'menu_selection': discoverBrandData.menuSelection }); } function ga4BrandLogoComponent(eventData) { ga4EventPush({ 'event': 'click_menu_nav', 'menu_level': eventData.menuLevel, 'menu_selection': eventData.menuSelection }); } function ga4SelectBrandName(brandData) { ga4EventPush({ 'event': 'select_brand_name', 'page_type': 'product', 'page_url': brandData.pageUrl, 'button_position': brandData.buttonPosition }); } function ga4BrandSelectContent(selectContentData) { ga4EventPush({ 'event': 'select_content', 'content_id': selectContentData.contentId, 'content_type': selectContentData.contentType, 'content_name': selectContentData.contentName }); } /** * GA4 select_shop_at_bata event */ function ga4SelectShopAtBata() { ga4EventPush({ 'event': 'select_shop_at_bata' }); } /** * GA4 select_news event * @param {Object} contentData Content related data */ function ga4SelectNews(contentData) { ga4EventPush({ 'event': 'select_news', 'content_id': contentData.contentId, 'content_type': contentData.contentType }); } // End of Google Analytics 4 function ga4BrandSecondCategoryLevel(eventData) { ga4EventPush({ 'event': 'click_menu_nav', 'menu_level': eventData.menuLevel, 'menu_selection': eventData.menuSelection }); } /** * GA4 select_footer_menu event * @param {String} footer_selection Selected link * @param {String} level Wrapper of the link */ function ga4SelectFooterMenu(footer_selection, level) { var footerImg = footer_selection.find('img'); if (footer_selection.text().trim().length > 0) { // If text, return text footer_selection = footer_selection.text(); } else if (footerImg) { // If image, return title or alt attribute footer_selection = footerImg.attr('title') && footerImg.attr('title').length > 0 ? footerImg.attr('title') : footerImg.attr('alt') && footerImg.attr('alt').length > 0 ? footerImg.attr('alt') : 'image_without_text'; } else { // Fallback if no text or image footer_selection = 'unknown_selection'; } // Determine level of clicked link level = level.text().trim().length > 0 ? level.text().trim() : 'unknown_level'; dataLayer.push({ 'event': 'select_footer_menu', 'footer_selection': footer_selection, 'level': level }); } // End of Google Analytics 4 /** * AB testing interaction dataLayer event * @param {Array} array of AB tests (from abTests) */ function abTestInteraction(list, pageType) { if (!list) { return; } list.forEach(function (item) { window.dataLayer.push({ event: 'abTestInteraction', page_type: pageType && pageType.length > 0 ? pageType : 'other', variant_id: item.variant_id, variant_name: item.variant_name, version_type: item.version_type }); }); } module.exports = { productClick: productClick, search: search, pageImpression: pageImpression, trackProductImpression: trackProductImpression, promoImpression: promoImpression, PageDesignerPromoImpression: PageDesignerPromoImpression, PageDesignerPromoClick: PageDesignerPromoClick, variantSelected: variantSelected, addToCart: addToCart, removeFromCart: removeFromCart, pushCheckoutData: pushCheckoutData, purchase: purchase, registration: registration, login: login, trackGAEvent: trackGAEvent, ga4AddPaymentInfo: ga4AddPaymentInfo, ga4AddShippingInfo: ga4AddShippingInfo, ga4AddToCart: ga4AddToCart, ga4AddToWishlist: ga4AddToWishlist, ga4RemoveFromWishlist: ga4RemoveFromWishlist, ga4BeginCheckout: ga4BeginCheckout, ga4ClearSearch: ga4ClearSearch, ga4CheckoutProgress: ga4CheckoutProgress, ga4SaveCreditCard: ga4SaveCreditCard, ga4ClickBackInStock: ga4ClickBackInStock, ga4Login: ga4Login, ga4Purchase: ga4Purchase, ga4RemoveFromCart: ga4RemoveFromCart, ga4SelectItem: ga4SelectItem, ga4SelectColor: ga4SelectColor, ga4SelectSize: ga4SelectSize, ga4SelectContent: ga4SelectContent, ga4SelectPromotion: ga4SelectPromotion, ga4SelectWishlist: ga4SelectWishlist, ga4SearchProduct: ga4SearchProduct, ga4StartSearch: ga4StartSearch, ga4SuccessfulSearch: ga4SuccessfulSearch, ga4BrandSelectContent: ga4BrandSelectContent, ga4UnsuccessfulSearch: ga4UnsuccessfulSearch, ga4Share: ga4Share, ga4SignUp: ga4SignUp, ga4SignUpCheckout: ga4SignUpCheckout, ga4ViewNextImagePDP: ga4ViewNextImagePDP, ga4ViewCart: ga4ViewCart, ga4ViewItem: ga4ViewItem, ga4ViewItemList: ga4ViewItemList, ga4ViewPromotion: ga4ViewPromotion, ga4PageView: ga4PageView, ga4ClickMenuNav: ga4ClickMenuNav, ga4ClickFilter: ga4ClickFilter, ga4Scroll: ga4Scroll, ga4Subscribe: ga4Subscribe, ga4SelectSizeGuide: ga4SelectSizeGuide, ga4ClickDiscoverBrand: ga4ClickDiscoverBrand, ga4BrandLogoComponent: ga4BrandLogoComponent, ga4SelectBrandName: ga4SelectBrandName, ga4BrandSecondCategoryLevel: ga4BrandSecondCategoryLevel, ga4OpenPdpImage: ga4OpenPdpImage, businessHours: businessHours, abTestInteraction: abTestInteraction, ga4SelectProceedPurchase: ga4SelectProceedPurchase, ga4SelectFooterMenu: ga4SelectFooterMenu, ga4SelectShopAtBata: ga4SelectShopAtBata, ga4SelectNews: ga4SelectNews, ga4SelectExpressCheckout: ga4SelectExpressCheckout }; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var PageTypeMap = __webpack_require__(1); var events = __webpack_require__(3); var pageMetaDataUtils = __webpack_require__(2); //global variable used for orders var productOrder; var scrollPosition = { "25": false, "50": false, "75": false, "100": false }; /** * Returns the sales status of a product based on discount data. * @param {Object} product - jQuery or plain object representing the product. * @returns {string} - "on sale" if discounted, otherwise "full price". */ function getSalesStatus(product) { var isSalesStatus = product instanceof jQuery ? product.data('discount') : product.discount; return isSalesStatus ? "on sale" : "full price"; } /** * Extend analytics product with categories related to Google Analytics 4 * @param {Object} product Analytics product * @param {Object} productData Product data * @param {Object} attributeName Analytics product's attribute name (postfix number will be added) * @returns Extended analytics product */ function extendProductDataWithGA4Categories(product, productData, attributeName) { if (!product || !productData) { return; } attributeName = attributeName || 'category'; var index = void 0; var key = void 0; for (index = 1; index <= 5; index++) { if (productData) { if (!productData['category' + index]) { continue; } } key = attributeName + index; // GA4 first category attribute does not contain postfix number if (attributeName === 'item_category' && index === 1) { key = attributeName; } if (productData) { product[key] = productData['category' + index]; } } return product; } /** * GA4 Get item_list_id by product data * @param {Object} product Product object * @returns {String} GA4 list id */ function ga4GetProductItemListId(product) { if (!product) { return; } if (product.listId) { return product.listId; } // check saved list id after click on product tile if (window.bata_com_ns.analytics.pageType === "product" && document.referrer) { try { var listId = window.sessionStorage.getItem("analyticsListId"); if (listId) { window.sessionStorage.removeItem("analyticsListId"); $('.analytics-productPDP.analytics-product').data('listId', listId); return listId; } } catch (error) { // sessionStorage not supported } } // set current category id and path for PLP if (window.bata_com_ns.analytics.pageType === "category" || window.bata_com_ns.analytics.pageType === "brands") { var categoryId = $("div.grid-footer > input.category-id").val() || $('.js-analytics-search-category').data('analytics-category-id'); if (categoryId) { return categoryId; } else { return "product search result"; } } if (window.bata_com_ns.analytics.pageType === "product") { return "detail"; } return product.list || window.bata_com_ns.analytics.pageType; } /** * GA4 formatted product items * @param {Array} products Analytics products * @returns GA4 formatted product items list */ function ga4GetProducts(products) { if (!products || !products.length) { return []; } var mappedProducts = []; mappedProducts = products.map(function (product) { var isSalesStatus = getSalesStatus(product); var ga4Product = { item_id: product.id, item_name: product.name, index: product.position || 0, item_brand: product.brand, price: parseFloat(product.price), quantity: product.quantity || 1, item_dimension1: product.dimension1 || "", item_dimension2: product.dimension2 || "", item_dimension3: product.dimension3 || "", item_sales_status: isSalesStatus }; extendProductDataWithGA4Categories(ga4Product, product, 'item_category'); if (product.size) { ga4Product.item_size = product.size; } if (product.variant) { ga4Product.item_variant = product.variant; } if (product.coupon) { ga4Product.coupon = product.coupon; } if (product.discount) { ga4Product.discount = parseFloat(product.discount); } if (product.promotionName) { ga4Product.promotion_id = product.promotionName; ga4Product.promotion_name = product.promotionName; } ga4Product.item_list_id = ga4GetProductItemListId(product); ga4Product.item_list_name = ga4Product.item_list_id; if (product.genderName) { ga4Product.item_gender = product.genderName; } if (product.itemSeason) { ga4Product.item_season = product.itemSeason; } if (product.stockStatus) { ga4Product.item_stock_status = product.stockStatus; } if (product.list_name) { ga4Product.item_list_name = product.list_name; } return ga4Product; }); return mappedProducts; } /** * GA4 Get value of products * @param {Arrray} products products to be evaluated * @returns value of all products in array */ function ga4GetProductsValue(products) { var value = products.reduce(function (accumulator, product) { return accumulator + parseFloat(product.price) * product.quantity; }, 0); return parseFloat(value); } /** * GA4 Get cart page data */ function ga4GetCartData() { var $cartInfo = $('#analytics-cartInfo'); return { couponNames: $cartInfo.data('coupons-name'), value: $cartInfo.data('value') }; } /** * GA4 formatted promotion items * @param {Array} products Analytics promotions * @returns GA4 formatted promotion items list */ function ga4GetPromotions(promotions) { if (!promotions || !promotions.length) { return []; } var mappedPromotions = []; mappedPromotions = promotions.map(function (promotion) { return { item_id: promotion.id, promotion_id: promotion.id, promotion_name: promotion.name, creative_name: promotion.creative, creative_slot: promotion.position }; }); return mappedPromotions; } /** * @description extract the user email and phone from menuAccount - analytics-user, populated after login * @return user {obj} an object with the customer email and phone */ function getCustomerEmailAndPhone() { var $user = $('#analytics-user'); var customerEmail = $user.data('email') || ''; var customerPhone = $user.data('phone') || ''; return { customerEmail: customerEmail, customerPhone: customerPhone }; } /** * @description get the product tile information * @param $product {div} the analytics-product div where the data will be extracted * @return product {Object} a the product Object contains the analytics informations */ function getProductBaseData($product) { var product = { 'name': $product.data('name'), 'id': $product.data('id'), 'price': $product.data('price'), 'brand': $product.data('brand'), 'category': $product.data('category'), 'discount': $product.data('discount'), 'promotionName': $product.data('promotionName') }; var size = $product.data('size'); if (size) { product.size = size; } var listId = $product.data('listId'); if (listId) { product.listId = listId; } var genderName = $product.data('gender-name'); if (genderName) { product.genderName = genderName; } var itemSeason = $product.data('item-season'); if (itemSeason) { product.itemSeason = itemSeason; } var stockStatus = $product.data('stock-status'); if (stockStatus) { product.stockStatus = stockStatus; } return product; } /** * @description get the product tile information * @param $product {div} the analytics-tileproduct div where the data will be extracted * @return product {Object} a the product Object contains the analytics tiles informations */ function getProductTileData($product) { var color = $product.data('color'), size = $product.data('size'); var variant = size ? color + ' | ' + size : color; var product = getProductBaseData($product); product.variant = variant; // quantity var quantity = $product.data('quantity'); if (typeof quantity !== 'undefined' && quantity !== null && !isNaN(quantity)) { product.quantity = parseInt(quantity); } // custom attributes - dimensions var dimension1 = $product.data('dimension1'); if (dimension1) { product.dimension1 = dimension1; } var dimension2 = $product.data('dimension2'); if (dimension2) { product.dimension2 = dimension2; } var dimension3 = $product.data('dimension3'); if (dimension3) { product.dimension3 = dimension3; } // ga4 categories extendProductDataWithGA4Categories(product, $product.data()); return product; } /** * @description get the product tile information with also the three dimensions and the tryon * @param $product {div} the analytics-tileproduct div where the data will be extracted * @return product {Object} a the product Object contains the analytics informations */ function getProductTileDataExtended($product) { var product = getProductTileData($product); product.dimension1 = $product.data('dimension1'); product.dimension2 = $product.data('dimension2'); product.dimension3 = $product.data('dimension3'); //IN-AR TRY ON if ($product.data('opened-in-ar-tryon')) { product.openedInArTryon = $product.data('opened-in-ar-tryon'); } return product; } /** * @description extract all the products impressions from the dom * @param index {number} the index to start the position of the products * @return products {list} a list of all the products showed in page */ function getProductsData(index) { var products = [], product, $product; var position = index || 0; //track the plp products var $productsPLP = $('.analytics-ProductList .analytics-product.unregistered'); if ($productsPLP.length > 1) { $productsPLP.each(function () { $product = $(this); product = getProductTileData($product); $product.data('position', position); product.position = position; product.list = window.bata_com_ns.analytics.pageType; position++; products.push(product); $product.removeClass('unregistered'); }); } else { product = getProductTileData($productsPLP); if (!product.id) { return; } $productsPLP.data('position', position); product.position = position; product.list = window.bata_com_ns.analytics.pageType; position++; products.push(product); $productsPLP.removeClass('unregistered'); } window.bata_com_ns.analytics.productsDisplayed = position; return products; } /** * @description extract all the products impressions from the search dom * @param index {number} the index to start the position of the products * @return products {list} a list of all the products showed in page */ function getProductsDataSearch(index) { var products = [], product, $product; var position = index; var list = window.bata_com_ns.analytics.pageType + ' search suggestion'; //get the search products's data from the DOM var $productsSearch = $('.analytics-ProductList .analytics-product-search.unregistered'); if ($productsSearch.length > 1) { $productsSearch.each(function () { $product = $(this); product = getProductTileData($product); $product.data('position', position); product.position = position; product.list = list; product.item_list_id = list; position++; products.push(product); $product.removeClass('unregistered'); }); } else { product = getProductTileData($productsSearch); $productsSearch.data('position', position); product.position = position; product.list = list; product.item_list_id = list; position++; products.push(product); $productsSearch.removeClass('unregistered'); } return products; } /** * @description extract all the products impressions from the cart in dom (cart or minicart) * @param pageType {String} the location where the event is triggered * @return products {list} a list of all the products showed in cart */ function getProductsCartData(pageType, expressPayment) { var products = [], product, $product; var selector = '.analytics-cart > .analytics-product' + (expressPayment ? '' : '.unregistered'); var $productsElements = $(selector); if ($productsElements.length > 1) { $productsElements.each(function () { $product = $(this); product = getProductTileData($product); product.position = $product.data('position'); product.list = pageType; product.listId = $product.data('listId'); products.push(product); $product.removeClass('unregistered'); }); } else if ($productsElements.length === 1) { product = getProductTileData($productsElements); product.position = $productsElements.data('position'); product.list = pageType; product.listId = $productsElements.data('listId'); products.push(product); $productsElements.removeClass('unregistered'); } return products; } /** * @description extract all the products data from checkout page * @param step {Int} the checkout's step * @param isCartOpened {boolean} optional: set on true only for checkout's step where the products's data needs to be picked from cart or minicart * @return products {list} a list of all the products showed in checkout page */ function getCheckoutProducts(step, isCartOpened) { var products = [], product, $product, $checkoutProducts; //if the minicart was opened means that some products could have been deleted (available only in the first and second checkout step) if (step < 2 && isCartOpened) { //if the user is in cart page picks the product's data directly from the main cart (and not from the minicart) if (window.bata_com_ns.analytics.pageType === 'cart') { $checkoutProducts = $('.js-analytics-MainCart .analytics-cart > .analytics-product'); } else { $checkoutProducts = $('.analytics-cart > .analytics-product'); } } else { $checkoutProducts = $('.js-analytics-checkout > .analytics-product'); } var elementsFound = $checkoutProducts.length; if (elementsFound === 0) { products = productOrder; } else if (elementsFound > 1) { $checkoutProducts.each(function () { $product = $(this); product = getProductTileDataExtended($product); product.quantity = parseInt($product.data('quantity')); products.push(product); }); } else { product = getProductTileDataExtended($checkoutProducts); product.quantity = parseInt($checkoutProducts.data('quantity')); products.push(product); } return products; } /** * @description simulate a page impression for checkout updates * @param order {OrderModel} the relative order model */ function setCheckoutProducts(order) { productOrder = []; var products = order.items.items; var analyticsProduct, variants; products.forEach(function (product) { if (product.variationAttributes.length > 1) { variants = product.variationAttributes[0].displayValue + ' | ' + product.variationAttributes[1].localizedSize || product.variationAttributes[1].displayValue; } else { variants = product.variationAttributes[0].displayValue; } analyticsProduct = { 'name': product.productName, 'id': product.id, 'dimension1': product.masterProductID, 'dimension2': product.articleNo, 'dimension3': product.variationGroupID, 'price': product.price.sales.decimalPrice, 'brand': product.brand, 'category': product.primaryCategoryID, 'variant': variants, 'quantity': product.quantity || 1, 'discount': product.discount, 'promotionName': product.promotionName, 'listId': product.analyticsListId, 'genderName': product.genderName, 'itemSeason': product.itemSeason, 'stockStatus': product.stockStatus }; if (product.size) { analyticsProduct.size = product.size; } extendProductDataWithGA4Categories(analyticsProduct, product); productOrder.push(analyticsProduct); }); } /** * @description extract the page type from the dom * @return pageType {String} the type of the page, mapped on analytics-pagemapping.js */ function getPageType() { var pageType = $('.page-meta-data').data('page-type'); return pageType; } /** * @description determine if this is a search page and proceed to extract search's data, the track the event */ function searchHelper() { var $search = $('.js-analytics-search-keyword'); var isCategorySearch = false, keyword = null, categoryId = null, numberOfResults = null; if ($search.length > 0) { numberOfResults = $search.data('analytics-results-number'); } else { //it's a category search isCategorySearch = true; $search = $('.js-analytics-search-category'); categoryId = $search.data('analytics-category-id'); } keyword = $search.data('analytics-keyword'); if (keyword && keyword.length > 0) { var searchData = { resultsNumber: numberOfResults && numberOfResults > 0 ? numberOfResults : 0, searchMethod: "standard", searchTerm: keyword }; if (searchData.resultsNumber > 0) { events.ga4SuccessfulSearch(searchData); } else { events.ga4UnsuccessfulSearch(searchData); } } events.search(isCategorySearch, keyword, categoryId, numberOfResults); } /** * @description extract the data from the PDP dom and return a product formatted * @return product {Object} the product formatted */ function getPDPProduct() { var $product = $('.analytics-productPDP'); var color = $product.data('color'), size = $product.data('size'); var variant = size ? color + ' | ' + size : color; var isSalesStatus = getSalesStatus($product); var product = { 'name': $product.data('name'), 'id': $product.data('id'), 'dimension1': $product.data('dimension1'), 'dimension2': $product.data('dimension2'), 'dimension3': $product.data('dimension3'), 'price': $product.data('price'), 'brand': $product.data('brand'), 'category': $product.data('category'), 'description': $product.data('description'), 'productUrl': $product.data('canonicalUrl'), 'categoryUrl': $product.data('categoryurl'), 'imageUrl': $product.data('imageurl'), 'variant': variant, 'promotionName': $product.data('promotionName'), 'discount': $product.data('discount'), 'listId': $product.data('listId'), 'genderName': $product.data('gender-name'), 'itemSeason': $product.data('item-season'), 'stockStatus': $product.data('stock-status'), 'itemSalesStatus': isSalesStatus }; if (size) { product.size = size; } extendProductDataWithGA4Categories(product, $product.data()); return product; } /** * @description get all the products's impression from the DOM * @return products {List} a list of products impression */ function getProductDataPDP() { var products = []; var product = getPDPProduct(); products.push(product); return products; } /** * @description get the product tile information * @param $product {div} the analytics-tileproduct div where the data will be extracted * @return product {Object} a the product Object contains the analytics informations */ function getProductClickTileData($product) { var color = $product.data('color'), size = $product.data('size'); var variant = size ? color + ' | ' + size : color; var isSalesStatus = getSalesStatus($product); var product = { 'name': $product.data('name'), 'id': $product.data('id'), 'dimension1': $product.data('dimension1'), 'dimension2': $product.data('dimension2'), 'dimension3': $product.data('dimension3'), 'price': $product.data('price'), 'brand': $product.data('brand'), 'category': $product.data('category'), 'position': $product.data('position'), 'variant': variant, 'discount': $product.data('discount'), 'promotionName': $product.data('promotionName'), 'list': window.bata_com_ns.analytics.pageType, 'listId': $product.data('listId'), 'genderName': $product.data('gender-name'), 'itemSeason': $product.data('item-season'), 'stockStatus': $product.data('stock-status'), 'item_sales_status': isSalesStatus }; if (size) { product.size = size; } extendProductDataWithGA4Categories(product, $product.data()); return product; } /** * @description get all the promo informations, then launch the event */ function promoHelper(promotions) { if (promotions && promotions.length > 0) { var promo, analyticsPromotionsData = []; //get all promotions data and build the analytics promo object for (var i = 0; i < promotions.length; i++) { promo = promotions[i]; analyticsPromotionsData.push({ 'id': promo.id, 'name': promo.name, 'creative': '', 'position': promo.rank || 'center' }); } var ga4Promotions = ga4GetPromotions(analyticsPromotionsData); events.ga4ViewPromotion(ga4Promotions); events.promoImpression(analyticsPromotionsData); } } /** * @description get all the promo information from the DOM, then process to pass the formatted data */ function promoImpressionHelper() { var $promo = $('span.analytics-promotion'); var promotions = [], promo = { 'id': $promo.data('id'), 'name': $promo.data('name'), 'rank': $promo.data('rank') }; promotions.push(promo); promoHelper(promotions); } /** * @description get all the pagedesigner promo information from the DOM, then process to pass the formatted data */ function PageDesignerPromoImpressionHelper() { var analyticsPromotionsData = []; var $productsElements = $('.js-analytics-banner'); if ($productsElements.length > 1) { $productsElements.each(function () { var $banner = $(this); if ($banner.data("analytics-title") && $banner.data("analytics-title") !== "" && $banner.data("analytics-title") !== "No title") { analyticsPromotionsData.push({ 'id': $banner.data("analytics-title"), 'name': $banner.data("analytics-title") }); } }); if (analyticsPromotionsData.length) { var ga4Promotions = ga4GetPromotions(analyticsPromotionsData); events.ga4ViewPromotion(ga4Promotions); events.PageDesignerPromoImpression(analyticsPromotionsData); } } } /** * @description Extract the data from the variation product, then call the event * @param product {Object} The new variation product selected */ function variationClickHelper(product, variationType) { // The master category is always contained in the last breadcrumb, so the variation group ID var masterCategory = product.breadcrumbs && product.breadcrumbs.length > 0 ? product.breadcrumbs[product.breadcrumbs.length - 1] : null; // Extract product details var productName = product.productName, productID = product.id, masterProductID = product.masterProductID, articleNo = product.custom.articleNo, variationGroupID = masterCategory ? masterCategory.variationGroupID : '', price = product.price.sales.decimalPrice, brand = product.brand, categoryID = masterCategory ? masterCategory.id : '', description = product.longDescription, productUrl = product.canonicalUrl, categoryUrl = masterCategory ? new URL(masterCategory.url, document.baseURI).href : '', imageUrl = product.images.large[0].url, promotionName = product.promotionName, discount = product.discount, isSalesStatus = getSalesStatus(product), stockStatus = product.stockStatus, genderName = product.genderName, itemSeason = product.itemSeason, color, size, variation; // Detect the color selected for (var i = 0; i < product.variationAttributes[0].values.length; i++) { variation = product.variationAttributes[0].values[i]; if (variation.selected) { color = variation.displayValue; } } // Detect the size selected, only if the size variation exist for (var _i = 0; _i < product.variationAttributes[1].values.length; _i++) { variation = product.variationAttributes[1].values[_i]; if (variation.selected) { size = variation.localizedSize || variation.displayValue; } } var variant = size ? color + ' | ' + size : color; var $analyticsProduct = $('.analytics-productPDP'); // Prepare the products object for analytics var products = [{ 'name': productName, 'id': productID, 'dimension1': masterProductID, 'dimension2': articleNo, 'dimension3': variationGroupID, 'price': price, 'brand': brand, 'category': categoryID, 'description': description, 'productUrl': productUrl, 'categoryUrl': categoryUrl, 'imageUrl': imageUrl, 'variant': variant, 'promotionName': promotionName, 'discount': discount, 'listId': $analyticsProduct.data('listId'), 'genderName': genderName, 'itemSeason': itemSeason, 'stockStatus': stockStatus, 'item_sales_status': isSalesStatus }]; if (size) { products.size = size; } extendProductDataWithGA4Categories(products[0], product); // Launch the event variantSelected events.variantSelected(window.bata_com_ns.analytics.currency, products); // Update the analytics producs data in the DOM, so it's ready for addToCart event $analyticsProduct.data('name', productName); $analyticsProduct.data('id', productID); $analyticsProduct.data('dimension1', masterProductID); $analyticsProduct.data('dimension2', articleNo); $analyticsProduct.data('dimension3', variationGroupID); $analyticsProduct.data('price', price); $analyticsProduct.data('brand', brand); $analyticsProduct.data('category', categoryID); $analyticsProduct.data('description', description); $analyticsProduct.data('canonicalUrl', productUrl); $analyticsProduct.data('categoryurl', categoryUrl); $analyticsProduct.data('imageurl', imageUrl); $analyticsProduct.data('color', color); $analyticsProduct.data('size', size); $analyticsProduct.data('category1', product.category1); $analyticsProduct.data('category2', product.category2); $analyticsProduct.data('category3', product.category3); $analyticsProduct.data('category4', product.category4); $analyticsProduct.data('category5', product.category5); $analyticsProduct.data('discount', product.discount); $analyticsProduct.data('promotionName', product.promotionName); $analyticsProduct.data('gender-name', genderName); $analyticsProduct.data('item-season', itemSeason); $analyticsProduct.data('stock-status', stockStatus); $analyticsProduct.data('item_sales_status', isSalesStatus); // Also collect the new possible promotions displayed promoHelper(product.promotions); // Update PDP analytics data for "share" event if (window.bata_com_ns.analytics.pageType === "product") { $('ul.social-icons').data('analytics-pid', variationGroupID); } } /** * @description simulate a page impression for checkout updates */ function checkoutUpdate() { var $user = $('#analytics-user'); var $checkout = $('#checkout-main'); var step = $checkout.attr('data-checkout-stage'); step = PageTypeMap.PAGE_MAPPING[step] || step; window.bata_com_ns.analytics.pageType = step; var customerEmailMarketing = $user.data('email-marketing').toString(); var customerEmail = $user.data('email'); var customerCrmId = $user.data('customer-crm-id'); var customerGender = $user.data('user-gender'); var customerId = $user.data('customerid'); var customerType = $user.data('order-count') > 0 ? 'existing' : 'new'; // set page-meta tag so that it's in sync with window.bata_com_ns.analytics.pageType pageMetaDataUtils.getOrSetPageMetaDataAttrElement('data-analytics-page-type', step); // set page-meta tag so that it's in sync with page's pageType pageMetaDataUtils.getOrSetPageMetaDataAttrElement('data-page-type', pageMetaDataUtils.PAGE_MAPPING[step] || step); events.pageImpression(customerType, step, window.location.href, customerEmail); var ga4CrmId = customerCrmId && customerCrmId !== 'guest' ? customerCrmId : null; var ga4Email = customerEmail && customerEmail !== 'guest' ? customerEmail : null; events.ga4PageView({ pageType: step, pageURL: window.location.origin, pagePath: window.location.pathname, country: window.bata_com_ns.analytics.country, emailMarketing: customerEmailMarketing, email: ga4Email || undefined, internalClientId: customerId, loginStatus: ga4CrmId ? "true" : "false", gender: customerGender, userID: ga4CrmId || undefined, userType: ga4CrmId ? customerType : "guest" }); } /** * @description simulate a page impression for checkout updates * @param $analyticsProduct {element} the div(s) that contains all the product's data * @returns products {List} a list that contains the product'data clicked */ function productClickHelper($analyticsProduct) { var products = [], product; //if the minicart is opened, there can be multiple tile of the same product, so pick the first one available $analyticsProduct = $analyticsProduct.length > 1 ? $analyticsProduct.first() : $analyticsProduct; product = getProductClickTileData($analyticsProduct); products.push(product); return products; } /** * @description launch both of the events for addToCart event * @param $product {element} the div that contains all the product's data * @param arTryonInfo {arTryonInfo} IN-AR TRY ON object with the tryon flags */ function addToCartHelper($product, arTryonInfo) { var product, products = [], pageType = window.bata_com_ns.analytics.pageType, pageView; if (pageType !== 'product' && $product) { product = getProductTileDataExtended($product); product.list = pageType; pageView = PageTypeMap.CART_MAPPING[pageType]; } else { product = getPDPProduct(); } product.quantity = 1; products.push(product); var currUser = getCustomerEmailAndPhone(), ga4Products = ga4GetProducts(products); events.ga4AddToCart(window.bata_com_ns.analytics.currency, ga4Products, parseFloat(product.price) * product.quantity); events.addToCart(window.bata_com_ns.analytics.currency, products, pageView, currUser.customerEmail, currUser.customerPhone, arTryonInfo); events.trackGAEvent(pageType, 'add to bag', product.id); } /** * @description launch both of the events for removeFromCart event * @param $product {element} the div that contains all the product's data * @param pageType {String} the page type where the product is removed * @param singleItem {String} only single item was removed from a cart */ function removeFromCartHelper($product, pageType, singleItem) { var product, products = []; product = getProductTileData($product); product.position = $product.data('position'); product.quantity = singleItem ? 1 : parseInt($product.data('quantity')); product.list = pageType; product.dimension1 = $product.data('dimension1'); product.dimension2 = $product.data('dimension2'); product.dimension3 = $product.data('dimension3'); products.push(product); var ga4Products = ga4GetProducts(products); events.ga4RemoveFromCart(window.bata_com_ns.analytics.currency, ga4Products, ga4GetProductsValue(ga4Products)); events.removeFromCart(products); events.trackGAEvent(pageType, 'remove', product.id); } /** * @description launch the event addToWishlist * @param pid {String} the product's ID added */ function addToWishlistHelper(pid, $product) { var product = getProductClickTileData($product); var ga4Products = ga4GetProducts([product]); events.ga4AddToWishlist(window.bata_com_ns.analytics.currency, ga4Products, parseFloat(product.price || 0)); events.trackGAEvent(PageTypeMap.WISHLIST_MAPPING[window.bata_com_ns.analytics.pageType], 'wishlist add', pid); } /** * @description launch the event removeFromWishlist * @param pid {String} the product's ID removed */ function removeFromWishlistHelper(pid, $product) { var product = getProductClickTileData($product); var ga4Products = ga4GetProducts([product]); events.ga4RemoveFromWishlist(window.bata_com_ns.analytics.currency, ga4Products, parseFloat(product.price || 0)); events.trackGAEvent(PageTypeMap.WISHLIST_MAPPING[window.bata_com_ns.analytics.pageType], 'wishlist remove', pid); } /** * @description launch the checkout's events * @param step {int} the checkout's step * @param options {Object} various information, step based * @param isMiniCartOpened {boolean} optional: set on true only for checkout's second step, if the minicart has been opened */ function checkouStepHelper(step, options, isMiniCartOpened) { var products = getCheckoutProducts(step, isMiniCartOpened); var currUser = getCustomerEmailAndPhone(); // GA4 begin_checkout (cart -> checkout) if (step === 1) { var ga4Products = ga4GetProducts(products); var ga4CartData = ga4GetCartData(); events.ga4BeginCheckout(window.bata_com_ns.analytics.currency, ga4Products, ga4CartData.couponNames, ga4CartData.value); } //checkout inversion if (step === 2) { var _ga4Products = ga4GetProducts(products); var _ga4CartData = ga4GetCartData(); var checkoutData = { currencyCode: window.bata_com_ns.analytics.currency, coupon: _ga4CartData && _ga4CartData.couponNames, value: _ga4CartData && _ga4CartData.value, stepLabel: "customer info", stepNumber: 2 }; events.ga4CheckoutProgress(checkoutData, _ga4Products); } // GA4 checkout_progress (payment page load) if (step === 3) { var _ga4Products2 = ga4GetProducts(products); var _ga4CartData2 = ga4GetCartData(); var _checkoutData = { currencyCode: window.bata_com_ns.analytics.currency, coupon: _ga4CartData2 && _ga4CartData2.couponNames, value: _ga4CartData2 && _ga4CartData2.value, stepLabel: "payment info", stepNumber: 3 }; events.ga4CheckoutProgress(_checkoutData, _ga4Products2); } events.pushCheckoutData(step, options, products, currUser.customerEmail, currUser.customerPhone); } /** * @description launch the checkout's events * @param step {int} the checkout's step * @param options {Object} various information, step based * @param order {Object} the order in execution */ function updateCheckoutData(step, options, order) { var option; // in case of multiple payment methods concatenate them (only for CO step 4) if (step === 4) { for (var i = 0; i < options.length; i++) { if (i === 0) { option = options[i].paymentMethod; } else { option += ' | ' + options[i].paymentMethod; } } } else { option = options; } setCheckoutProducts(order); var products = productOrder; // GA4 payment if (step === 4 && order) { var ga4Products = ga4GetProducts(products); var checkoutData = { currency: window.bata_com_ns.analytics.currency, paymentType: order.billing && order.billing.payment && order.billing.payment.selectedPaymentInstruments && order.billing.payment.selectedPaymentInstruments.length && order.billing.payment.selectedPaymentInstruments[0].labelMethod, coupon: order.couponsName, paymentMethodSaved: order.paymentMethodSaved, value: order.totals && order.totals.grandTotalDecimal }; events.ga4AddPaymentInfo(checkoutData, ga4Products); events.ga4SelectProceedPurchase(order); } events.pushCheckoutData(step, option, products); } /** * @description launch the express checkout event * @param order {Object} the order in execution */ function expressCheckout(order) { var products = getProductsCartData(getPageType(), true); var ga4Products = ga4GetProducts(products); var paymentType = order.billing && order.billing.payment && order.billing.payment.selectedPaymentInstruments && order.billing.payment.selectedPaymentInstruments.length && order.billing.payment.selectedPaymentInstruments[0].labelMethod; var cartData = { coupon: order.couponsName, currency: window.bata_com_ns.analytics.currency, paymentMethodSaved: false, value: order.totals && order.totals.grandTotalDecimal, paymentType: paymentType }; events.ga4AddPaymentInfo(cartData, ga4Products); var data = { defaultPaymentMethod: paymentType, shipping: order.shipping }; events.ga4SelectProceedPurchase(data); } /** * @description launch the click express checkout button event * @param data {Object} contains the selected express checkout payment method */ function selectExpressCheckout(data) { events.ga4SelectExpressCheckout(data); } /** * @description launch the event order confirmation */ function orderConfirmHelper() { var step = 5; var products = getCheckoutProducts(step, false); events.pushCheckoutData(step, 'orderconfirmation', products); var $checkoutInfo = $('#analytics-checkoutInfo'); var coupon = { 'couponCodeName': $checkoutInfo.data('coupons-name'), 'couponDiscount': $checkoutInfo.data('coupons-discount') }; var currUser = getCustomerEmailAndPhone(); var couponNames = coupon.couponCodeName; var ga4Products = ga4GetProducts(products); var ga4PurchaseData = { currency: window.bata_com_ns.analytics.currency, affiliation: 'Bata', transactionId: $checkoutInfo.data('id'), value: parseFloat($checkoutInfo.data('revenue')), shipping: parseFloat($checkoutInfo.data('shipping')), shippingTier: $checkoutInfo.data('shipping-tier'), paymentType: $checkoutInfo.data('payment-type'), tax: $checkoutInfo.data('tax'), adjustedMerchandizeTotalNetPrice: $checkoutInfo.data('adjustedMerchandizeTotalNetPrice'), adjustedMerchandizeTotalTax: $checkoutInfo.data('adjustedMerchandizeTotalTax'), bataStore: $checkoutInfo.data('bataStore'), cartId: $checkoutInfo.data('cartId'), transactionType: $checkoutInfo.data('transactionType'), email: $checkoutInfo.data('email') }; if (couponNames) { ga4PurchaseData.coupon = couponNames; } events.ga4Purchase(ga4PurchaseData, ga4Products); events.purchase({ id: $checkoutInfo.data('id'), revenue: $checkoutInfo.data('revenue'), tax: $checkoutInfo.data('tax'), shipping: $checkoutInfo.data('shipping'), coupon: coupon, products: products, customerEmail: currUser.customerEmail, customerPhone: currUser.customerPhone, adjustedMerchandizeTotalNetPrice: $checkoutInfo.data('adjustedMerchandizeTotalNetPrice'), adjustedMerchandizeTotalTax: $checkoutInfo.data('adjustedMerchandizeTotalTax') }); } /** * @description update the analytics product quantity in Cart page * @param productID {String} the product's ID * @param quantity {Int} the quantity of the product */ function updateProductQuantity(productID, quantity) { var analyticsSelector = '.js-analytics-MainCart .analytics-product.' + productID; $(analyticsSelector).data('quantity', quantity); } /** * @description gets business hours (they are defined within Site preferences - businessHours field) */ function getBusinessHours() { var $bh = $('.analytics-businessHours'); var content = $bh && $bh.length ? $bh.data('content') : null; return content; } /** * @description extract the data from the cart unavailability modal and fire removeFromCart event */ function removeFromCartByUnavailabilityModal() { var products = [], $product, $removedProducts = $('#unavailableProductsModal .cc-cart-item'); var elementsFound = $removedProducts.length; if (elementsFound > 0) { $removedProducts.each(function () { $product = $(this); var product = {}; product.id = $product.data('id'); product.quantity = parseInt($product.data('quantity')); product.price = $product.data('priceTotal'); products.push(product); }); } var ga4Products = ga4GetProducts(products); events.ga4RemoveFromCart(window.bata_com_ns.analytics.currency, ga4Products, ga4GetProductsValue(ga4Products)); events.removeFromCart(products); } /** * Track recommendations products view * @param {Object} recommendationContainer recommendation element */ function trackRecommendationsLists(recommendationContainer) { var product, $product, $recommendation; // loop recommendations carousels var $recommendations = $(recommendationContainer) || $('.recommendations'); if ($recommendations.length > 0) { $recommendations.each(function () { $recommendation = $(this); var position = 0; var products = []; var recommendationName = $recommendation.find('.carousel-title').first().html().trim() || 'recommendation'; var $products = $recommendation.find('.analytics-product.unregistered'); if ($products.length > 0) { // loop products in a recommendation carousel $products.each(function () { $product = $(this); product = getProductTileData($product); // skip invalid product if (!product.id) { return; } product.position = position; $product.data('position', position); product.listId = recommendationName; $product.data('listId', recommendationName); position++; products.push(product); $product.removeClass('unregistered'); }); } if (products.length === 0) { return; } // enhance product object with GA4 attributes var ga4Products = ga4GetProducts(products); // track products view event events.ga4ViewItemList(window.bata_com_ns.analytics.currency, ga4Products); }); } return; } /** * Track scroll position */ function trackScrollPosition() { var scrollPercent = ($(window).scrollTop() / ($(document).height() - $(window).height()) * 100).toFixed(); [25, 50, 75, 100].some(function (position) { if (scrollPercent < position) { return true; } if (scrollPercent >= position && !scrollPosition[position.toString()]) { scrollPosition[position.toString()] = true; events.ga4Scroll(position); return true; } }); } /** * Parse abTests data off the page's DOM * Only active and visible ab tests are there (div's data) */ function getABtestsDataFromDOM(abTestId) { var list = []; $('.abTestsSegmentData').each(function () { var id = $(this).data('id'); var segment = $(this).data('segment'); if (typeof id !== 'undefined' && id !== null && id.length > 0 && typeof segment !== 'undefined' && segment !== null && segment.length > 0 && (!(typeof abTestId !== 'undefined' && abTestId !== null && abTestId.length > 0) || abTestId === id)) { var params = { variant_id: id, variant_name: segment, version_type: $(this).data('is-control-segment') ? 'control' : 'variant' }; list.push(params); } }); return list; } /** * Call ab test interection event that pushes active ab test data to the dataLayer * @param {Object} params - example: {abTestId: null, pageType: 'other'} */ function callAbTestInteraction(params) { var abTestId = null; var pageType = 'other'; if (params) { abTestId = params.abTestId && params.abTestId.length > 0 ? params.abTestId : abTestId; if (params.pageType && params.pageType.length > 0) { pageType = params.pageType; } else if (window.bata_com_ns && window.bata_com_ns.pageType && window.bata_com_ns.pageType.length > 0) { pageType = window.bata_com_ns.pageType; } } events.abTestInteraction(getABtestsDataFromDOM(abTestId), pageType); } module.exports = { extendProductDataWithGA4Categories: extendProductDataWithGA4Categories, ga4GetProductItemListId: ga4GetProductItemListId, ga4GetProducts: ga4GetProducts, ga4GetPromotions: ga4GetPromotions, productClickHelper: productClickHelper, getProductTileDataExtended: getProductTileDataExtended, variationClickHelper: variationClickHelper, checkoutUpdate: checkoutUpdate, expressCheckout: expressCheckout, addToCartHelper: addToCartHelper, getProductsCartData: getProductsCartData, removeFromCartHelper: removeFromCartHelper, addToWishlistHelper: addToWishlistHelper, removeFromWishlistHelper: removeFromWishlistHelper, getPageType: getPageType, searchHelper: searchHelper, getProductDataPDP: getProductDataPDP, getProductsData: getProductsData, getProductsDataSearch: getProductsDataSearch, checkouStepHelper: checkouStepHelper, getCheckoutProducts: getCheckoutProducts, orderConfirmHelper: orderConfirmHelper, updateCheckoutData: updateCheckoutData, setCheckoutProducts: setCheckoutProducts, promoHelper: promoHelper, promoImpressionHelper: promoImpressionHelper, getProductClickTileData: getProductClickTileData, updateProductQuantity: updateProductQuantity, removeFromCartByUnavailabilityModal: removeFromCartByUnavailabilityModal, PageDesignerPromoImpressionHelper: PageDesignerPromoImpressionHelper, getBusinessHours: getBusinessHours, ga4GetCartData: ga4GetCartData, trackRecommendationsLists: trackRecommendationsLists, trackScrollPosition: trackScrollPosition, getABtestsDataFromDOM: getABtestsDataFromDOM, callAbTestInteraction: callAbTestInteraction, selectExpressCheckout: selectExpressCheckout }; /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var utils = __webpack_require__(4); var events = __webpack_require__(3); /** * @description variationClick listener * @param response {Object} an object that contains the fullproduct as an attribute (response.product) */ $('body').on('product:afterAttributeSelect', function (e, response) { var variationType = 'unknown'; // Default value var variationElement; if (response.container && Array.isArray(response.container.prevObject) && response.container.prevObject.length > 0 && response.container.prevObject[0]) { variationElement = response.container.prevObject[0].className || ''; if (variationElement.includes('size')) { variationType = 'size'; } else if (variationElement.includes('color')) { variationType = 'color'; } } utils.variationClickHelper(response.data.product, variationType); }); /** * @description addToCart listener * @param data {Object} a data object containing: * -productID: the id of the product added to the cart with pageType, * -tryOnDesktopClick: true if the user clicked on the tryon button on Desktop, * -tryOnMobileRedirect: true if the user used the tryon funcionality and got redirected back on Mobile */ $('body').on('analytics:addToCart', function (e, data) { var $product, analyticsTileSelector = '.analytics-ProductList .analytics-product.' + data.productID, tile = $(analyticsTileSelector), //IN-AR TRY ON arTryonInfo = {}; //tryOnDesktopClick and tryOnMobileRedirect are not null only if the tryon logic is active if (data.tryOnDesktopClick && data.tryOnDesktopClick !== null && data.tryOnMobileRedirect && data.tryOnMobileRedirect !== null) { arTryonInfo.tryOnDesktopClick = data.tryOnDesktopClick; arTryonInfo.tryOnMobileRedirect = data.tryOnMobileRedirect; } else { arTryonInfo = null; } //the tile will be > 0 only if the event is originated outside the PDP if (tile.length > 0) { $product = tile; } else { $product = $('.analytics-productPDP'); } if (data.pageType === 'cart') { analyticsTileSelector = '.analytics-cart > .analytics-product.' + data.productID; tile = $(analyticsTileSelector); $product = tile; } utils.addToCartHelper($product, arTryonInfo); }); /** * @description removeFromCart listener * @param pid {String} the id of the product added to the cart * @param pageType {String} the page type where the action is committed */ $('body').on('analytics:removeFromCart', function (e, data) { var $product; //the cart tiles must be the at first child level of analytics-cart var analyticsTileSelector = '.analytics-cart > .analytics-product.' + data.productID; var tile = $(analyticsTileSelector); $product = tile; utils.removeFromCartHelper($product, data.pageType, data.singleItem); }); $('body').on('analytics:selectExpressCheckout', function (e, data) { utils.selectExpressCheckout(data); }); $('body').on('analytics:expressCheckout', function (e, order) { utils.expressCheckout(order); }); /** * @description removeFromCartBySystem listener */ $('body').on('analytics:removeFromCartBySystem', function () { utils.removeFromCartByUnavailabilityModal(); }); /** * @description addToWishlist listener * @param pid {String} the id of the product added */ $('body').on('analytics:addToWishlist', function (e, pid) { var $analyticsProduct; if (utils.getPageType() === "product") { // PDP $analyticsProduct = $('.analytics-productPDP'); } else { $analyticsProduct = $('.analytics-product.' + pid); } utils.addToWishlistHelper(pid, $analyticsProduct); }); /** * @description removeFromWishlist listener * @param pid {String} the id of the product removed */ $('body').on('analytics:removeFromWishlist', function (e, pid) { var $analyticsProduct; if (utils.getPageType() === "product") { $analyticsProduct = $('.analytics-productPDP'); } else { $analyticsProduct = $('.analytics-product.' + pid); } utils.removeFromWishlistHelper(pid, $analyticsProduct); }); /** * @description launch the checkout update data and impressions */ $('body').on('analytics:checkoutUpdateState', function () { utils.checkoutUpdate(); }); /** * @description collect the new product impressions */ $('body').on('analytics:productsLoaded', function () { //get the number of the products already registered, then collect the new products and launch the impression var numberProductAlreadyDisplayed = window.bata_com_ns.analytics.productsDisplayed || 0; var products = utils.getProductsData(numberProductAlreadyDisplayed); var ga4Products = utils.ga4GetProducts(products); events.ga4ViewItemList(window.bata_com_ns.analytics.currency, ga4Products); events.trackProductImpression(window.bata_com_ns.analytics.currency, products); }); /** * @description collect the new search suggestion products */ $('body').on('analytics:searchProductLoaded', function (e, searchTerm) { var searchData = { resultsNumber: $('.js-analytics-searchProduct [id^="product-"]').length || 0, searchMethod: "autosuggested", searchTerm: searchTerm }; if (searchData.resultsNumber > 0) { var products = utils.getProductsDataSearch(0); var ga4Products = utils.ga4GetProducts(products); events.ga4SuccessfulSearch(searchData); events.ga4ViewItemList(window.bata_com_ns.analytics.currency, ga4Products); events.trackProductImpression(window.bata_com_ns.analytics.currency, products); } else { events.ga4UnsuccessfulSearch(searchData); } }); $('body').on('analytics:nextImagePDP', function () { var $activeItem = $('.slick-slide.slick-current.slick-active .js-analytics-nextImagePDP-active'); if (!$activeItem.length) { return; } var imageData = { itemId: $activeItem.data('product-id'), colorVariant: $activeItem.data('color-variant') }; events.ga4ViewNextImagePDP(imageData); }); /** * @description standard search */ $('body').on('analytics:searchProduct', function (e, searchTerm) { if (searchTerm && searchTerm.length) { var searchData = { searchTerm: searchTerm, searchType: "standard" }; events.ga4SearchProduct(searchData); } }); /** * @description user clicked on an product image on the product description page */ $(document).on('click', '.cc-pdp-carousel-item[data-target="#pdpImgModal"]', function () { events.ga4OpenPdpImage(); }); /** * @description It is triggered when a user clicks the "X" button on the search bar, which is * used to clear the text entered by the user. */ $(document).on('click', '.js-resetSearch.cc-search__reset', function () { events.ga4ClearSearch(); return true; }); /** * @description register the product click (PLP. CART, CAROUSELS ETC.) */ $(document).on('click', 'a.js-analytics-productClick', function (e) { e.preventDefault(); var $product = $(this); var url = $product.attr('href'), productId = $product.data('analytics-product-id'), $analyticsProduct = void 0; if ($product.hasClass("js-analytics-suggestionProduct")) { // Product suggestion on product search $analyticsProduct = $('.analytics-product-search.' + productId); } else { $analyticsProduct = $('.analytics-product.' + productId); } var products = utils.productClickHelper($analyticsProduct), analyticsInfo = window.bata_com_ns.analytics; // save GA4 item list id try { var listId = utils.ga4GetProductItemListId(products && products.length && products[0]); window.sessionStorage.setItem("analyticsListId", listId); } catch (error) {} // session storage not supported // Trigger the productClick event - GA3 events.productClick(analyticsInfo.currency, analyticsInfo.pageType, products); // Trigger the selectItem event - GA4 var ga4Products = utils.ga4GetProducts(products); events.ga4SelectItem(window.bata_com_ns.analytics.currency, ga4Products); window.location.href = url; }); /** * @description register the PDP product size click */ $(document).on('click', 'li.js-analytics-selectSizePDP', function () { var $product = $(this); var productId = $product.data('pid'), selectedSize = $product.data('display-value'); if (productId && selectedSize) { events.ga4SelectSize(productId, selectedSize); } }); /** * @description register the PDP product color click */ $(document).on('click', '.js-analytics-selectColorPDPImage', function () { var $product = $(this).closest('button.js-colorAttribute'); var productId = $product.data('pid'), selectedColor = $product.data('value'); if (productId && selectedColor) { events.ga4SelectColor(productId, selectedColor); } }); /** * @description user clicked on a size guide link on a PDP page */ $(document).on('click', '#size-guide-asset', function () { events.ga4SelectSizeGuide(); return true; }); /** * @description user clicked on a wishlist link in the account menu */ $(document).on('click', '.menu-container a[href*="wishlist"]', function () { events.ga4SelectWishlist(); return true; }); /** * @description user clicked on a wishlist link in the header */ $(document).on('click', '.wishlistLink', function () { events.ga4SelectWishlist(); return true; }); /** * @description user clicked on a search bar in the header */ $(document).on('click', '.js-headerSearchButton', function () { events.ga4StartSearch(); }); /** * @description register the click on a suggested product */ $(document).on('click', '.js-analytics-suggestionProduct', function () { events.trackGAEvent('Ecommerce', 'Suggestion Click', $(this).attr('href')); }); /** * @description register the display of the cookiesbar */ $('body').on('analytics:showCookieBar', function () { events.trackGAEvent('cookie bar', 'shown', '-', 0, true); }); /** * @description register the closing of cookiesbar */ $('.js-cookies-bar-close').on('click', function () { events.trackGAEvent('cookie bar', 'accepted', '-', 0, true); }); /** * @description register the click on a promotional banner */ $(document).on('click', 'a.js-analytics-banner, a.js-analytics-banner-button', function (e) { e.preventDefault(); var analyticsPromotionsData = []; var $banner = $(this); var url = $banner.attr('href'); if ($banner.data("analytics-title") && $banner.data("analytics-title") !== "" && $banner.data("analytics-title") !== "No title") { analyticsPromotionsData.push({ 'id': $banner.data("analytics-title"), 'name': $banner.data("analytics-title") }); events.ga4SelectContent({ contentId: $banner.data("analytics-title"), contentType: 'banner', contentName: $banner.data("analytics-title") }); events.ga4SelectPromotion({ promotionId: $banner.data("analytics-title"), promotionName: $banner.data("analytics-title") }); events.PageDesignerPromoClick(analyticsPromotionsData); } window.location.href = url; }); $(document).on('click', '.js-analytics-selectContentBrand .cc-component-textbox-cta', function (e) { var brandElement = $(this).closest('.js-analytics-selectContentBrand'); var heroBannerElement = $(this).closest('.js-analytics-herobanner'); if (!brandElement.length || !heroBannerElement.length) { return; } var contentType = brandElement.attr('data-analytics-select-content-brand'); var contentName = heroBannerElement.attr('data-analytics-select-content-name'); var contentId = heroBannerElement.attr('data-analytics-select-content-id'); if (!contentType || !contentName || !contentId) { return; } var selectContentData = { contentId: contentId, contentType: contentType + ' - banner content', contentName: contentName }; events.ga4BrandSelectContent(selectContentData); }); /** * @description the user select a product sorting rule * @param sorting {Int} the sort id selected */ $('body').on('analytics:updateProductSorting', function (e, data) { events.ga4ClickFilter("Radio", "Sort by", data.sorting); events.trackGAEvent(window.bata_com_ns.analytics.pageType, 'sorting', data.sorting); }); /** * @description register the refinement clicks (not the price one) */ $('.container').on('click', '.js-analytics-refinement', function (e) { e.preventDefault(); var $refinement = $(this); events.ga4ClickFilter("Checkbox", $refinement.data('refinement-id'), $refinement.data('refinement-value')); events.trackGAEvent(window.bata_com_ns.analytics.pageType, 'filter - ' + $refinement.data('refinement-id'), $refinement.data('refinement-value')); }); /** * @description register the category clicks */ $('.container').on('click', '.js-categoryItem', function (e) { e.preventDefault(); var $refinement = $(this); events.ga4ClickFilter("Category selection", $refinement.data('category-id'), $refinement.data('category-title')); events.trackGAEvent(window.bata_com_ns.analytics.pageType, 'filter - ' + $refinement.data('category-id'), $refinement.data('category-title')); }); /** * @description register the "proceed to checkout" button click from cart page */ $('#cart-page-checkout-btn').on('click', function (e) { e.preventDefault(); utils.checkouStepHelper(1, 'cart', true); }); /** * @description register the "proceed to checkout" button click from the minicart */ $('body').on('analytics:cartSubmit', function () { utils.checkouStepHelper(1, 'minicart', true); }); /** * @description register the checkout step * @param step {Int} the step number * @param option {Object} various information, step based */ $('body').on('analytics:checkoutStep', function (e, data) { //step 3 and 4 replace the products's informations displayed, so we need to extract them directly from the order object if (data.order) { var checkbox = $('.adyen-checkout__checkbox__input[name="storeDetails"]'); if (checkbox.length) { data.order.paymentMethodSaved = checkbox.prop('checked'); } else { data.order.paymentMethodSaved = false; } utils.updateCheckoutData(data.step, data.option, data.order); } else { utils.checkouStepHelper(data.step, data.option); } }); /** * @description register the second checkout step */ $('body').on('analytics:loginStep', function (e, data) { var options = $('#checkout-main').attr('data-customer-type') === 'registered' ? 'Logged In' : 'Guest'; utils.checkouStepHelper(data.step, options, false); }); /** * @description a new user has registered from the registration form * @param customerId {String} the ID of the customer registered */ $('body').on('analytics:registration', function (e, data) { events.ga4SignUp({ method: 'email', customerCrmId: data.customerCrmId, signupType: 'standard' }); events.registration(data.customerId, data.email, data.phone); }); /** * @description new registration submit in checkout with lightregistration */ $('body').on('analytics:registrationCheckout', function () { events.ga4SignUpCheckout({ signupType: 'checkout' }); }); /** * @description a user has logged in * @param customerCrmId {String} the CRM ID of the logged in customer */ $('body').on('analytics:login', function (e, data) { events.ga4Login({ method: 'email', customerCrmId: data.customerCrmId, loginType: data.isLoginCheckout ? 'checkout' : 'standard' }); events.login(data.customerCrmId, data.email); }); /** * @description socialShareClick event on PDP */ $('a.js-analytics-socialIcon').on('click', function () { var $social = $(this); var socialName = $social.data('share'), productId = $social.closest('ul.social-icons').data('analytics-pid'), elementId = $social.data('id'), elementText = $social.attr('title'), linkUrl = $social.attr('href'), linkDomain = linkUrl ? new URL(linkUrl).hostname : null, type = $social.data('content-type'); var contentType = 'product detail page'; events.ga4Share({ method: socialName, contentType: contentType, itemId: productId, elementId: elementId, elementText: elementText, linkUrl: linkUrl, linkDomain: linkDomain, content_type: linkDomain, type: type }); events.trackGAEvent(contentType, 'social media sharing - ' + socialName, productId); }); /** * @description storeAvailibility event on PDP */ $('body').on('analytics:storeAvailibility', function () { events.trackGAEvent('storeAvailibility', 'click', $('button#findInStoreButton').data('pid')); }); /** * @description Handles click on the first level category and tracks the event */ $('.cc-menu__level__link.cc-menu__firstLevel__link').on('click', function () { var $category = $(this).closest('.cc-menu__level__link.cc-menu__firstLevel__link'); var categoryName = $category.attr('aria-label') || $category.text().trim(); events.ga4ClickMenuNav(1, categoryName); }); /** * @description Handles click on the second level category of menu */ $('.cc-menu__secondLevel__link-wrapper .cc-menu__level__link.cc-menu__secondLevel__link').on('click', function () { var $category = $(this); var categoryName = $category.attr('aria-label') || $category.text().trim(); var parentCatName = $(this).closest('.cc-menu__level.cc-menu__secondLevel').siblings('.cc-menu__level__link.cc-menu__firstLevel__link').attr('aria-label'); events.ga4ClickMenuNav(2, parentCatName + " - " + categoryName); events.trackGAEvent('dropdown', parentCatName, categoryName); }); /** * @description Handles click on the second level content links of menu */ $('.cc-menu__secondLevel__content-link__item a').on('click', function () { var $link = $(this); var categoryName = $link.text().trim(); events.ga4ClickMenuNav(2, categoryName); }); /** * @description Handles click on the third level category of menu */ $('.cc-menu__level__link.cc-menu__thirdLevel__link').on('click', function () { var $category = $(this); var thirdCatName = $category.attr('aria-label') || $category.text().trim(); var secondCatName = $category.closest('.cc-menu__thirdLevel').prev('.cc-menu__secondLevel__link-wrapper').find('.cc-menu__secondLevel__link').attr('aria-label') || $category.closest('.cc-menu__thirdLevel').prev('.cc-menu__secondLevel__link-wrapper').find('.cc-menu__secondLevel__title').text().trim(); var firstCatName = $category.closest('.cc-menu__secondLevel').siblings('.cc-menu__level__link.cc-menu__firstLevel__link').attr('aria-label') || $category.closest('.cc-menu__secondLevel').siblings('.cc-menu__level__link.cc-menu__firstLevel__link').find('.cc-menu__firstLevel__title').text().trim(); var parentCatName = firstCatName + ' - ' + secondCatName; events.ga4ClickMenuNav(3, parentCatName + " - " + thirdCatName); events.trackGAEvent('dropdown', parentCatName, thirdCatName); }); /** * @description Handles click on the highlights section buttons of third level menu */ $('.cc-menu__HighlightsSection__cta').on('click', function () { var $button = $(this); var buttonText = $button.text().trim(); var secondCatName = $button.closest('.cc-menu__HighlightsSection').prev('.cc-menu__secondLevelColumn').find('.cc-menu__secondLevel__link').attr('aria-label') || $button.closest('.cc-menu__HighlightsSection').prev('.cc-menu__secondLevelColumn').find('.cc-menu__secondLevel__title').text().trim(); var firstCatName = $button.closest('.cc-menu__secondLevel').siblings('.cc-menu__level__link.cc-menu__firstLevel__link').attr('aria-label') || $button.closest('.cc-menu__secondLevel').siblings('.cc-menu__level__link.cc-menu__firstLevel__link').find('.cc-menu__firstLevel__title').text().trim(); var parentCatName = firstCatName + ' - ' + secondCatName; events.ga4ClickMenuNav(3, parentCatName + " - " + buttonText); events.trackGAEvent('highlight section', parentCatName, buttonText); }); /** * @description Handles click on the multiple block section links */ $('.cc-menu__blockForMultipleBlocksSection__link').on('click', function () { var $link = $(this); var blockTitle = $link.find('.cc-menu__blockForMultipleBlocksSection__text').text().trim(); var secondCatName = $link.closest('.cc-menu__multipleBlockSection').prev('.cc-menu__secondLevelColumn').find('.cc-menu__secondLevel__link').attr('aria-label') || $link.closest('.cc-menu__multipleBlockSection').prev('.cc-menu__secondLevelColumn').find('.cc-menu__secondLevel__title').text().trim(); var firstCatName = $link.closest('.cc-menu__secondLevel').siblings('.cc-menu__level__link.cc-menu__firstLevel__link').attr('aria-label') || $link.closest('.cc-menu__secondLevel').siblings('.cc-menu__level__link.cc-menu__firstLevel__link').find('.cc-menu__firstLevel__title').text().trim(); var parentCatName = firstCatName + ' - ' + secondCatName; events.ga4ClickMenuNav(3, "PROMO - " + parentCatName + " - " + blockTitle); events.trackGAEvent('collection block', parentCatName, blockTitle); }); /** * @description Handles click on a category in the mobile menu, fetches parent and current category, and tracks the event */ $(document).on('click', '.js-category-container .cc-menu__secondLevel__link', function () { var $category = $(this); if (!$category.data('subcategories')) { var parent = $category.data('analytics-parent'); var name = $category.data('name') || $category.attr('aria-label') || $category.text().trim(); if (parent) { events.ga4ClickMenuNav(2, parent + " - " + name); events.trackGAEvent('dropdown', parent, name); } else { events.ga4ClickMenuNav(1, name); events.trackGAEvent('main menu', name, '', 0, true); } } }); /** * @description Handles click on a brand category in PDP */ $('body').on('click', '.js-analytics-selectBrandName', function () { var button = $(this); var pageUrl = button.data('page-url'); var buttonPosition = button.data('button-position'); if (!button || !pageUrl || !buttonPosition) { return; } events.ga4SelectBrandName({ pageUrl: pageUrl, buttonPosition: buttonPosition }); }); /** * @description register the quantity variation of product * @param pid {String} the id of the product changed * @param qty {Int} the new quantity selected */ $('body').on('analytics:updateProductQuantity', function (e, data) { utils.updateProductQuantity(data.pid, data.qty); }); /** * @description It is triggered when a user clicks on brand logo */ $(document).on('click', '.js-analytics-brandLogoComponent', function (e) { var menuItem = $(this); if (menuItem && menuItem.attr('data-menu-selection')) { var logoComponentData = menuItem.attr('data-menu-selection'); $('body').trigger('analytics:clickBrandLogoComponent', logoComponentData); } }); /** * @description variationSelectedPLP listener * @param pid {pid} the id of the product added to the cart */ $('body').on('analytics:variantSelectionPLP', function (e, data) { var product = data.productData; var products = [{ 'name': product.name, 'id': product.id, 'dimension1': product.dimension1, 'dimension2': product.dimension2, 'dimension3': product.dimension3, 'price': product.price, 'brand': product.brand, 'category': product.category, 'description': product.description, 'productUrl': product.producturl, 'categoryUrl': product.categoryurl, 'imageUrl': product.imageurl, 'variant': product.color + (product.size ? " | " + product.size : ""), 'discount': product.discount, 'promotionName': product.promotionName, 'position': product.position, 'genderName': product.genderName, 'itemSeason': product.itemSeason, 'stockStatus': product.stockStatus }]; utils.extendProductDataWithGA4Categories(products[0], product); var ga4Products = utils.ga4GetProducts(products); // Launch the event depending on variationType, either color or size selection if uknown then use select_item if (data.variationType === 'color') { events.ga4SelectColor(product.id, product.color); } else if (data.variationType === 'size') { events.ga4SelectSize(product.id, product.size); } else { events.ga4SelectItem(window.bata_com_ns.analytics.currency, ga4Products); } //launch the event variantSelected events.variantSelected(window.bata_com_ns.analytics.currency, products); }); /** * @description Checkout progress event * @param data {String} checkout step name */ //checkout inversion $('body').on('analytics:checkoutProgress', function () { var products = utils.getCheckoutProducts(3, false); var ga4Products = utils.ga4GetProducts(products); var ga4CheckoutData = utils.ga4GetCartData(); var checkoutData = { currencyCode: window.bata_com_ns.analytics.currency, coupon: ga4CheckoutData.couponNames, value: ga4CheckoutData.value, stepLabel: "shipping info", stepNumber: 1 }; events.ga4CheckoutProgress(checkoutData, ga4Products); }); /** * @description collect the cart product views / impressions */ $('body').on('analytics:viewMiniCart', function () { var products = utils.getProductsCartData(window.bata_com_ns.analytics.pageType); var ga4Products = utils.ga4GetProducts(products); events.ga4ViewItemList(window.bata_com_ns.analytics.currency, ga4Products); events.trackProductImpression(window.bata_com_ns.analytics.currency, products); }); /** * @description collect the recommendations products views */ $('body').on('analytics:recommendationsLoaded', function (e, recommendationContainer) { utils.trackRecommendationsLists(recommendationContainer); }); /** * @description GA4 track checkout progress */ $('body').on('analytics:shippingSubmitted', function (e, order) { if (!order) { return; } //checkout inversion var products = utils.getCheckoutProducts(2, false); var ga4Products = utils.ga4GetProducts(products); var checkoutData = { currency: window.bata_com_ns.analytics.currency, shipping: order.totals && order.totals.shippingTotalAfterDiscountValue, shippingTier: order.shipping && order.shipping.length && order.shipping[0].selectedShippingMethod && order.shipping[0].selectedShippingMethod.displayName, coupon: order.couponsName, value: order.totals && order.totals.grandTotalDecimal }; events.ga4AddShippingInfo(checkoutData, ga4Products); }); /** * @description GA4 newsletter form submitted */ $('body').on('analytics:newsletterSubscribe', function () { events.ga4Subscribe("newsletter"); }); /** * @description GA4 Add to cart submitting -> extend the form with analytics list id */ $('body').on('analytics:addToCartSubmitting', function (e, form) { if (window.bata_com_ns.analytics.pageType === "category") { form.analyticsListId = $("div.grid-footer > input.category-id").val() || $('.js-analytics-search-category').data('analytics-category-id') || 'product search'; } else if (window.bata_com_ns.analytics.pageType === "product") { form.analyticsListId = $('.analytics-productPDP.analytics-product').data('listId') || 'detail'; } else { form.analyticsListId = 'detail'; } }); $('body').on('analytics:brandSecondCategoryLevel', function (secondLevelData) { var eventData = { menuLevel: "2 - second level category brand", menuSelection: secondLevelData || "" }; events.ga4CheckoutProgress(eventData); }); $('body').on('analytics:clickBackInStock', function (e, buttonData) { if (!buttonData || !$('#product-id').length) { return; } var productId = $('#product-id').val(); var elementId = buttonData.id || ''; var elementMessage = buttonData.message || ''; var $analyticsProduct = void 0; if (utils.getPageType() === "product") { $analyticsProduct = $('.analytics-productPDP'); } else { $analyticsProduct = $('.analytics-product.' + productId); } var clickBackInStockData = { 'linkUrl': $analyticsProduct.data('producturl') || '', 'elementId': elementId, 'elementText': elementMessage }; events.ga4ClickBackInStock(clickBackInStockData); }); $('body').on('analytics:clickBrandLogoComponent', function (e, brandName) { var eventData = { menuLevel: "3 - brand logo component", menuSelection: brandName || "" }; events.ga4BrandLogoComponent(eventData); }); /** * @description clickDiscoverBrand listener * @param discoverBrand {String} the name of the brand clicked */ $('.js-analytics-clickDiscoverBrand').on('click', function () { var discoverBrand = $(this).data('menu-selection'); if (!discoverBrand) { return; } var discoverBrandData = { menuLevel: "discover - brand", menuSelection: discoverBrand }; events.ga4ClickDiscoverBrand(discoverBrandData); }); /** * @description on editorial product click send select_item GA4 event */ $(document).on('click', '.js-editorial-pdp a.js-analytics-productClick', function () { var currentProductId = utils.getProductDataPDP()[0].id || 'undefined product'; var analyticsProduct = $(this).closest('.product').find('.analytics-product'); var sectionTitle = $('.js-editorial-pdp .cc-recommended-slider__title-link').text().trim() || 'Editorial PDP'; if (analyticsProduct.data('name') && analyticsProduct.data('id')) { var productData = [utils.getProductClickTileData(analyticsProduct)]; productData[0].list_name = 'PDP - ' + currentProductId + ' - ' + sectionTitle; var ga4ProductsList = utils.ga4GetProducts(productData); events.ga4SelectItem(window.bata_com_ns.analytics.currency, ga4ProductsList); } }); /** * @description GA4 scroll position */ $(window).bind('scroll', function () { utils.trackScrollPosition(); }); $('body').on('change', 'input[name="storeDetails"]', function () { events.ga4SaveCreditCard(); }); /** * @description GA4 Click on footer item in column */ $('.cc-footer .cc-footer-main .cc-footer-nav-list a').on('click', function () { var footer_selection = $(this); var level = $(this).closest('.col-12').find('.cc-footer-nav-title'); events.ga4SelectFooterMenu(footer_selection, level); }); /** * @description GA4 Click on Footer CTA button */ $('.cc-footer .cc-footer-custom-section-button > a').on('click', function () { var footer_selection = $(this); var level = $(this).closest('.col-12').find('.cc-footer-custom-section-title'); events.ga4SelectFooterMenu(footer_selection, level); }); /***/ }) /******/ ]); //# sourceMappingURL=analytics-index.min.js.map