1let shippingInfoTracked = false, paymentInfoTracked = false; 2let analytics = { 3 arrival: false, 4 departure: false, 5 range: false, 6 nights: false, 7 value: false, 8 units: [] 9}; 10(function($, global, undefined) { 11 $(function () { 12 // Get details about their search/selection 13 var arrival = $('#arrival').val(); 14 var departure = $('#depart').val(); 15 if (typeof arrival == 'string' && arrival.length) { 16 analytics.arrival = arrival; 17 if (departure.length) { 18 analytics.departure = departure; 19 var arrivalDate = new Date(arrival); 20 var departureDate = new Date(departure); 21 var range = arrivalDate.toISOString().split('T')[0] + ':' + departureDate.toISOString().split('T')[0]; 22 analytics.range = range; 23 var oneDay = 1000 * 60 * 60 * 24; 24 var nights = Math.abs(Math.ceil((arrivalDate.getTime() - departureDate.getTime()) / oneDay)); 25 analytics.nights = nights; 26 } 27 } else { 28 // unit scope 29 var arrival = $('#check-availability-arrival-date').val(); 30 var departure = $('#check-availability-departure-date').val(); 31 if (typeof arrival == 'string' && arrival.length) { 32 analytics.arrival = arrival; 33 if (departure.length) { 34 analytics.departure = departure; 35 var arrivalDate = new Date(arrival); 36 var departureDate = new Date(departure); 37 var range = arrivalDate.toISOString().split('T')[0] + ':' + departureDate.toISOString().split('T')[0]; 38 analytics.range = range; 39 var oneDay = 1000 * 60 * 60 * 24; 40 var nights = Math.abs(Math.ceil((arrivalDate.getTime() - departureDate.getTime()) / oneDay)); 41 analytics.nights = nights; 42 } 43 } else { 44 // booking scope 45 var arrival = $('input[name="booking[arrival]"]').val(); 46 var departure = $('input[name="booking[depart]"]').val(); 47 if (typeof arrival == 'string' && arrival.length) { 48 analytics.arrival = arrival; 49 if (departure.length) { 50 analytics.departure = departure; 51 var arrivalDate = new Date(arrival); 52 var departureDate = new Date(departure); 53 var range = arrivalDate.toISOString().split('T')[0] + ':' + departureDate.toISOString().split('T')[0]; 54 analytics.range = range; 55 var oneDay = 1000 * 60 * 60 * 24; 56 var nights = Math.abs(Math.ceil((arrivalDate.getTime() - departureDate.getTime()) / oneDay)); 57 analytics.nights = nights; 58 } 59 } 60 } 61 } 62 63 if ($('.abe-results .abe-item').length > 0) { 64 // view_item_list 65 analytics.units = []; 66 $('.abe-results .abe-item').each(function (i, item) { 67 var unit = $(item); 68 analytics.units.push({ 69 item_id: unit.data('vrp-property-code'), 70 item_name: unit.data('vrp-name'), 71 affiliation: 'Reservations', 72 index: unit.data('vrp-index'), 73 item_brand: unit.data('vrp-type'), 74 item_category: unit.data('vrp-beds') + ' Bedrooms', 75 item_category2: unit.data('vrp-baths') + ' Bathrooms', 76 item_category3: 'Sleeps ' + unit.data('vrp-sleeps'), 77 item_category4: analytics.range, 78 item_category5: analytics.nights ? (analytics.nights + ' Nights') : false 79 }); 80 }); 81 updateDataLayer('view_item_list'); 82 83 $('.abe-results .abe-item a').click(function (e) { 84 //select_item 85 var unit = $(this).closest('.abe-item'); 86 analytics.units = []; 87 analytics.units.push({ 88 item_id: unit.data('vrp-property-code'), 89 item_name: unit.data('vrp-name'), 90 affiliation: 'Reservations', 91 index: unit.data('vrp-index'), 92 item_brand: unit.data('vrp-type'), 93 item_category: unit.data('vrp-beds') + ' Bedrooms', 94 item_category2: unit.data('vrp-baths') + ' Bathrooms', 95 item_category3: 'Sleeps ' + unit.data('vrp-sleeps'), 96 item_category4: analytics.range, 97 item_category5: analytics.nights ? (analytics.nights + ' Nights') : false 98 }); 99 updateDataLayer('select_item'); 100 }); 101 } 102 103 if ($('.abe.abe-unit').length > 0) { 104 var unit = $('.abe.abe-unit .abe-unit-info'); 105 analytics.units = []; 106 analytics.units.push({ 107 item_id: unit.data('unit-property-code'), 108 item_name: unit.data('unit-name'), 109 affiliation: 'Reservations', 110 index: unit.data('unit-index'),
111 item_brand: unit.data('unit-type'), 112 item_category: unit.data('unit-beds') + ' Bedrooms', 113 item_category2: unit.data('unit-baths') + ' Bathrooms', 114 item_category3: 'Sleeps ' + unit.data('unit-sleeps'), 115 item_category4: analytics.range, 116 item_category5: analytics.nights ? (analytics.nights + ' Nights') : false 117 }); 118 updateDataLayer('view_item'); 119 120 $('*#booklink').click(function (e) { 121 var price = parseFloat($('#ratebreakdown .double .rate-breakdown-value').html().replace(new RegExp(/[^0-9.]/g), '')) / analytics.nights; 122 analytics.units[0].currency = 'USD'; 123 analytics.units[0].price = Math.round((price + Number.EPSILON) * 100) / 100; 124 analytics.units[0].quantity = analytics.nights; 125 updateDataLayer('add_to_cart'); 126 }); 127 } 128 129 $('.abe-favorite:not(.active').click(function () { 130 // double check .active 131 if (!$(this).hasClass('active')) { 132 // todo 133 } 134 }); 135 136 if ($('#vrpbookform').length > 0) { 137 analytics.units = []; 138 var unit = $('#vrpbookform'); 139 var price = parseFloat($('input[name="booking[TotalCost]"]').val()) / analytics.nights; 140 analytics.units.push({ 141 item_id: unit.data('unit-property-code'), 142 item_name: unit.data('unit-name'), 143 affiliation: 'Reservations', 144 item_brand: unit.data('unit-type'), 145 item_category: unit.data('unit-beds') + ' Bedrooms', 146 item_category2: unit.data('unit-baths') + ' Bathrooms', 147 item_category3: 'Sleeps ' + unit.data('unit-sleeps'), 148 item_category4: analytics.range, 149 item_category5: analytics.nights ? (analytics.nights + ' Nights') : false, 150 currency: 'USD', 151 price: Math.round((price + Number.EPSILON) * 100) / 100, 152 quantity: analytics.nights 153 }); 154 updateDataLayer('begin_checkout'); 155 156 // shipping info (personal information) 157 $('#vrpbookform input, #vrpbookform select').change(function () { 158 var requiredFields = { 159 'fname': 'input', 160 'lname': 'input', 161 'address': 'input', 162 'city': 'input', 163 'state': 'select', 164 'zip': 'input', 165 'country': 'select', 166 'phone': 'input', 167 'email': 'input' 168 }; 169 var valid = 0; 170 for (name in requiredFields) { 171 var field = $(requiredFields[name] + '[name="booking[' + name + ']"]'); 172 if (field.val().replace(new RegExp(/[\s\r\t\n]+/g)).length > 0) valid++; 173 } 174 if (Object.keys(requiredFields).length == valid && !shippingInfoTracked) { 175 shippingInfoTracked = true; 176 analytics.value = parseFloat($('input[name="booking[TotalCost]"]').val()); 177 updateDataLayer('add_shipping_info'); 178 } 179 180 if (shippingInfoTracked) { 181 var requiredFields = { 182 'ccNumber': 'input', 183 'cvv': 'input', 184 'expMonth': 'select', 185 'expYear': 'select' 186 }; 187 var valid = 0; 188 for (name in requiredFields) { 189 var field = $(requiredFields[name] + '[name="booking[' + name + ']"]'); 190 if (field.val().replace(new RegExp(/[\s\r\t\n]+/g)).length > 0) valid++; 191 } 192 if (Object.keys(requiredFields).length == valid && !paymentInfoTracked) { 193 paymentInfoTracked = true; 194 updateDataLayer('add_payment_info'); 195 } 196 } 197 }); 198 199 // promo code 200 $('.abe-apply-promo').click(function () { 201 updateDataLayer('enter_promo_code'); 202 console.log('apply promo'); 203 }); 204 } 205 206 function updateDataLayer(event) 207 { 208 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 209 switch (event) { 210 case 'view_item_list': 211 dataLayer.push({ 212 event: event, 213 ecommerce: { 214 items: analytics.units 215 } 216 }); 217 break; 218 219 case 'select_item': 220 dataLayer.push({ 221 event: event, 222 ecommerce: { 223 items: analytics.units 224 } 225 }); 226 break; 227 228 case 'view_item': 229 delete analytics.units[0].index; 230 dataLayer.push({ 231 event: event, 232 ecommerce: { 233 items: analytics.units 234 } 235 }); 236 break; 237 238 case 'add_to_cart': 239 delete analytics.units[0].index; 240 if(analytics.units[0].item_name != ""){ 241 dataLayer.push({ 242 event: event, 243 ecommerce: { 244 items: analytics.units 245 } 246 }); 247 } 248 break; 249
250 case 'begin_checkout': 251 delete analytics.units[0].index; 252 if(analytics.units[0].item_name != ""){ 253 dataLayer.push({ 254 event: event, 255 ecommerce: { 256 items: analytics.units 257 } 258 }); 259 } 260 break; 261 262 case 'add_shipping_info': 263 delete analytics.units[0].index; 264 if(analytics.units[0].item_name != ""){ 265 dataLayer.push({ 266 event: event, 267 ecommerce: { 268 // currency: 'USD', 269 // value: analytics.value, 270 items: analytics.units 271 } 272 }); 273 } 274 break; 275 276 case 'add_payment_info': 277 delete analytics.units[0].index; 278 if(analytics.units[0].item_name != ""){ 279 dataLayer.push({ 280 event: event, 281 ecommerce: { 282 // currency: 'USD', 283 // value: analytics.value, 284 items: analytics.units 285 } 286 }); 287 } 288 break; 289 290 case 'enter_promo_code': 291 if(analytics.units[0].item_name != ""){ 292 dataLayer.push({ 293 event: event, 294 promo_code: $('input[name="booking[PromoCode]"]').val() 295 }); 296 } 297 break; 298 } 299 300 } 301 }); 302}(jQuery, window));
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.