1/* for handling all datalayer related events compatible with GA4 requirements */ 2 3/************* 4************** 5configs et misc 6*************** 7**************/ 8 9//event names, noms par défaut donnés dans la doc de tunn3l 10var eventNames = { 11 'productImpressions' : 'view_item_list', 12 'productClick' : 'select_item', 13 'productDetails' : 'view_item', 14 'addToCart' : 'add_to_cart', 15 'removeFromCart' : 'remove_from_cart', 16 'checkout_step_1' : 'begin_checkout', 17 'checkout_step_2' : 'add_payment_info', 18 'purchase' : 'purchase', 19 'sign_up' : 'sign_up', 20 'login' : 'login', 21}; 22 23//productFormating, basique par choix. surcharger si le client veut ses infos différemment 24function dataLayer_format_genericProductList(products){ 25 return products; 26} 27 28function dataLayer_format_checkoutProductList(products, bookingDate, bookingHour){ 29 var productsFormated = []; 30 products.forEach(element => { 31 32 element.date = bookingDate; 33 element.timeSlot = bookingHour; 34 35 productsFormated.push(element); 36 }); 37 return productsFormated; 38} 39 40/************* 41************** 42push functions 43*************** 44**************/ 45 46//productImpressions 47function dataLayer_push_productImpressions(products, infos){ 48 49 if(products.length == 0){ 50 return false; 51 } 52 53 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 54 dataLayer.push({ 55 'event': eventNames.productImpressions, 56 'ecommerce': { 57 'items': dataLayer_format_genericProductList(products) 58 } 59 }); 60} 61//productClick 62function dataLayer_push_productClick(products, infos){ 63 64 if(products.length == 0){ 65 return false; 66 } 67 68 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 69 dataLayer.push({ 70 'event': eventNames.productClick, 71 'ecommerce': { 72 'items': dataLayer_format_genericProductList(products) 73 } 74 }); 75} 76//productDetails 77function dataLayer_push_productDetails(products, infos){ 78 79 if(products.length == 0){ 80 return false; 81 } 82 83 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 84 dataLayer.push({ 85 'event': eventNames.productDetails, 86 'ecommerce': { 87 'items': dataLayer_format_genericProductList(products) 88 } 89 }); 90} 91//addToCart 92function dataLayer_push_addToCart(products, infos){ 93 94 if(products.length == 0){ 95 return false; 96 } 97 98 products.forEach(product => { 99 let gtm_obj = { 100 event : "addToCart", 101 source : "shop", 102 is_ga4 : 1, 103 item_id : product.item_id, 104 price : product.price, 105 qty : product.quantity, 106 currency : product.currency, 107 }; 108 109 addGTMlog(gtm_obj); 110 }); 111 112 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 113 dataLayer.push({ 114 'event': eventNames.addToCart, 115 'ecommerce': { 116 'items': dataLayer_format_genericProductList(products) 117 } 118 }); 119} 120//removeFromCart 121function dataLayer_push_removeFromCart(products, infos){ 122 123 if(products.length == 0){ 124 return false; 125 } 126 127 products.forEach(product => { 128 let gtm_obj = { 129 event : "removeFromCart", 130 source : "shop", 131 is_ga4 : 1, 132 item_id : product.item_id, 133 price : product.price, 134 qty : product.quantity, 135 currency : product.currency, 136 }; 137 138 addGTMlog(gtm_obj); 139 }); 140 141 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 142 dataLayer.push({ 143 'event': eventNames.removeFromCart, 144 'ecommerce': { 145 'items': dataLayer_format_genericProductList(products) 146 } 147 }); 148} 149//begin_checkout 150function dataLayer_push_begin_checkout(products, infos){ 151 152 if(products.length == 0){ 153 return false; 154 } 155 156 products.forEach(product => { 157 let gtm_obj = { 158 event : "begin_checkout", 159 source : "shop", 160 is_ga4 : 1, 161 item_id : product.item_id, 162 price : product.price, 163 qty : product.quantity, 164 currency : product.currency, 165 }; 166 167 addGTMlog(gtm_obj); 168 }); 169 170 var productsFormated = products; 171 if(typeof infos.bookingdate !== 'undefined' && infos.bookingdate != '' && typeof infos.bookinghour && infos.bookinghour != ''){ 172 productsFormated = dataLayer_format_checkoutProductList(products, infos.bookingdate, infos.bookinghour); 173 } 174 else{ 175 productsFormated = dataLayer_format_genericProductList(products); 176 } 177 178 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 179 dataLayer.push({ 180 'event': eventNames.checkout_step_1, 181 'ecommerce': { 182 'items': productsFormated 183 }, 184 'eventCallback' : function() { 185 if(typeof infos.callBackUrl != 'undefined' && infos.callBackUrl != ''){ 186 console.log('redirect to '+infos.callBackUrl+' by gtm callback'); 187 window.location.href = infos.callBackUrl; 188 clearTimeout(timeoutTimer); 189 } 190 } 191 }); 192} 193//add_payment_info 194function dataLayer_push_add_payment_info(products, infos){ 195 196 if(products.length == 0){ 197 return false;
198 } 199 200 products.forEach(product => { 201 let gtm_obj = { 202 event : "add_payment_info", 203 source : "shop", 204 is_ga4 : 1, 205 item_id : product.item_id, 206 price : product.price, 207 qty : product.quantity, 208 currency : product.currency, 209 payment_type : infos.payment_type, 210 transaction_id : infos.order_id, 211 }; 212 213 addGTMlog(gtm_obj); 214 }); 215 216 var productsFormated = products; 217 if(typeof infos.bookingdate !== 'undefined' && infos.bookingdate != '' && typeof infos.bookinghour && infos.bookinghour != ''){ 218 productsFormated = dataLayer_format_checkoutProductList(products, infos.bookingdate, infos.bookinghour); 219 } 220 else{ 221 productsFormated = dataLayer_format_genericProductList(products); 222 } 223 224 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 225 dataLayer.push({ 226 'event': eventNames.checkout_step_2, 227 'ecommerce': { 228 'currency': DatalayerBasicInfos.currencyCode, 229 'value': infos.total, 230 'payment_type' : infos.payment_type, 231 'items': productsFormated 232 }, 233 'eventCallback' : function() { 234 if(typeof infos.callBackUrl != 'undefined' && infos.callBackUrl != ''){ 235 console.log('redirect to '+infos.callBackUrl+' by gtm callback'); 236 window.location.href = infos.callBackUrl; 237 clearTimeout(timeoutTimer); 238 } 239 } 240 }); 241} 242//purchase 243function dataLayer_push_purchase(products, infos){ 244 245 if(products.length == 0){ 246 return false; 247 } 248 249 products.forEach(product => { 250 let gtm_obj = { 251 event : "purchase", 252 source : "shop", 253 is_ga4 : 1, 254 item_id : product.item_id, 255 price : infos.revenue, 256 qty : product.quantity, 257 currency : product.currency, 258 payment_type : infos.payment_type, 259 transaction_id : infos.order_id, 260 }; 261 262 addGTMlog(gtm_obj); 263 }); 264 265 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 266 dataLayer.push({ 267 'event': eventNames.purchase, 268 'ecommerce': { 269 'transaction_id': infos.order_id, 270 'currency': DatalayerBasicInfos.currencyCode, 271 'value': infos.revenue, 272 'tax': infos.tax, 273 'payment_type' : infos.payment_type, 274 'shipping': infos.shipping, 275 'coupon': infos.coupon, 276 'items': dataLayer_format_genericProductList(products) 277 278 } 279 }); 280} 281//login 282function dataLayer_push_login(infos){ 283 284 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 285 dataLayer.push({ 286 'event': eventNames.login, 287 'user_id' : infos.user_id, 288 'eventCallback' : function() { 289 if(typeof infos.callBackUrl != 'undefined' && infos.callBackUrl != ''){ 290 console.log('redirect to '+infos.callBackUrl+' by gtm callback'); 291 window.location.href = infos.callBackUrl; 292 clearTimeout(timeoutTimer); 293 } 294 } 295 }); 296 297} 298//sign_up 299function dataLayer_push_sign_up(infos){ 300 301 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 302 dataLayer.push({ 303 'event': eventNames.sign_up, 304 'user_id' : infos.user_id, 305 'eventCallback' : function() { 306 if(typeof infos.callBackUrl != 'undefined' && infos.callBackUrl != ''){ 307 console.log('redirect to '+infos.callBackUrl+' by gtm callback'); 308 window.location.href = infos.callBackUrl; 309 clearTimeout(timeoutTimer); 310 } 311 } 312 }); 313 314} 315 316 317/*************** 318**************** 319javascript custom events handlers 320*************** 321**************/ 322$(function() { 323 324 $( document ).on( 'productImpressions', '', function(event, products, infos){ 325 dataLayer_push_productImpressions(products, infos); 326 }); 327 $( document ).on( 'productClick', '', function(event, products, infos){ 328 dataLayer_push_productClick(products, infos); 329 }); 330 $( document ).on( 'productDetails', '', function(event, products, infos){ 331 dataLayer_push_productDetails(products, infos); 332 }); 333 $( document ).on( 'addToCart', '', function(event, products, infos){ 334 dataLayer_push_addToCart(products, infos); 335 }); 336 $( document ).on( 'removeFromCart', '', function(event, products, infos){ 337 dataLayer_push_removeFromCart(products, infos); 338 }); 339 $( document ).on( 'checkout', '', function(event, products, infos){ 340 if(infos.step == 1){ 341 dataLayer_push_begin_checkout(products, infos); 342 } 343 else if(infos.step == 2){ 344 dataLayer_push_add_payment_info(products, infos); 345 } 346 else{ 347 dataLayer_push_begin_checkout(products, infos); 348 } 349 }); 350 $( document ).on( 'purchase', '', function(event, products, infos){ 351 dataLayer_push_purchase(products, infos); 352 }); 353 $( document ).on( 'login', '', function(event, infos){ 354 dataLayer_push_login(infos); 355 }); 356 $( document ).on( 'sign_up', '', function(event, infos){ 357 dataLayer_push_sign_up(infos); 358 }); 359 360}); 361
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.