1function getGtmGa4ID() { 2 if(typeof gtm_ga4_advanced !== "undefined" && gtm_ga4_advanced) { 3 return gtm_ga4_advanced; 4 } 5 return null; 6} 7 8function isSetSelectedFilter() { 9 if (typeof selectedFilterVar !== 'undefined' && selectedFilterVar) { 10 return selectedFilterVar; 11 } 12 return true; 13} 14 15function googleTagManagerGA4_metricData(metricData){ 16 17 let NB_GTM_ADV = getGtmGa4ID(); 18 19 console.log('GA4 New activated!') 20 21 if(typeof NB_GTM_ADV === 'undefined' || NB_GTM_ADV === null){ 22 console.log('Error: NB_GTM_ADV is not defined'); 23 } 24 25 if(typeof dataLayer === 'undefined' || dataLayer === null){ 26 console.log('Error: dataLayer is not defined'); 27 return 28 } 29 30 initFirebaseCart(); 31 32 function allEventsCall(loadedElement, ajaxCall = false) { 33 ProductEvents(); 34 ViewItemList(loadedElement); 35 HandlePromotions(metricData, loadedElement, false, ajaxCall); 36 SelectEvents(); 37 CartEvents(); 38 SearchEvents(); 39 gtm_errorPage(); 40 customEvents(); 41 popoverEcoEvent(); 42 } 43 44 function popoverEcoEvent() { 45 46 $(document).on('show.bs.popover', function (e) { 47 48 let popoverTargetElement = $(e.target) 49 let elementTitle = $(popoverTargetElement).data('original-title'); 50 let ecoVisionList = typeof $(popoverTargetElement).data() !== "undefined" && $(popoverTargetElement).data().listId !== "undefined" 51 && $(popoverTargetElement).data().listId === 'eco-vision'; 52 53 if(typeof popoverTargetElement !== "undefined" && popoverTargetElement.length > 0 && typeof elementTitle === "string" 54 && ecoVisionList) { 55 dataLayer.push({ 56 event: 'ecovision_popup_impression', 57 element: popoverTargetElement[0], 58 title: elementTitle, 59 list_id: 'eco-vision' 60 }); 61 } 62 63 }) 64 65 } 66 67 if(nb_type_page !== 'cart_confirm') { 68 69 allEventsCall(false); 70 gtm_SelectedFilter(); 71 72 ViewItemList(true); 73 $(window).on("loadproductsevent", function () { 74 ViewItemList($(".product-listing .products-listing")); 75 SelectEvents($(".product-listing .products-listing")); 76 gtm_SelectedFilter(); 77 }) 78 ciRegistrationEvents(); 79 80 //ajax call 81 $(window).on("blockLoaded", function (event) { 82 83 let loadedBlock = event.originalEvent.detail.loadedElement; 84 85 ViewItemList(loadedBlock); 86 HandlePromotions(metricData, loadedBlock, false, true); 87 SelectEvents(loadedBlock); 88 89 }); 90 //ajax call 91 92 $(window).on("lastviewedproducts_load", function () { 93 94 let loadedBlock = $(".last-viewed-slider"); 95 96 ViewItemList(loadedBlock); 97 HandlePromotions(metricData, loadedBlock, false, true); 98 99 }); 100 101 let observer = new IntersectionObserver(function(entries, observer) { 102 entries.forEach(function(entry) { 103 if (entry.isIntersecting) { 104 105 if(nb_type_page !== "product_list") ViewItemList($(entry.target)); 106 HandlePromotions(metricData, $(entry.target), false); 107 observer.unobserve(entry.target); 108 } 109 }); 110 }, { 111 rootMargin: "20px 20px" 112 }); 113 114 let sliders = $(".slider, .slider-static"); 115 116 sliders.each(function() { 117 observer.observe(this); 118 }); 119 120 } 121 122 123 // EVENTS 124 125 function gtm_errorPage(){ 126 if(metricData.uniqueCode === 'error'){ 127 dataLayer.push({ 128 'event': 'GTMError', 129 'eventCategory': '404', 130 }); 131 } 132 } 133 134 function ProductEvents() { 135 136 function productEventHandler(event, eventName) { 137 $(window).on(event, function (e) { 138 139 let productId = parseFloat(e.originalEvent.detail.id); 140 141 if(event === "deleteProductFromCartOnePage") { 142 productId = e.originalEvent.detail.id.split("-")[1] 143 } 144 145 let formattedProduct; 146 147 if(nb_type_page === 'product' && productId == parseFloat(metricData.id)) { 148 149 if(eventName === "add_to_cart_ga4") { 150 let combination = $('.product-attributes li.active').data(); 151 let quantity = $("#product_quantity").val(); 152 153 formattedProduct = formatItem({ 154 productid: metricData.id,
155 productcode: metricData.productCode, 156 productname: metricData.name, 157 productdiscount: collectValue(combination.productsizePricesaved), 158 productbrand: collectValue(metricData.brand), 159 productcatbread: collectValue(metricData.breadCrumbs), 160 productsize: collectValue(combination.productsizeName), 161 productprice: convertValue(collectValue(combination.productsizePrice).toString()), 162 quantity: collectValue(quantity) === '' ? 0 : convertValue(collectValue(quantity)), 163 productprevprice: collectValue(combination.productsizeOldprice), 164 }); 165 166 pushFunction({ 167 items: [formattedProduct], 168 ...(typeof e.originalEvent.detail.event_id !== 'undefined' && { event_id: e.originalEvent.detail.event_id }), 169 }, eventName) 170 171 } else { 172 173 formattedProduct = formatItem({ 174 productid: metricData.id, 175 productcode: metricData.productCode, 176 productname: metricData.name, 177 productdiscount: convertValue(metricData.discount) > 0 ? convertValue(metricData.prevprice) * (convertValue(metricData.discount) / 100) : 0, 178 productbrand: collectValue(metricData.brand), 179 productcatbread: collectValue(metricData.breadCrumbs), 180 productsize: '', 181 productprice: metricData.price, 182 quantity: 1, 183 productprevprice: collectValue(metricData.productsizeOldprice), 184 }); 185 186 pushFunction({ 187 items: [formattedProduct], 188 value: [formattedProduct].reduce((total, product) => { return total + product.price }, 0), 189 ...(typeof e.originalEvent.detail.event_id !== 'undefined' && { event_id: e.originalEvent.detail.event_id }), 190 }, eventName) 191 192 } 193 194 } else { 195 196 let productObj = $('.item[data-productid="'+productId+'"]'); 197 198 let selectedSize = $(productObj).find(".sizes-btn-wrapper .item.active"); 199 200 formattedProduct = formatItem({ 201 ...({ 202 ...productObj.data(), 203 ...(elementExists(selectedSize) && { productsize: collectValue(selectedSize.data("productsize-name")) }) 204 }), 205 quantity: $(productObj).find(".product-list-quantity-wrapper .product-list-quantity input").val() 206 }); 207 208 pushFunction({ 209 items: [formattedProduct], 210 ...(typeof e.originalEvent.detail.event_id !== 'undefined' && { event_id: e.originalEvent.detail.event_id }), 211 }, eventName) 212 213 } 214 215 }) 216 } 217 218 productEventHandler("cartButtonClick", "add_to_cart_ga4") 219 productEventHandler("ViewItemEvent", "view_item_ga4") 220 productEventHandler("addToFavoritesProduct", "add_to_wishlist_ga4") 221 productEventHandler("removeFavoritesProduct", "remove_from_wishlist") 222 productEventHandler("deleteProductFromCartOnePage", "remove_from_cart_ga4") 223 224 if(nb_type_page === "product") { 225 nbshopJS.CustomEventTrigger('ViewItemEvent', { id : metricData.id, event_id: metric_onload_event_id }); 226 } 227 228 } 229 230 function ViewItemList(loadedElement = false, endFunction = false){ 231 232 let productLists = false; 233 234 if(loadedElement) { 235 if(!endFunction) { 236 if(nb_type_page === "product_list") { 237 productLists = $(".product-listing .products-listing"); 238 } else { 239 if($(loadedElement).hasClass('product-slider')) { 240 productLists = $(loadedElement); 241 } else { 242 productLists = $(loadedElement).find('.product-slider:visible'); 243 } 244 } 245 } else { 246 productLists = $(loadedElement); 247 } 248 } else productLists = $('.product-slider:not(.viewed):visible'); 249 250 if(typeof productLists === "undefined" || productLists.length === 0 || !productLists) return; 251 252 for (let list of productLists) { 253 254 if($(list).hasClass("viewed")) continue; 255 256 let counter = 0; 257 let productsInList = $(list).find('.item.product-item:not(.tracked)'); 258 let listArray = []; 259 let listName = $(list).data('list-name') ? $(list).data('list-name') : ''; 260 let tabs = (typeof $(list).closest(".tab-pane") !== "undefined" && $(list).closest(".tab-pane").length > 0); 261 262 if(tabs && !$(list).closest(".tab-pane").hasClass("active") && !endFunction) { 263 continue; 264 } 265 266 if(productsInList.length === 0) break; 267 268 for (let productItem of productsInList) { 269 270 let productObj = {}; 271 272 let productData = $(productItem).data(); 273 274 275 productObj = formatItem({ 276 productid: productData.productid, 277 productcode: productData.productcode, 278 productname: productData.productname, 279 productdiscount: convertValue(productData.productdiscount) > 0 ? convertValue(productData.productprice) * (convertValue(productData.productdiscount) / 100) : 0, 280 productbrand: collectValue(productData.productbrand), 281 productcatbread: collectValue(productData.productcatbread), 282 item_variant: '', 283 productprice: productData.productprice, 284 quantity: 1, 285 }, counter); 286 287 if(nb_type_page === "product_list") { 288 289 $(productItem).addClass("tracked"); 290 291 listArray.push(productObj) 292 } else listArray.push(productObj) 293 294 counter++; 295 296 } 297 298 pushFunction({ 299 items: listArray, 300 item_list_name: listName 301 }, "view_item_list", false); 302 303 $(list).addClass("viewed"); 304 305 } 306 307 if(endFunction) return; 308 309 let tabItem = $('.lists-tabs .nav-tabs .nav-item'); 310 311 if(loadedElement) { 312 tabItem = $(loadedElement).find('.nav-tabs .nav-item'); 313 } 314 315 if(typeof tabItem !== "undefined" && tabItem.length > 0) { 316 tabItem.click(function () { 317 let sliderId = $(this).find('.nav-link').attr('href'); 318 let element = $(this).closest('.lists-tabs').find(sliderId + ' .product-slider') 319 ViewItemList(element, true); 320 }) 321 } 322 323 } 324 325 function HandlePromotions(metricData, loadedElement = false, endFunction = false, ajaxCall = false) { 326 327 if(!NB_GTM_ADV) { 328 return; 329 } 330 331 function getPromotionId(promotion) { 332 333 let promotionClasses = $(promotion).attr("class").replace('appear', '').replace('appeared', '').replace('viewed', '').trim().split(' '); 334 335 if(promotionClasses.length === 0) return ''; 336 337 return promotionClasses[promotionClasses.length - 1].replace('-slider', ''); 338 339 } 340 341 var sliders = $(loadedElement); 342 let promotionArray = []; 343 344 if(ajaxCall && typeof $(sliders).find(".product-slider") !== "undefined" && $(sliders).find(".product-slider").length > 0) { 345 sliders = $(sliders).find(".product-slider"); 346 } 347 348 let tabs = (typeof $(sliders).closest(".tab-pane") !== "undefined" && $(sliders).closest(".tab-pane").length > 0) 349 if (typeof sliders === "undefined" || sliders.length === 0) return; 350 351 for (let promotion of sliders) { 352 353 let eventData = {}; 354 let counter = 0; 355 356 let promotionItem = false;
357 let isProductSlider = false; 358 359 promotionItem = $(promotion); 360 361 if($(promotion).hasClass("product-slider")) { 362 isProductSlider = true; 363 } 364 365 if(typeof $(promotion).find(".product-slider") !== "undefined" && $(promotion).find(".product-slider").length > 0) { 366 promotionItem = $(promotion).find(".product-slider"); 367 isProductSlider = true; 368 } 369 370 if($(promotion).hasClass("slider-tracked")) continue; 371 372 if(tabs && !$(promotion).closest(".tab-pane").hasClass("active") && !endFunction) { 373 continue; 374 } 375 376 if(promotionItem) { 377 378 let promotionName = '', items = ''; 379 let promotionId = getPromotionId(promotionItem); 380 381 if(isProductSlider) { 382 383 items = $(promotionItem).find(".item.product-item:not(.slick-cloned)"); 384 385 if(typeof $(promotionItem).data("list-name") !== "undefined") { 386 promotionName = $(promotionItem).data("list-name"); 387 } 388 389 if(typeof $(promotionItem).data('list-unique-name') !== "undefined" && $(promotionItem).data('list-unique-name') !== "") { 390 promotionId = $(promotionItem).data('list-unique-name'); 391 } 392 393 if(tabs) { 394 promotionId = $(promotion).closest('.tab-pane').data("unique-name"); 395 } 396 397 } 398 399 if(!isProductSlider) { 400 401 let position = false; 402 if(($(promotion).hasClass("slider-static") || $(promotion).hasClass("grid-slider"))) { 403 position = $(promotion).data('gtm-slider-position') 404 } else { 405 position = $(promotion).find('.slider-init').data('gtm-slider-position') 406 } 407 408 let positionName = (typeof position !== "undefined" && position) ? position : ''; 409 410 items = $(promotionItem).find(".item:not(.slick-cloned)"); 411 412 for (let item of items) { 413 414 415 let bannerData = $(item).data(); 416 417 let bannerObj = { 418 ...( collectValue(positionName) !== '' && { creative_slot: collectValue(positionName) } ), 419 ...( collectValue(bannerData.gtmSliderCreative) !== '' && { creative_name: collectValue(bannerData.gtmSliderCreative) } ), 420 ...( collectValue(bannerData.gtmSliderName) !== '' && { promotion_name: collectValue(bannerData.gtmSliderName) } ), 421 ...( collectValue(bannerData.gtmSliderId) !== '' && { promotion_id: collectValue(bannerData.gtmSliderId) } ), 422 } 423 424 if(Object.keys(bannerObj).length < 2) continue; 425 426 eventData.creative_slot = trimText(bannerObj.creative_slot); 427 eventData.creative_name = trimText(bannerObj.creative_name); 428 eventData.promotion_name = trimText(bannerObj.promotion_name); 429 eventData.promotion_id = bannerObj.promotion_id; 430 431 432 if(typeof window.nbMetaConversionsTracking !== "undefined" && typeof disableFBBrowserEvents !== "undefined" && disableFBBrowserEvents) { 433 pushFunction(eventData, "view_promotion", false, true); 434 } else { 435 pushFunction(eventData, "banner_view", false, true); 436 } 437 438 $(item).click(function () { 439 440 let bannerData = $(this).data(); 441 442 let bannerObj = { 443 ...( collectValue(positionName) !== '' && { creative_slot: collectValue(positionName) } ), 444 ...( collectValue(bannerData.gtmSliderCreative) !== '' && { creative_name: collectValue(bannerData.gtmSliderCreative) } ), 445 ...( collectValue(bannerData.gtmSliderName) !== '' && { promotion_name: collectValue(bannerData.gtmSliderName) } ), 446 ...( collectValue(bannerData.gtmSliderId) !== '' && { promotion_id: collectValue(bannerData.gtmSliderId) } ), 447 } 448 449 eventData.creative_slot = bannerObj.creative_slot; 450 eventData.creative_name = bannerObj.creative_name; 451 eventData.promotion_name = bannerObj.promotion_name; 452 eventData.promotion_id = bannerObj.promotion_id; 453 454 if(typeof window.nbMetaConversionsTracking !== "undefined" && typeof disableFBBrowserEvents !== "undefined" && disableFBBrowserEvents) { 455 pushFunction(eventData, "select_promotion", false, true); 456 } else { 457 pushFunction(eventData, "banner_click", false, true); 458 } 459 460 }) 461 462 counter++; 463 464 } 465 } else { 466 for (let item of items) { 467 promotionArray.push(formatItem($(item).data(), counter)); 468 counter++; 469 } 470 471 } 472 473 if(!isProductSlider) return; 474 475 eventData.creative_slot = promotionName; 476 eventData.creative_name = promotionId 477 eventData.promotion_name = promotionId; 478 eventData.items = promotionArray; 479 480 if(typeof eventData.items !== "undefined" && eventData.items.length > 0) { 481 482 pushFunction(eventData, "view_promotion", false); 483 484 } else { 485 continue; 486 } 487 488 $(promotionItem).find(".item").click(function () { 489 490 eventData.creative_slot = promotionName; 491 eventData.creative_name = promotionId 492 eventData.promotion_name = promotionId; 493 494 eventData.items = [ formatItem($(this).data())] ; 495 496 pushFunction(eventData, "select_promotion", false) 497 }) 498 499 } 500 501 $(promotion).addClass("slider-tracked"); 502 503 } 504 505 if(endFunction) return; 506 507 let tabItem = $('.lists-tabs .nav-tabs .nav-item'); 508 509 if(tabs) { 510 tabItem = $(loadedElement).find('.nav-tabs .nav-item'); 511 } 512 513 if(typeof tabItem !== "undefined" && tabItem.length > 0) { 514 tabItem.click(function () { 515 let sliderId = $(this).find('.nav-link').attr('href'); 516 let element = $(this).closest('.lists-tabs').find(sliderId + ' .product-slider') 517 HandlePromotions(metricData, element, true); 518 }) 519 } 520 521 } 522 523 function SelectEvents(loadedEvent = false) { 524 525 let product = $(".item.product-item"); 526 527 if(loadedEvent) { 528 product = $(loadedEvent).find(".item.product-item"); 529 } 530 531 product.click(function () { 532 533 let productData = $(this).data(); 534 535 pushFunction({ 536 items: [formatItem(productData)], 537 }, 'select_item') 538 539 }) 540 541 } 542 543 function triggerCartEvent(event) { 544
545 let productsInCart = $("#order_cart_content .cart-step [data-productid]"); 546 let productArray = []; 547 548 if(!elementExists(productsInCart)) return; 549 550 551 for (let item of productsInCart) { 552 553 productArray.push($(item).data()); 554 555 } 556 557 switch (event) { 558 559 case "ViewCart": { 560 561 nbshopJS.CustomEventTrigger(event, { products : productArray }); 562 563 } break; 564 565 case "BeginCheckout": { 566 567 nbshopJS.CustomEventTrigger(event, { products : productArray, event_id: metric_onload_event_id }); 568 569 } break; 570 571 case "AddShippingInfo": { 572 573 $("#submit_order_one_page").on("click", function () { 574 575 let shippingTier = $(".delivery-options .iradio_flat input[name='carierId']:checked").closest("li[data-carrier-name]").data("carrier-name"); 576 577 nbshopJS.CustomEventTrigger(event, { products : productArray, shippingTier: shippingTier }); 578 }) 579 580 } break; 581 582 case "AddPaymentInfoGA4": { 583 584 $("#submit_order_one_page").on("click", function () { 585 586 let typePayment = $("#cart-payment-content input[name='typepayment']:checked").val(); 587 588 setTimeout(function () { 589 if(typeof $(".cart .validation-error") === "undefined" || $(".cart .validation-error").length === 0) { 590 nbshopJS.CustomEventTrigger(event, { products : productArray, typePayment: typePayment, event_id: metric_onload_event_id }); 591 } 592 }, 500) 593 }) 594 595 } break; 596 597 } 598 599 } 600 601 function CartEvents() { 602 603 604 if(nb_type_page !== "cart") return; 605 606 function cartEventHandler(event, eventName) { 607 608 $(window).on(event, function(e) { 609 610 let products = e.originalEvent.detail.products; 611 612 let formattedProducts = products.map((item, index) => formatItem(item, index)) 613 let paymentType = collectValue(e.originalEvent.detail.typePayment); 614 let shippingTier = collectValue(e.originalEvent.detail.shippingTier); 615 616 pushFunction({ 617 items: formattedProducts, 618 payment_type: trimText(collectValue(paymentType)), 619 shipping_tier: trimText(collectValue(shippingTier)), 620 ...(typeof e.originalEvent.detail.event_id !== 'undefined' && { event_id: e.originalEvent.detail.event_id }), 621 }, eventName) 622 623 }) 624 625 } 626 627 cartEventHandler("ViewCart", "view_cart") 628 cartEventHandler("BeginCheckout", "begin_checkout_ga4") 629 cartEventHandler("AddShippingInfo", "add_shipping_info") 630 cartEventHandler("AddPaymentInfoGA4", "add_payment_info") 631 632 triggerCartEvent("ViewCart") 633 triggerCartEvent("BeginCheckout") 634 triggerCartEvent("AddShippingInfo") 635 triggerCartEvent("AddPaymentInfoGA4") 636 637 } 638 639 // Search 640 641 function SearchEvents() { 642 643 if(!NB_GTM_ADV) { 644 return; 645 } 646 647 $(window).on("searchSuggestAutocomplateNew", function (e) { 648 649 var searchTermVar = $('#search-text').val(); 650 651 var resultsFound = $('.search-sugest, .autocomplete-products-wrapper').data('productsfound'); 652 653 if(typeof resultsFound === "undefined" || !resultsFound ) { 654 resultsFound = 0; 655 } 656 657 if(resultsFound === 0) { 658 clearDataLayer(); 659 dataLayer.push({ 660 'event': 'no_search_results', 661 'search_term' : searchTermVar, 662 }); 663 } 664 665 clearDataLayer(); 666 dataLayer.push({ 667 'event': 'search_ga4', 668 ...( collectValue(e.originalEvent.detail.event_id) !== '' && { event_id: e.originalEvent.detail.event_id }), 669 'search_term' : searchTermVar, 670 }); 671 672 }) 673 674 } 675 676 function gtm_SelectedFilter() { 677 if(!isSetSelectedFilter() || !NB_GTM_ADV || nb_type_page !== "product_list") { 678 return; 679 } 680 681 let checkbox = $("#filter_form input[type=checkbox]"); 682 683 $(checkbox).on("change", function () { 684 var filterObject = {}; 685 var targetCheckbox = $(this); 686 var currentDate = new Date();
687 var formattedDate = currentDate.toLocaleString(); 688 689 if(targetCheckbox.is(":checked")) { 690 filterObject.statusOptIn = true 691 } else filterObject.statusOptIn = false; 692 693 filterObject.attributeValue = (typeof targetCheckbox.attr("value") !== "undefined" || targetCheckbox.attr("value")) ? targetCheckbox.attr("value") : ''; 694 695 filterObject.attributeName = $(targetCheckbox).closest(".filter-group").find('.headline-wrapper .title').text(); 696 697 698 filterObject.paginationPage = $(".pagination > li.active").text(); 699 700 filterObject.pageUrl = window.location.href; 701 702 filterObject.eventDate = formattedDate; 703 704 clearDataLayer(); 705 dataLayer.push({ 706 'event': 'selectedFilter', 707 ...(ecommerceWrap({ 708 'attributeName': trimText(filterObject.attributeName), 709 'attributeValue': filterObject.attributeValue, 710 'eventDate': filterObject.eventDate, 711 'statusOptIn' : filterObject.statusOptIn, 712 'pageUrl' : filterObject.pageUrl, 713 'paginationPage': filterObject.paginationPage === "" ? 1 : parseFloat(filterObject.paginationPage) 714 })) 715 }); 716 717 718 }) 719 720 } 721 722 function ciRegistrationEvents() { 723 724 function newsletterEvent() { 725 726 $(window).on("load", function () { 727 if(typeof window.nbMetricObject.NB_METRIC_DATA.uniqueCode !== "undefined" && window.nbMetricObject.NB_METRIC_DATA.uniqueCode === "ci_newsletter_verification") { 728 nbshopJS.CustomEventTrigger('NewsletterLoginEventGA4', { event_id: metric_onload_event_id }); 729 console.log(window.nbMetricObject.NB_METRIC_DATA.uniqueCode) 730 } 731 }) 732 733 } 734 735 // start_registration 736 $(window).on("openCIRegistrationModal", function () { 737 clearDataLayer(); 738 dataLayer.push({ 739 'event': 'start_registration', 740 }); 741 }) 742 743 //legalRegistration 744 $(window).on("CIRegistrationSuccess", function (event) { 745 var method = "website"; 746 747 if(typeof event.method !== "undefined" && event.method !== "") { 748 method = event.method; 749 } 750 clearDataLayer(); 751 dataLayer.push({ 752 'event': 'legalRegistration', 753 'method': method // ovde treba proslediti odakle se je korisnik ulogovao 754 }); 755 }) 756 757 //start_phone_registration 758 $(window).on("openCILoyaltyModal", function () { 759 clearDataLayer(); 760 dataLayer.push({ 761 'event': 'start_phone_registration', 762 }); 763 }) 764 765 //enter_sms_code 766 $(window).on("openCISmsCodeModal", function () { 767 clearDataLayer(); 768 dataLayer.push({ 769 'event': 'enter_sms_code', 770 }); 771 }) 772 773 //completed_user_registration 774 $(window).on("RegisterEvent", function (e) { 775 clearDataLayer(); 776 dataLayer.push({ 777 event: 'completed_user_registration', 778 ...(typeof e.originalEvent.detail.event_id !== 'undefined' && { event_id: e.originalEvent.detail.event_id }), 779 }); 780 781 if(typeof e.originalEvent.detail.event_id !== 'undefined') { 782 localStorage.setItem('completed_user_registration', e.originalEvent.detail.event_id) 783 } 784 }) 785 786 //end_phone_registration 787 $(window).on("endCIPhoneRegister", function () { 788 dataLayer.push({ 789 'event': 'end_phone_registration', 790 }); 791 localStorage.setItem('end_phone_registration', "true") 792 }) 793 794 //userLogin 795 $(window).on("LoginEvent", function (e) { 796 clearDataLayer(); 797 dataLayer.push({ 798 event: 'userLogin', 799 'eventCategory': 'User Engagement', 800 'eventAction': 'User Login', 801 'loginMethod': 'Standard', 802 ...(typeof e.originalEvent.detail.userInfo !== 'undefined' && { userID: e.originalEvent.detail.userInfo.userID }), 803 ...(typeof e.originalEvent.detail.event_id !== 'undefined' && { event_id: e.originalEvent.detail.event_id }), 804 }); 805 806 if(typeof e.originalEvent.detail.event_id !== 'undefined') { 807 localStorage.setItem('userLogin', e.originalEvent.detail.event_id) 808 } 809 }) 810 811 $(window).on("NewsletterLoginEventGA4", function (e) { 812 clearDataLayer(); 813 dataLayer.push({ 814 event: 'subscribe_ga4', 815 ...(typeof e.originalEvent.detail.event_id !== 'undefined' && { event_id: e.originalEvent.detail.event_id }), 816 }); 817 818 if(typeof e.originalEvent.detail.event_id !== 'undefined') { 819 localStorage.setItem('subscribe_ga4', e.originalEvent.detail.event_id) 820 } 821 }) 822 823 newsletterEvent(); 824 825 } 826 827 828} 829 830// PROPERTY BUILDERS 831 832function elementExists(element) { 833 return typeof element !== "undefined" && element.length > 0; 834} 835 836function convertValue(value) { 837 if(typeof value === 'string') { 838 var convertedValue = value; 839 var convertedValue2, convertedValue3; 840 841 if(convertedValue.includes('.') && convertedValue.includes(',')) { 842 convertedValue2 = convertedValue.replace(/\./g, ''); 843 } else if(convertedValue.includes('.') && !convertedValue.includes(',')){ 844 if(/^\d+\.\d{3}$/.test(convertedValue)) { 845 convertedValue2 = parseInt(convertedValue.replace('.', '')); 846 } else { 847 convertedValue2 = parseFloat(parseFloat(convertedValue).toFixed(2)); 848 } 849 } else convertedValue2 = convertedValue; 850 851 if(typeof convertedValue2 === 'string' && convertedValue2.includes(',')) { 852 convertedValue3 = convertedValue2.replace(/,/g, '.'); 853 } else convertedValue3 = convertedValue2; 854 855 return parseFloat(parseFloat(convertedValue3).toFixed(2)); 856 } else return value; 857} 858 859// DATALAYER PUSH FUNCTION 860 861function ecommerceWrap(obj) { 862 863 if (typeof ecommerceWrapVar !== 'undefined' && ecommerceWrapVar) { 864 return { 865 ecommerce : { 866 ...obj 867 } 868 } 869 } 870 871 return obj; 872 873} 874 875function clearDataLayer() { 876 if (typeof ecommerceWrapVar !== 'undefined' && ecommerceWrapVar) { 877 dataLayer.push({ ecommerce: null }); 878 } 879} 880 881function pushFunction(object, eventName, insertValue = true, banner = false) { 882 883 const _DefaultCurrency = nbMetricObject.NB_METRIC_DATA.currencyISO; 884 885 if(banner) { 886 dataLayer.push({ 887 event: eventName, 888 ...ecommerceWrap({ 889 ...( collectValue(object.creative_slot) !== '' && { creative_slot: collectValue(object.creative_slot) } ), 890 ...( collectValue(object.creative_name) !== '' && { creative_name: collectValue(object.creative_name) } ), 891 ...( collectValue(object.promotion_name) !== '' && { promotion_name: collectValue(object.promotion_name) } ), 892 ...( collectValue(object.promotion_id) !== '' && { promotion_id: collectValue(object.promotion_id) } ), 893 }), 894 ...(typeof object.event_id !== 'undefined' && { event_id: object.event_id }), 895 }); 896 897 return; 898 899 } 900 901 902 let value = object.items.reduce((total, product) => { 903 return total + product.price * product.quantity; 904 }, 0); 905 906 if(typeof object.value !== "undefined" && object.value > 0) { 907 value = object.value 908 } 909 910 if(eventName !== "view_promotion" && eventName !== "select_promotion") { 911 clearDataLayer(); 912 } 913 914 let pushObj = { 915 event: eventName, 916 ...ecommerceWrap({ 917 currency: _DefaultCurrency, 918 items: object.items, 919 ...( insertValue && { value: value ? Math.round(value) : 0 } ), 920 ...( collectValue(object.item_list_name) !== '' && { item_list_name: collectValue(object.item_list_name) } ), 921 ...( collectValue(object.creative_name) !== '' && { creative_name: collectValue(object.creative_name) } ), 922 ...( collectValue(object.promotion_name) !== '' && { promotion_name: collectValue(object.promotion_name) } ), 923 ...( collectValue(object.creative_slot) !== '' && { creative_slot: collectValue(object.creative_slot) } ), 924 ...( collectValue(object.payment_type) !== '' && { payment_type: object.payment_type } ), 925 ...( collectValue(object.shipping_tier) !== '' && { shipping_tier: object.shipping_tier } ), 926 ...( collectValue(object.transaction_id) !== '' && { transaction_id: object.transaction_id } ), 927 ...( collectValue(object.shipping) !== '' && { shipping: object.shipping } ), 928 ...( collectValue(object.tax) !== '' && { tax: object.tax } ), 929 ...( collectValue(object.email_address) !== '' && { email_address: object.email_address } ), 930 ...( collectValue(object.phone_number) !== '' && { phone_number: object.phone_number } ), 931 ...( collectValue(object.sha256_email_address) !== '' && { sha256_email_address: object.sha256_email_address } ), 932 ...( collectValue(object.sha256_phone_number) !== '' && { sha256_phone_number: object.sha256_phone_number } ), 933 ...( collectValue(object.address) !== '' && { address: object.address } ), 934 ...( collectValue(object.event_id) !== '' && { event_id: object.event_id }), 935 ...( collectValue(object.hasPurchases) !== '' && { hasPurchases: object.hasPurchases }), 936 ...( collectValue(object.purchaseSum) !== '' && { purchaseSum: object.purchaseSum }), 937 }) 938 } 939 940 if(!isMobileCart() && !isMobileLanding()) { 941 dataLayer.push({
942 ...pushObj 943 }); 944 } 945 946 firebaseEvents(pushObj, eventName); 947 948} 949 950let analyticsFirebase = false; 951 952function isMobileCart() { 953 return ($(".cart-app") !== "undefined" && $(".cart-app").length > 0) || (typeof $(".cart-confirm-app") !== "undefined" && $(".cart-confirm-app").length > 0); 954} 955 956 957function isMobileLanding() { 958 return $(".landing-app") !== "undefined" && $(".landing-app").length > 0; 959} 960 961function initFirebaseCart() { 962 963 if(typeof firebase !== "undefined" && typeof firebaseConfig !== "undefined" && (isMobileCart() || isMobileLanding())) { 964 965 function gtag(){ dataLayer.push(arguments); } 966 967 gtag('consent', 'update', { 968 'ad_storage': 'granted', 969 'ad_user_data': 'granted', 970 'ad_personalization': 'granted', 971 'analytics_storage': 'granted' 972 }); 973 974 firebase.initializeApp(firebaseConfig); 975 analyticsFirebase = firebase.analytics(); 976 977 } 978} 979 980 981 982function firebaseEvents(pushObj, eventName) { 983 984 if(typeof firebase !== "undefined" && analyticsFirebase) { 985 986 function exclude(obj, key) { 987 const { [key]: _, ...rest } = obj; 988 return rest; 989 } 990 991 console.log(eventName.replace('_ga4', ''), { 992 ...exclude(pushObj, "event") 993 }) 994 995 996 analyticsFirebase.logEvent(eventName.replace('_ga4', ''), { 997 ...exclude(pushObj, "event") 998 }); 999 1000 } 1001} 1002 1003function collectValue(value) { 1004 1005 return typeof value !== "undefined" ? value : ''; 1006 1007} 1008 1009function trimText(string) { 1010 1011 return typeof string === "string" ? string.trim() : ''; 1012 1013} 1014 1015function formatItem(product, counter = 0) { 1016 1017 let productData = product; 1018 1019 let productCategoryArray = collectValue(productData.productcatbread).split(">") 1020 1021 let discount = convertValue(productData.productdiscount) < 100 && convertValue(productData.productdiscount) > 0 ? convertValue(product.productprice.toString()) * (convertValue(productData.productdiscount) / 100) : convertValue(productData.productdiscount); 1022 1023 if(collectValue(productData.productprevprice) !== '' && convertValue(productData.productprevprice) > convertValue(productData.productprice.toString())) { 1024 discount = parseFloat((convertValue(productData.productprevprice) - convertValue(productData.productprice.toString())).toFixed(2)); 1025 } 1026 1027 return { 1028 item_id: collectValue(window.purchaseProductCodeInsteadOfId) !== '' ? collectValue(productData.productcode) : parseFloat(productData.productid), 1029 item_name: trimText(productData.productname), 1030 discount: discount, 1031 index: counter, 1032 item_brand: collectValue(productData.productbrand), 1033 item_category: trimText(collectValue(productCategoryArray[0])), 1034 item_category2: trimText(collectValue(productCategoryArray[1])), 1035 item_category3: trimText(collectValue(productCategoryArray[2])), 1036 item_category4: trimText(collectValue(productCategoryArray[3])), 1037 item_category5: trimText(collectValue(productCategoryArray[4])), 1038 item_list_id: collectValue(productData.item_list_id), 1039 item_variant: collectValue(productData.productsize) !== '' ? collectValue(productData.productsize) : collectValue(productData.productsizename), 1040 price: collectValue(productData.productprice) === '' ? 0 : convertValue(collectValue(productData.productprice.toString())), 1041 quantity: collectValue(product.quantity) === '' ? 1 : convertValue(collectValue(product.quantity)), 1042 sku: collectValue(productData.productcode) 1043 } 1044 1045} 1046 1047function customEvents() { 1048 1049 if(typeof customEventsVar === "undefined" || !customEventsVar) { 1050 console.log("GTM-GA4: Custom eventovi nisu aktivni!") 1051 return; 1052 } 1053 1054 function eventCall() { 1055 menuOpen(); 1056 loginModalOpen(); 1057 registerModalOpen(); 1058 filtersOpen(); 1059 quickViewItem(); 1060 viewItemLanding(); 1061 ticketApplied(); 1062 } 1063 1064 function menuOpen() { 1065 1066 if($(window).width() > 576) return; 1067 1068 let menuNav = $('.nav-mobile-icon'); 1069 1070 if(!elementExists(menuNav)) return; 1071 1072 menuNav.click(function () { 1073 clearDataLayer(); 1074 setTimeout(function () { 1075 if($(".nav-main-wrapper").hasClass("loaded")) { 1076 dataLayer.push({ 1077 'event': 'menu_open', 1078 }); 1079 } 1080 }, 200) 1081 }) 1082 1083 } 1084 1085 function loginModalOpen() { 1086 1087 if($(window).width() > 576) return; 1088 1089 $( "#login_modal").on('shown.bs.modal', function (e) { 1090 clearDataLayer(); 1091 dataLayer.push({ 1092 'event': 'login_modal_open', 1093 }); 1094 }); 1095 } 1096 1097 1098 function registerModalOpen() { 1099 1100 if($(window).width() > 576) return; 1101 1102 $( "#register_modal").on('shown.bs.modal', function (e) { 1103 clearDataLayer(); 1104 dataLayer.push({ 1105 'event': 'register_modal_open', 1106 }); 1107 }); 1108 } 1109 1110 function filtersOpen() { 1111 1112 if($(window).width() > 576 || nb_type_page !== "product_list") return; 1113 1114 let filtersButton = $('.action-filters'); 1115 1116 if(!elementExists(filtersButton)) return; 1117 1118 filtersButton.click(function () { 1119 1120 setTimeout(function () { 1121 if($('.product-listing-filters').hasClass("loaded")) { 1122 dataLayer.push({ 1123 'event': 'filters_open', 1124 }); 1125 } 1126 }, 200) 1127 }) 1128 1129 } 1130 1131 function quickViewItem() { 1132 1133 $(window).on("productQuickViewOnModal", function (e) { 1134 let productData = $(".products-detail-wrapper").data(); 1135 pushFunction({ items: [formatItem(productData)]},"quick_view_item"); 1136 }) 1137 1138 } 1139 1140 function viewItemLanding() { 1141 1142 let productPin = $('.image-with-pins-item-wrapper .image-with-pins-wrapper .pin-marker'); 1143 1144 if (!elementExists(productPin)) return; 1145 1146 productPin.click(function () { 1147 let selectedPin = $(this); 1148 setTimeout(function () { 1149 let content = $(selectedPin).find(".click-content"); 1150 if (!content.hasClass("hidden")) { 1151 let productData = $(selectedPin).find(".product-item").data(); 1152 if(!isMobileLanding()) { 1153 pushFunction({items: [formatItem(productData)]}, "view_item_landing"); 1154 } else { 1155 let fbObject = {items: [formatItem(productData)]}; 1156 let value = fbObject.items.reduce((total, product) => { 1157 return total + product.price * product.quantity; 1158 }, 0); 1159 firebaseEvents({items: [formatItem(productData)], value: value, currency: nbMetricObject.NB_METRIC_DATA.currencyISO}, 'view_item_landing'); 1160 } 1161 } 1162 1163 }, 200) 1164 1165 }) 1166 } 1167 1168 1169 function ticketApplied() { 1170 1171 if(nb_type_page !== "cart") return; 1172 1173 let ticketId = $("#ticket_id"); 1174 1175 if(typeof ticketId !== "undefined" && ticketId.length > 0 && ticketId.val() !== '' && ticketId.val() !== ' ') { 1176 if(!isMobileCart()) { 1177 dataLayer.push({ 1178 event: 'ticket_applied', 1179 ticket_name: ticketId.val() 1180 }); 1181 } 1182 firebaseEvents({ ticket_name: ticketId.val() }, 'ticket_applied'); 1183 } 1184 1185 } 1186 1187 eventCall(); 1188 1189} 1190 1191function isPaymentPage() { 1192 if(typeof $(".confirm-payment-wrapper") !== "undefined" && $(".confirm-payment-wrapper").length > 0) { 1193 return true; 1194 } 1195 return false;
1196} 1197 1198function transactionGtm_ga4(order,oItems,storeName,orderAdress, orderBillingAdress,metricData){ 1199 1200 if(isPaymentPage()) { 1201 return; 1202 } 1203 1204 let total = order.total; 1205 1206 let products = oItems.map((item, index) => formatItem({ 1207 productid: item.id, 1208 productcode: item.code ? item.code : item.productCode, 1209 productname: item.name, 1210 productdiscount: 0, 1211 productbrand: collectValue(item.brand), 1212 productcatbread: collectValue(item.groupName), 1213 item_variant: collectValue(item.size), 1214 productprice: collectValue(item.price) === '' ? 0 : convertValue(collectValue(item.price)), 1215 quantity: collectValue(item.quantity) === '' ? 0 : convertValue(collectValue(item.quantity)), 1216 }, index)) 1217 1218 initFirebaseCart(); 1219 1220 pushFunction({ 1221 transaction_id : order.id, 1222 value: convertValue(total), 1223 shipping : convertValue(order.totalCarrier), 1224 tax : convertValue(order.tax), 1225 voucher: order.voucher, 1226 items: products, 1227 sha256_email_address: orderAdress.emailHashed, 1228 sha256_phone_number: orderAdress.phoneHashed, 1229 email_address: orderAdress.email, 1230 phone_number: orderAdress.phone, 1231 ...( typeof order.hasPurchases !== "undefined" && { hasPurchases: order.hasPurchases } ), 1232 ...( typeof order.purchaseSum !== "undefined" && { purchaseSum : order.purchaseSum } ), 1233 address: { 1234 sha256_first_name: orderAdress.firstnameHashed, 1235 sha256_last_name: orderAdress.lastnameHashed, 1236 first_name: orderAdress.firstname, 1237 last_name: orderAdress.lastname, 1238 street: collectValue(orderAdress.street), 1239 city: collectValue(orderAdress.city), 1240 country: collectValue(orderAdress.countryGeo), 1241 postal_code: collectValue(orderAdress.postcode), 1242 region: collectValue(orderAdress.region) 1243 }, 1244 event_id: metric_onload_event_id 1245 }, "purchase_ga4", true) 1246 1247}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.