1 2/* Product Page Gallery scroll stickyness for desktop */ 3document.addEventListener('DOMContentLoaded', function() { 4 const gallery = document.querySelector('.woocommerce-product-gallery'); 5 const product = document.querySelector('.product'); 6 7 if (!gallery || !product) return; 8 9 let lastScrollTop = 0; 10 let ticking = false; 11 12 function updateGalleryPosition() { 13 const scrollTop = window.pageYOffset || document.documentElement.scrollTop; 14 const productRect = product.getBoundingClientRect(); 15 const galleryRect = gallery.getBoundingClientRect(); 16 17 const productTop = productRect.top + scrollTop; 18 const productBottom = productTop + productRect.height; 19 const galleryHeight = galleryRect.height; 20 21 let newTop; 22 const menuOffset = 60; 23 24 if (scrollTop > productTop - menuOffset && scrollTop + galleryHeight < productBottom) { 25 // Sticky behavior 26 newTop = scrollTop - productTop + menuOffset; 27 } else if (scrollTop + galleryHeight >= productBottom) { 28 // Reached the bottom of the product container 29 newTop = productRect.height - galleryHeight + menuOffset; 30 } else { 31 // At the top of the product container 32 newTop = 0; 33 } 34 35 gallery.style.transform = `translateY(${newTop}px)`; 36 37 lastScrollTop = scrollTop; 38 ticking = false; 39 } 40 41 window.addEventListener('scroll', function() { 42 if (!ticking) { 43 window.requestAnimationFrame(function() { 44 updateGalleryPosition(); 45 ticking = false; 46 }); 47 48 ticking = true; 49 } 50 }); 51 52 // Initial position 53 updateGalleryPosition(); 54 }); 55 56var showSubscribePromo = false; 57 58function checkSubscription() { 59 $('select.wcsatt-options-product-dropdown').val('1_month').trigger('change'); 60 // 'yes' or 'no' 61 var option = $('input[name="subscribe-to-action-input"]:checked').val(); 62 63 if ($('.wcsatt-options-product-dropdown option[selected]').length) { 64 var period = parseInt($('.wcsatt-options-product-dropdown option[selected]').val()); 65 } else { 66 var period = 1; 67 } 68 var hasSubscription = false; 69 if (option == 'yes') { 70 hasSubscription = true; 71 } 72 $('.m-subscribe-select select').val(period).trigger('change'); 73 74 $('.summary .m-price > *').removeClass('is-active'); 75 76 var btn_text = 'Buy now'; 77 var btn_price = ''; 78 79 if ( hasSubscription ) { 80 $('.summary .m-price-offer').addClass('is-active'); 81 $('.summary .m-price-main').addClass('is-active'); 82 $('.summary .m-price-main').addClass('subscription-price'); 83 $('.summary .m-price-main').removeClass('single-price'); 84 $('.summary .m-price-main').css('text-decoration', 'line-through'); 85 86 $('#purchase-type-subscribe').prop('checked', true); 87 btn_text = 'Subscribe'; 88 $('.summary').attr('data-payment', 'subscription'); 89 } else { 90 $('.summary .m-price-main').css('text-decoration', ''); 91 $('.summary .m-price-main').addClass('is-active'); 92 $('.summary .m-price-main').addClass('single-price'); 93 $('.summary .m-price-main').removeClass('subscription-price'); 94 $('#purchase-type-one').prop('checked', true); 95 $('.summary').attr('data-payment', 'single'); 96 } 97 98 if ($('.summary .m-price > .is-active > .woocommerce-Price-amount').length) { 99 btn_price = $('.summary .m-price > .is-active > .woocommerce-Price-amount').html(); 100 } 101 102 $('.single_add_to_cart_button').html(` 103 <span class="js-cart-button">${btn_text}</span> 104 <span class="js-product-price">${btn_price}</span> 105 `); 106 if ($('.single_add_to_cart_button').hasClass('is-preorder')) { 107 $('.single_add_to_cart_button').html('Pre-order'); 108 } else { 109 $('.single_add_to_cart_button').html('Add to bag'); 110 } 111 112 $('[name="instant-buy"]').html(btn_text); 113 if ($('#custom-newsletter-register').is(':checked')) { 114 $('#kl_newsletter_checkbox').prop('checked', 'checked'); 115 } 116 117 118} 119function onCheckout() { 120 $('.m-out-different .kl_sms_consent_checkbox_field').insertAfter('.woocommerce-shipping-fields .validate-phone'); 121 $('.m-out-different .woocommerce-account-fields').insertAfter('.custom-newsletter-register'); 122 $('#billing_email').each(function () { 123 var email = $(this).val(); 124 $('.js-checkout-email').text(email); 125 }); 126 if ($('#custom-newsletter-register').is(':checked')) { 127 $('#kl_newsletter_checkbox').prop('checked', 'checked'); 128 } 129 130 131} 132function formCheck() { 133 $('.gfield input, .gfield select, .gfield textarea').each(function () { 134 var field = $(this).closest('.gfield'); 135 var input = $(this); 136 if (input.attr('type') == 'checkbox' || input.attr('type') == 'radio') { 137 field.addClass('not-field'); 138 } else { 139 if (input.val() && input.val().length > 0) { 140 field.addClass('has-value'); 141 } else { 142 field.removeClass('has-value'); 143 } 144 } 145 }); 146 $('.gfield input, .gfield select, .gfield textarea').on('blur', function () { 147 var field = $(this).closest('.gfield'); 148 var input = $(this); 149 if (input.val() && input.val().length > 0) { 150 field.addClass('has-value'); 151 } else { 152 field.removeClass('has-value'); 153 } 154 }); 155 $('.woocommerce-billing-fields__field-wrapper p input, .woocommerce-billing-fields__field-wrapper p select, .woocommerce-billing-fields__field-wrapper p textarea, .woocommerce-shipping-fields__field-wrapper p input, .woocommerce-shipping-fields__field-wrapper p select, .woocommerce-shipping-fields__field-wrapper p textarea').each(function () { 156 var field = $(this).closest('p'); 157 var input = $(this); 158 if (input.attr('type') == 'checkbox' || input.attr('type') == 'radio') { 159 field.addClass('not-field'); 160 } else { 161 if (input.val() && input.val().length > 0) { 162 field.addClass('has-value'); 163 } else { 164 field.removeClass('has-value'); 165 } 166 } 167 }); 168 $('.woocommerce-billing-fields__field-wrapper p select, .woocommerce-shipping-fields__field-wrapper p select').each(function () { 169 var field = $(this).closest('p'); 170 field.addClass('has-value'); 171 }); 172 $('.woocommerce-billing-fields__field-wrapper p input, .woocommerce-billing-fields__field-wrapper p select, .woocommerce-billing-fields__field-wrapper p textarea, .woocommerce-shipping-fields__field-wrapper p input, .woocommerce-shipping-fields__field-wrapper p select, .woocommerce-shipping-fields__field-wrapper p textarea').on('blur', function () { 173 var field = $(this).closest('p'); 174 var input = $(this); 175 if (input.val() && input.val().length > 0) { 176 field.addClass('has-value'); 177 } else { 178 field.removeClass('has-value'); 179 } 180 }); 181 $('.woocommerce-billing-fields__field-wrapper p select, .woocommerce-shipping-fields__field-wrapper p select').on('blur', function () { 182 var field = $(this).closest('p'); 183 field.addClass('has-value'); 184 }); 185} 186function onResize() { 187 $('body.hero-first .header-main.has-bar').each(function () { 188 $(this).css('padding-top', $('.bar').outerHeight()); 189 }); 190 $('.mission').each(function () { 191 var height = $(this).find('.mission-secondary').outerHeight(); 192 $(this).attr("style", '--secondary:' + height + 'px;'); 193 }); 194} 195var totalDelay = 0; 196function animationsScatter() { 197 $('.x-down').each(function () { 198 var $this = $(this); 199 if ($(this).isInViewport()) { 200 setTimeout(function () { 201 $this.addClass('x-down-active'); 202 }, totalDelay); 203 totalDelay += 350; 204 } 205 }); 206} 207function animations() { 208 $('.x-down').each(function () { 209 if ($(this).isInViewport()) { 210 $(this).addClass('x-down-active'); 211 } 212 }); 213 $('.x-left').each(function () { 214 if ($(this).isInViewport()) { 215 $(this).addClass('x-left-active'); 216 } 217 }); 218 $('.x-right').each(function () { 219 if ($(this).isInViewport()) { 220 $(this).addClass('x-right-active'); 221 } 222 }); 223 $('.x-up').each(function () { 224 if ($(this).isInViewport()) { 225 $(this).addClass('x-up-active'); 226 } 227 }); 228} 229 230function loadAndScroll() { 231 var s = $(window).scrollTop(); 232 if (s > 150) { 233 $('body').addClass('sticky-active'); 234 } else { 235 $('body').removeClass('sticky-active'); 236 } 237} 238function intuUpdatedCheckout() { 239 if ($('[data-id="information"] .ppc-button-wrapper').length > 0 && !$('[data-id="payment"] .ppc-button-wrapper').length) { 240 $('[data-id="information"] .ppc-button-wrapper').appendTo('[data-id="payment"] .payment_method_ppcp-gateway.payment_box'); 241 } 242} 243function onReady() { 244 onCheckout(); 245 246 animations(); 247 $(window).on('resize scroll', function () { 248 animations(); 249 }); 250 251 if ($('.js-intro-links').length) { 252 var introLinks = $('.js-intro-links').html(); 253 $(introLinks).insertAfter('.header-sticky'); 254 $('.js-intro-links').remove(); 255 } 256 257 var baseUrl = php.site_url; 258 $('#billing_email').on('blur', function () { 259 $('#billing_email_field .custom-error-notice').remove(); 260 var email = $(this).val(); 261 $.ajax({ 262 url: php.ajax_url, 263 type: 'POST', 264 data: { 265 action: 'check_email_account', 266 'email': email, 267 } 268 }) 269 .success(function (results) { 270 if (!results.success) { 271 $('#billing_email_field').append(`<div class="custom-error-notice">It seems like you already have an account. Please <a href="${baseUrl}/my-account/">log in</a> first.</div>`); 272 } 273 }) 274 275 .fail(function (data) { 276 console.log(data.responseText); 277 console.log('Request failed: ' + data.statusText); 278 }) 279 280 }); 281 282 if ($(window).width() <= 767 && $('.igrid-item').length) { 283 $(window).scroll(function () { 284 $('.igrid-item').each(function () { 285 var self = $(this); 286 if (self.isInMiddleViewport()) { 287 self.addClass('is-hover'); 288 } else { 289 self.removeClass('is-hover'); 290 } 291 }); 292 }); 293 } 294 295 296 $('body').on('click', '.js-custom-add-to-cart', function (e) { 297 e.preventDefault(); 298 $('form.cart').submit(); 299 }); 300 $('body').on('click', '[name="instant-buy"]', function (e) { 301 e.preventDefault(); 302 if ($('form.cart input[name="custom-redirect-to"]').length === 0) { 303 $('form.cart').append('<input type="hidden" name="custom-redirect-to" value="checkout">'); 304 } 305 $('form.cart').submit(); 306 }); 307 308 309 310 $('select.wcsatt-options-product-dropdown').val('3_month').trigger('change'); 311 checkSubscription(); 312 313 $('body').on('change', 'input[name="subscribe-to-action-input"]', function () { 314 checkSubscription(); 315 }); 316 317 $('body').on('change', 'input[name="purchase-type"]', function () { 318 if ($(this).val() == 'subscribe') { 319 $('input[name="subscribe-to-action-input"][value="yes"]').prop('checked', true).trigger('change'); 320 } else { 321 $('input[name="subscribe-to-action-input"][value="no"]').prop('checked', true).trigger('change'); 322 } 323 checkSubscription(); 324 }); 325 326 $('body').on('change', '.m-subscribe-select select', function () { 327 var months = parseInt($(this).val()); 328 $('select.wcsatt-options-product-dropdown').val(months + '_month').trigger('change'); 329 }); 330 331 332 333 $('.purchase-button').on('click', function() { 334 // Remove active class from all buttons 335 $('.purchase-button').removeClass('active'); 336 // Add active class to the clicked button 337 $(this).addClass('active'); 338 // Set the radio button based on selection 339 var purchaseType = $(this).data('purchase-type'); 340 if(purchaseType === 'subscribe') { 341 $('#purchase-type-subscribe').prop('checked', true).trigger('change'); 342 // Show subscription options 343 $('.m-subscribe-select').show(); 344 } else { 345 $('#purchase-type-one').prop('checked', true).trigger('change'); 346 // Hide subscription options 347 $('.m-subscribe-select').hide(); 348 } 349 }); 350 351 // On page load, check if purchase type is 'subscribe' and show/hide accordingly 352 if($('#purchase-type-subscribe').is(':checked')) { 353 $('.m-subscribe-select').show(); 354 } else { 355 $('.m-subscribe-select').hide(); 356 } 357 358 // Handle quantity box selection 359 $('.quantity-box').on('click', function() { 360 // Remove active class from all quantity boxes 361 $('.quantity-box').removeClass('active'); 362 // Add active class to the clicked box 363 $(this).addClass('active'); 364 // Get the selected quantity from data attribute 365 var selectedQuantity = $(this).data('quantity'); 366 // Set the hidden input value 367 $('#selected-quantity').val(selectedQuantity); 368 // Update the quantity input in the form 369 $('input.qty').val(selectedQuantity); 370 }); 371 372 373 if ($('body.single-product .woocommerce-message .button').length && $('.woocommerce-message .button').text() == 'View cart') { 374 // location.href = php.site_url + '/checkout/'; 375 $('#fly-cart').addClass('is-active'); 376 $('html').addClass('overlay-active'); 377 } 378 379 if ($('.fly-cart-list > *').length && location.href.indexOf('?removed_item') > -1) { 380 $('#fly-cart').addClass('is-active'); 381 $('html').addClass('overlay-active'); 382 } 383 if ($('.fly-cart-list > *').length && location.href.indexOf('?add-to-cart') > -1) { 384 $('#fly-cart').addClass('is-active'); 385 $('html').addClass('overlay-active'); 386 } 387 388 $('.js-product-price').each(function () { 389 var price = $('.summary .m-price > .is-active > .woocommerce-Price-amount').html(); 390 $(this).html(price); 391 }); 392 $('.js-price-afterpay').each(function () { 393 var price = parseFloat($('.summary .m-price > .is-active > .amount bdi').text().substring(1)); 394 var div = price / 4; 395 $(this).html(Math.ceil(div * 100) / 100); 396 }); 397 var formatCurrency = new Intl.NumberFormat('en-US', { 398 style: 'currency', 399 currency: 'USD', 400 }); 401 $('.product .summary input.qty').each(function () { 402 var q = parseInt($(this).val()); 403 var p = parseFloat($('.summary .m-price > .is-active > .amount bdi').text().substring(1)); 404 var t = p * q; 405 var f = formatCurrency.format(t); 406 $('.js-product-price').text(f); 407 $('.js-price-afterpay').each(function () { 408 var div = t / 4; 409 $(this).html(formatCurrency.format(div)); 410 }); 411 }); 412 $('body').on('change', '.product .summary input.qty', function () { 413 var q = parseInt($(this).val()); 414 var p = parseFloat($('.summary .m-price > .is-active > .amount bdi').text().substring(1)); 415 var t = p * q; 416 var f = formatCurrency.format(t); 417 $('.js-product-price').text(f); 418 $('.js-price-afterpay').each(function () { 419 var div = t / 4; 420 $(this).html(formatCurrency.format(div)); 421 }); 422 }); 423 424 $('.marquee').each(function () { 425 var self = $(this); 426 var offset = 0; 427 var clone = self.html(); 428 setInterval(() => { 429 offset--; 430 self.css('margin-left', offset); 431 }, 35); 432 setInterval(() => { 433 self.append(clone); 434 }, 10000); 435 }); 436 437 $('body').on('click', '.m-out-tab .back-button', function (e) { 438 e.preventDefault(); 439 var tab = $(this).closest('.m-out-tab'); 440 var id = tab.data('id'); 441 tab.removeClass('is-active'); 442 tab.prev().addClass('is-active'); 443 $('.nav-crumbs li[data-id="' + id + '"]').removeClass('active done'); 444 $('.nav-crumbs li[data-id="' + id + '"]').prev().addClass('active done'); 445 }); 446 447 448 $('body').on('click', '.m-out .go-to', function (e) { 449 e.prevent
449Default(); 450 var i = $(this).data('target'); 451 $('.m-out-tab').removeClass('is-active'); 452 $('.m-out-tab[data-id="' + i + '"]').addClass('is-active'); 453 $('.nav-crumbs li').removeClass('active done'); 454 $('.nav-crumbs li[data-id="' + i + '"]').addClass('done active'); 455 $('.nav-crumbs li[data-id="' + i + '"]').prevAll().addClass('done'); 456 }); 457 458 $('body').on('click', '.m-out .nav-crumbs li.done:not(.active) > span', function (e) { 459 e.preventDefault(); 460 var i = $(this).closest('li').data('id'); 461 $('.m-out-tab').removeClass('is-active'); 462 $('.m-out-tab[data-id="' + i + '"]').addClass('is-active'); 463 $('.nav-crumbs li').removeClass('active done'); 464 $('.nav-crumbs li[data-id="' + i + '"]').addClass('done active'); 465 $('.nav-crumbs li[data-id="' + i + '"]').prevAll().addClass('done'); 466 }); 467 468 $('body').on('click', '.m-out-tab[data-id="information"] .next-button', function (e) { 469 e.preventDefault(); 470 var tab = $(this).closest('.m-out-tab'); 471 var id = tab.data('id'); 472 var hasErrors = false; 473 474 tab.find('.validate-required').each(function () { 475 var self = $(this); 476 var input = self.find('.woocommerce-input-wrapper > :first-child'); 477 if (input[0].nodeName == 'INPUT' || input[0].nodeName == 'TEXTAREA' || input[0].nodeName == 'SELECT') { 478 if (input.attr('type') == 'email') { 479 if (!isEmail(input.val())) { 480 self.addClass('has-error'); 481 hasErrors = true; 482 } else { 483 self.removeClass('has-error'); 484 } 485 } else { 486 if (!input.val()) { 487 self.addClass('has-error'); 488 hasErrors = true; 489 } else { 490 self.removeClass('has-error'); 491 } 492 } 493 } else { 494 self.removeClass('has-error'); 495 } 496 }); 497 498 if ($('#shipping_state').val().length === 0) { 499 if ($('#shipping_state option').length > 0) { 500 $('#shipping_state_field').addClass('has-error'); 501 hasErrors = true; 502 } 503 else { 504 $('#shipping_state_field').removeClass('has-error'); 505 } 506 } 507 setTimeout(function () { 508 if (!hasErrors) { 509 $('.nav-crumbs li[data-id="' + id + '"]').removeClass('active'); 510 $('.nav-crumbs li[data-id="' + id + '"]').next().addClass('active done'); 511 tab.removeClass('is-active'); 512 tab.next().addClass('is-active'); 513 514 if ($('select#shipping_country').length) { 515 var country = $('#shipping_country option[value="' + $('#shipping_country').val() + '"]').text(); 516 } else { 517 var country = $('#shipping_country_field .woocommerce-input-wrapper > strong').text(); 518 } 519 var address = $('#shipping_address_1').val() + ' ' + $('#shipping_address_2').val() + ', ' + $('#shipping_city').val() + ', ' + country; 520 $('.js-checkout-address').text(address); 521 } 522 }, 10); 523 }); 524 525 526 527 if ($('input[name="custom-billing-type"]:checked').val() == 'different') { 528 $('.m-out-different').removeClass('concealed'); 529 $('#ship-to-different-address-checkbox').prop('checked', 'checked'); 530 } else { 531 $('.m-out-different').addClass('concealed'); 532 } 533 534 if ($('#custom-newsletter-register').is(':checked')) { 535 $('#kl_newsletter_checkbox').prop('checked', 'checked'); 536 } 537 538 539 540 $('body').on('click', '.m-out-sidebar a.woocommerce-remove-coupon', function (e) { 541 $(this).closest('.checkout_coupon_applied').remove(); 542 }); 543 544 $('input[name="custom-billing-type"]').on('change', function () { 545 jQuery(document.body).trigger("update_checkout"); 546 if ($('input[name="custom-billing-type"]:checked').val() == 'different') { 547 $('.m-out-different').removeClass('concealed'); 548 $('#ship-to-different-address-checkbox').prop('checked', 'checked'); 549 // $('.js-checkout-address').text('â'); 550 } else { 551 $('.m-out-different').addClass('concealed'); 552 // if ($('select#shipping_country').length) { 553 // var country = $('#shipping_country option[value="' + $('#shipping_country').val() + '"]').text(); 554 // } else { 555 // var country = $('#shipping_country_field .woocommerce-input-wrapper > strong').text(); 556 // } 557 // var address = $('#shipping_address_1').val() + ' ' + $('#shipping_address_2').val() + ', ' + $('#shipping_city').val() + ', ' + country; 558 // $('.js-checkout-address').text(address); 559 } 560 }); 561 $(document).ajaxComplete(function () { 562 if (showSubscribePromo && $('input[name="purchase-type"]:checked').val() == 'one') { 563 $('body').on('click', '.single_add_to_cart_button:not(.was-asked)', function (e) { 564 if ($('input[name="purchase-type"]:checked').val() == 'one') { 565 e.preventDefault(); 566 $('#popup-save').addClass('is-active'); 567 $(this).addClass('was-asked'); 568 $('html').addClass('overlay-active'); 569 var responseInterval = setInterval(function () { 570 if (!$('#popup-save').hasClass('is-active')) { 571 clearInterval(responseInterval); 572 $('.single_add_to_cart_button').trigger('click'); 573 } 574 }, 10); 575 } 576 }); 577 } 578 var total = $('#order_review .order-total td').html(); 579 $('.m-out-total .h3').html(total); 580 581 582 var shipping = $('input.shipping_method:checked').parents('li').find('bdi').text(); 583 //console.log(shipping); 584 if (shipping) { 585 $('.js-checkout-shipping').text(shipping); 586 } else { 587 shipping = $('input.shipping_method').parents('li').find('bdi').text(); 588 $('.js-checkout-shipping').text(shipping); 589 } // Validate if the shipping method has only one option 590 591 }); 592 $('body').on('click', '.m-out-tab[data-id="information"] .next-button', function (e) { 593 if ($('select#shipping_country').length) { 594 var country = $('#shipping_country option[value="' + $('#shipping_country').val() + '"]').text(); 595 } else { 596 var country = $('#shipping_country_field .woocommerce-input-wrapper > strong').text(); 597 } 598 var address = $('#shipping_address_1').val() + ' ' + $('#shipping_address_2').val() + ', ' + $('#shipping_city').val() + ', ' + country; 599 $('.js-checkout-address').text(address); 600 }); 601 $('body').on('click', '.m-out-tab[data-id="shipping"] .next-button', function (e) { 602 e.preventDefault(); 603 var tab = $(this).closest('.m-out-tab'); 604 var id = tab.data('id'); 605 var hasErrors = false;
606 607 tab.find('.m-out-different:not(.concealed) .validate-required').each(function () { 608 var self = $(this); 609 var input = self.find('.woocommerce-input-wrapper > :first-child'); 610 if (input[0].nodeName == 'INPUT' || input[0].nodeName == 'TEXTAREA' || input[0].nodeName == 'SELECT') { 611 if (input.attr('type') == 'email') { 612 if (!isEmail(input.val())) { 613 self.addClass('has-error'); 614 hasErrors = true; 615 } else { 616 self.removeClass('has-error'); 617 } 618 } else { 619 if (!input.val()) { 620 self.addClass('has-error'); 621 hasErrors = true; 622 } else { 623 self.removeClass('has-error'); 624 } 625 } 626 } else { 627 self.removeClass('has-error'); 628 } 629 }); 630 631 if (!hasErrors) { 632 $('.nav-crumbs li[data-id="' + id + '"]').removeClass('active'); 633 $('.nav-crumbs li[data-id="' + id + '"]').next().addClass('active done'); 634 tab.removeClass('is-active'); 635 tab.next().addClass('is-active'); 636 637 var methodDiv = $('input.shipping_method:checked').closest('li'); 638 var method = ''; 639 if (methodDiv.find('label').length) { 640 method = methodDiv.find('label').contents()[0].textContent + ' - ' + methodDiv.find('label bdi').text(); 641 } else { 642 // console.log($('input.shipping_method').closest('li')); 643 var methodDivSingle = $('input.shipping_method').closest('li'); 644 var methodSingle = methodDivSingle.find('label').contents()[0].textContent + ' ' + methodDiv.find('label bdi').text(); 645 method = methodSingle 646 //console.log(methodSingle); 647 } // validate if the shipping option has a single option 648 $('.js-checkout-method').text(method); 649 } 650 }); 651
652 function checkPaypal() { 653 if ($('input[name="payment_method"]:checked').val() == 'ppcp-gateway') { 654 $('.m-out-tab[data-id="payment"] .m-out-tab-footer .next-button').hide(); 655 } else { 656 $('.m-out-tab[data-id="payment"] .m-out-tab-footer .next-button').css('display', 'inline-flex'); 657 } 658 } 659 checkPaypal(); 660 $('body').on('change', 'input[name="payment_method"]', function () { 661 checkPaypal(); 662 }); 663 664 $('body').on('click', '.m-out-tab[data-id="payment"] .next-button', function (e) { 665 e.preventDefault(); 666 $('#place_order').click(); 667 }); 668 669 jQuery('body').on('update_checkout', function () { 670 $('body').addClass('is-loading'); 671 }); 672 jQuery('body').on('checkout_error', function () { 673 if (!$('.js-append-payment .wc_payment_method').length) { 674 $('.m-out-tab[data-id="information"] #order_review #payment .wc_payment_methods').appendTo('.js-append-payment'); 675 } 676 $('.m-out-tab[data-id="information"] #order_review #payment .wc_payment_methods').remove(); 677 $('body').removeClass('is-loading'); 678 }); 679 if ($('#order_review > #ppc-button').length && $('.payment_method_ppcp #ppc-button').length == 0) { 680 $('#order_review > #ppc-button').appendTo('.payment_method_ppcp-gateway'); 681 } 682 intuUpdatedCheckout(); 683 jQuery('body').on('updated_checkout', function () { 684 if ($('#order_review > #ppc-button').length && $('.payment_method_ppcp #ppc-button').length == 0) { 685 $('#order_review > #ppc-button').appendTo('.payment_method_ppcp-gateway'); 686 } 687 if (!$('.js-append-payment .wc_payment_method').length) { 688 $('.m-out-tab[data-id="information"] #order_review #payment .wc_payment_methods').appendTo('.js-append-payment'); 689 } 690 $('body').removeClass('is-loading'); 691 692 if ($('[data-id="shipping"] input[name="billing_email"]').val() == '') { 693 var theEmail = $('[data-id="information"] input[name="billing_email"]').val(); 694 $('[data-id="shipping"] #billing_email_field').addClass('has-value'); 695 $('[data-id="shipping"] input[name="billing_email"]').val(theEmail).trigger('change'); 696 } 697 intuUpdatedCheckout(); 698 }); 699 700 jQuery(document.body).on('updated_checkout', function () { 701 var total = $('#order_review .order-total td').html(); 702 $('.m-out-total .h3').html(total); 703 }); 704 705 if ($('body').hasClass('woocommerce-checkout')) { 706 function appendPaymentCheckout() { 707 if ($('.wc_payment_methods').length) { 708 709 if (!$('.js-append-payment .wc_payment_method').length) { 710 $('.m-out-tab[data-id="information"] #order_review #payment .wc_payment_methods').appendTo('.js-append-payment'); 711 } 712 $('.m-out-tab[data-id="information"] #order_review #payment .wc_payment_methods').remove(); 713 714 $('.m-out-sticky #payment .wc_payment_method ').each(function () { 715 716 if ($(this).find('input').prop('checked')) { 717 718 $(".js-append-payment input").prop('checked', false); 719 $(".js-append-payment").find('#' + $(this).find('input').attr('id')).prop('checked', true); 720 721 } 722 723 }) 724 // $('.m-out-sticky #payment').remove(); 725 } 726 } 727 jQuery('body').on('init_checkout', function () { 728 appendPaymentCheckout(); 729 }); 730 jQuery('body').on('updated_checkout', function () { 731 appendPaymentCheckout(); 732 }); 733 } 734 735 736 737 formCheck(); 738 jQuery(document).on('gform_page_loaded', function (event, form_id, current_page) { 739 formCheck(); 740 }); 741 742 $('body').on('change', '.m-reviews-sort select', function (e) { 743 e.preventDefault(); 744 var url = $(this).parent().data('url'); 745 if ($(this).val() == 'old') { 746 url += '?order-reviews=asc'; 747 } 748 $div = $('<div />'); 749 $('.m-reviews-search input').val(''); 750 $('.m-reviews-body').addClass('is-loading'); 751 $div.load(url + ' .m-reviews', function () { 752 $(".m-reviews-body").empty().append($div.find('.m-reviews-body > *')); 753 $('.m-reviews-body').removeClass('is-loading'); 754 }); 755 }); 756 $('body').on('click', '.m-reviews-pagination a', function (e) { 757 e.preventDefault(); 758 var url = $(this).attr('href'); 759 $('.m-reviews-search').val('');
760 $div = $('<div />'); 761 $('.m-reviews-body').addClass('is-loading'); 762 $div.load(url + ' .m-reviews', function () { 763 $(".m-reviews-body").empty().append($div.find('.m-reviews-body > *')); 764 $('.m-reviews-body').removeClass('is-loading'); 765 }); 766 }); 767 768 $('body').on('keyup', '.m-reviews-search input', function (e) { 769 e.preventDefault(); 770 var url = $(this).parent().data('url'); 771 if ($(this).val().length > 0) { 772 url += '?search-reviews=' + $(this).val(); 773 } 774 $('.m-reviews-sort select').val('new'); 775 $div = $('<div />'); 776 $('.m-reviews-body').addClass('is-loading'); 777 $div.load(url + ' .m-reviews', function () { 778 $(".m-reviews-body").empty().append($div.find('.m-reviews-body > *')); 779 $('.m-reviews-body').removeClass('is-loading'); 780 }); 781 }); 782 783 $('body').on('click', '.m-reviews-sort-toggle', function (e) { 784 e.preventDefault(); 785 $(this).closest('.m-reviews-sort').addClass('is-active'); 786 }); 787 $('body').on('change', '.m-reviews-sort select', function (e) { 788 $(this).closest('.m-reviews-sort').removeClass('is-active'); 789 }); 790 $('body').on('click', '.toggle-product-text', function (e) { 791 e.preventDefault(); 792 if(!$(this).hasClass('is-active')) 793 { 794 $(this).text("- Read Less"); 795 } 796 else 797 { 798 $(this).text("+ Read More"); 799 } 800 $(this).toggleClass('is-active'); 801 802 $('.custom-product-text').slideToggle(); 803 }); 804 805 $('.woocommerce-product-gallery a').fancybox({ 806 'selector': '.woocommerce-product-gallery a', 807 'loop': true, 808 }); 809 810 $('body').on('click', '.m-index .load-more a', function (e) { 811 e.preventDefault(); 812 var $button = $(this); 813 $button.text('Please wait...') 814 $div = $('<div />'); 815 $div.load($(this).attr('href') + ' .m-index', function () { 816 $(".m-index-list > .set").append($div.find('.m-index-list > .set > *')); 817 if ($div.find('.load-more a').length) { 818 $button.text('Load more').attr('href', $div.find('.load-more a').attr('href')); 819 } else { 820 $button.parent().remove(); 821 } 822 }); 823 824 }); 825 826 $('body').on('click', '.faq-header', function (e) { 827 e.preventDefault(); 828 var item = $(this).closest('.faq-item'); 829 if (item.hasClass('is-active')) { 830 item.removeClass('is-active');
831 item.find('.faq-body').slideUp(); 832 } else { 833 item.addClass('is-active'); 834 item.find('.faq-body').slideDown(); 835 836 } 837 }); 838 $('body').on('click', '.fly-tabs-nav a', function (e) { 839 e.preventDefault(); 840 var nr = $(this).index() + 1; 841 var group = $(this).closest('.fly-tabs'); 842 group.find('.fly-tabs-nav a').removeClass('is-active'); 843 $(this).addClass('is-active'); 844 group.find('.fly-tab').removeClass('is-active'); 845 group.find('.fly-tab[data-id="' + nr + '"]').addClass('is-active'); 846 }); 847 848 849 $('body').on('click', '#fly-cart .stepper-decrease, #fly-cart .stepper-increase', function (e) { 850 var qty = parseInt($(this).closest('.stepper').find('> div').text()); 851 var n = qty - 1; 852 if ($(this).hasClass('stepper-increase')) { 853 n = qty + 1; 854 } 855 if (qty > 1) { 856 $('.stepper').addClass('is-loading'); 857 var cart_item_key = $(this).closest('.stepper').data('key'); 858 $.ajax({ 859 type: 'POST', 860 dataType: 'json', 861 url: php.ajax_url, 862 data: { action: 'update_item_from_cart', 'cart_item_key': cart_item_key, 'qty': n, }, 863 success: function (data) { 864 var count = data.data.cart_count; 865 $('.js-cart-count').text(count); 866 $('.stepper').removeClass('is-loading'); 867 var $div = $('<div />'); 868 $('#fly-cart .fly-card-inner').addClass('is-loading'); 869 $div.load(php.site_url + ' #fly-cart', function () { 870 $("#fly-cart .fly-card-inner").empty().append($div.find('.fly-card-inner > *')); 871 $('#fly-cart .fly-card-inner').removeClass('is-loading'); 872 }); 873 } 874 }); 875 } 876 }); 877 878 $('.quantity .stepper > div').each(function () { 879 var initial = $(this).closest('.quantity').find('input.qty').val(); 880 $(this).text(initial); 881 }); 882 /* 883 $('body').on('click', '.stepper-increase', function (e) { 884 e.preventDefault(); 885 var el = $(this).closest('.stepper'); 886 var qty = el.find('> div'); 887 var amount = parseInt(qty.text()); 888 qty.text(amount + 1); 889 var input = $(this).closest('.quantity').find('input.qty'); 890 input.val(amount + 1).trigger('change'); 891 }); 892 $('body').on('click', '.stepper-decrease', function (e) { 893 e.preventDefault(); 894 var el = $(this).closest('.stepper'); 895 var qty = el.find('> div'); 896 var amount = parseInt(qty.text()); 897 if (amount > 1) { 898 qty.text(amount - 1); 899 var input = $(this).closest('.quantity').find('input.qty'); 900 input.val(amount - 1).trigger('change'); 901 } 902 }); 903 */ 904 905 $(document.body).on('updated_cart_totals', function () { 906 $('.js-cart-count').text($('.woocommerce-cart-form__contents').data('count')); 907 908 var $div = $('<div />'); 909 $('#fly-cart .fly-card-inner').addClass('is-loading'); 910 $div.load(php.site_url + ' #fly-cart', function () { 911 $("#fly-cart .fly-card-inner").empty().append($div.find('.fly-card-inner > *')); 912 $('#fly-cart .fly-card-inner').removeClass('is-loading'); 913 }); 914 }); 915 916 $('body').on('click', '.fly-close', function (e) { 917 e.preventDefault(); 918 $('.fly').removeClass('is-active'); 919 $('html').removeClass('overlay-active'); 920 }); 921 $('body').on('click', '.menu-button', function (e) { 922 e.preventDefault(); 923 $('html').toggleClass('menu-is-active'); 924 }); 925 $('body').on('click', '.nav-panel li.menu-item-has-children > a > .menu-item-dropdown-toggle', function (e) { 926 e.preventDefault(); 927 $('.menu-page-1').css('margin-left', '-100vw'); 928 var items = $(this).closest('li').find('> ul').html(); 929 $('.menu-page-2 .nav-panel > ul').empty().append(items); 930 }); 931 $('body').on('click', '.menu-page-2 a.back', function (e) { 932 e.preventDefault(); 933 $('.menu-page-1').css('margin-left', '0vw'); 934 }); 935 936 $('body').on('click', '.popup-close, .js-close-popup', function (e) { 937 e.preventDefault(); 938 $('.popup-outer').removeClass('is-active'); 939 $('html').removeClass('overlay-active'); 940 }); 941 942 $('.popup-form form').on('submit', function () { 943 $('.popup-outer').removeClass('is-active'); 944 $('html').removeClass('overlay-active'); 945 }); 946 947 $('body').on('click', '.js-switch-subscribe', function (e) { 948 e.preventDefault(); 949 $('#purchase-type-subscribe').prop('checked', true).trigger('change'); 950 $('.popup-outer').removeClass('is-active'); 951 $('html').removeClass('overlay-active'); 952 }); 953 954 $('body').on('change', 'input[name="purchase-type"]', function () { 955 var q = parseInt($('.product .summary input.qty').val()); 956 var p = parseFloat($('.summary .m-price > .is-active > .amount bdi').text().substring(1)); 957 var t = p * q; 958 var f = formatCurrency.format(t); 959 var s = formatCurrency.format(t * 0.15); 960 if ($(this).val() == 'one') { 961 $('.js-price-save').text(s); 962 if (showSubscribePromo) { 963 $('#popup-save').addClass('is-active'); 964 $('html').addClass('overlay-active'); 965 } 966 $('.summary .m-price > *').removeClass('is-active'); 967 $('.summary .m-price > :nth-child(1)').addClass('is-active'); 968 } else { 969 //$('.summary .m-price > *').removeClass('is-active'); 970 $('.summary .m-price > :nth-child(2)').addClass('is-active'); 971 } 972 $('.js-product-price').each(function () { 973 $(this).html(f); 974 }); 975 $('.js-price-afterpay').each(function () { 976 var div = t / 4; 977 $(this).html(formatCurrency.format(div)); 978 }); 979 }); 980 981 $('body').on('click', '.popup-outer', function (e) { 982 if (e.target !== this) { 983 return; 984 } 985 e.preventDefault(); 986 $('.popup-outer').removeClass('is-active'); 987 $('html').removeClass('overlay-active'); 988 }); 989 $('body').on('click', '.fly', function (e) { 990 if (e.target !== this) { 991 return; 992 } 993 e.preventDefault(); 994 $('.fly').removeClass('is-active'); 995 $('html').removeClass('overlay-active'); 996 }); 997 $('body').on('click', 'a[href^="#popup-"]', function (e) { 998 e.preventDefault(); 999 var i = $(this).attr('href').substring(7); 1000 $('#popup-' + i).addClass('is-active'); 1001 $('html').addClass('overlay-active'); 1002 }); 1003 $('body').on('click', 'a[href^="#fly-"]', function (e) { 1004 e.preventDefault(); 1005 $('html').removeClass('menu-is-active'); 1006 var i = $(this).attr('href').substring(5); 1007 $('#fly-' + i).addClass('is-active'); 1008 $('html').addClass('overlay-active'); 1009 }); 1010 1011 if ($(window).width() <= 767) { 1012 $('.m-cart-body .woocommerce-cart-form__cart-item').each(function () { 1013 var self = $(this); 1014 self.find('.product-quantity .quantity').insertAfter(self.find('.custom-product-cart > :nth-child(2) > :nth-child(1)')); 1015 self.find('.product-subtotal .woocommerce-Price-amount').insertAfter(self.find('.custom-product-cart > :nth-child(2) > :nth-child(1)')); 1016 }); 1017 } 1018 1019 loadAndScroll(); 1020 $(window).scroll(function () { 1021 loadAndScroll(); 1022 }); 1023 onResize(); 1024 $(window).resize(function () { 1025 onResize(); 1026 }) 1027 1028 $('.testimonials-body .owl-carousel').owlCarousel({ 1029 items: 1, 1030 loop: true, 1031 nav: true, 1032 dots: false, 1033 margin: 100, 1034 autoplay: true, 1035 autoplayTimeout: 6000, 1036 navText: ['', ''], 1037 }); 1038 $('.fp-slider .owl-carousel').owlCarousel({ 1039 items: 2, 1040 loop: true, 1041 nav: true, 1042 dots: false, 1043 margin: 10, 1044 navText: ['', ''], 1045 responsive: { 1046 768: { 1047 items: 3, 1048 margin: 20, 1049 } 1050 } 1051 }); 1052 $('.product-slider .owl-carousel').owlCarousel({ 1053 items: 1, 1054 loop: true, 1055 nav: false, 1056 dots: true, 1057 margin: 0, 1058 navText: ['', ''], 1059 }); 1060 1061 $('.m-out-shipping').each(function () { 1062 var text = $(this).contents().get(0).nodeValue.trim(); 1063 $(this).contents().get(0).remove(); 1064 $(this).prepend('<div class="h5 upper color-1 mb-h">Shipping Method</div>'); 1065 }); 1066 1067 function recentNav() { 1068 $('.recent-body').each(function () { 1069 var height = $(this).find('.card-image').first().outerHeight(); 1070 $('.recent-body .owl-nav').css('max-height', height); 1071 }); 1072 } 1073 $('.recent-body .owl-carousel').owlCarousel({ 1074 loop: true, 1075 nav: true, 1076 dots: false, 1077 margin: 20, 1078 navText: ['', ''], 1079 items: 1, 1080 responsive: { 1081 768: { 1082 items: 2 1083 }, 1084 1025: { 1085 items: 3 1086 }, 1087 }, 1088 onInitialized: function () { 1089 recentNav(); 1090 }, 1091 onResized: function () { 1092 recentNav(); 1093 }, 1094 }); 1095} 1096 1097$ = jQuery.noConflict(); 1098 1099let vh = window.innerHeight * 0.01;
1100document.documentElement.style.setProperty('--vh', vh + 'px'); 1101 1102// Usage: height: calc(var(--vh, 1vh) * 100); 1103 1104 1105/***** Resize Items *****/ 1106resizeItems = function () { 1107 1108 /***** Something *****/ 1109 if ($("#something").length > 0) { 1110 1111 }; 1112 1113 // only on desktop 1114 if (w > 1025) { 1115 1116 } 1117 // on tablet 1118 if (w < 1026) { 1119 1120 } 1121 // on phone 1122 if (w < 768) { 1123 1124 } 1125 1126}; 1127 1128 1129$(window).on('load', function () { 1130 /***** Resize Items *****/ 1131 resizeItems(); 1132 1133 1134 /***** Transitional Effects *****/ 1135 setTimeout(function () { 1136 $("body a, body input[type='submit'], button").addClass("loaded"); 1137 }, 1000); 1138 1139}); 1140 1141$(document).ready(function () { 1142 /***** Resize Items *****/ 1143 resizeItems(); 1144 onReady(); 1145 1146}); 1147 1148 1149var w = $(window).width(); 1150$(window).resize(function () { 1151 /***** Resize Items *****/ 1152 if ($(window).width() == w) return; 1153 w = $(window).width(); 1154 resizeItems(); 1155}); 1156 1157 1158/***** Adjust Height Function *****/ 1159jQuery.fn.adjustHeight = function () { 1160 var maxHeightFound = 0; 1161 this.css('min-height', '1px'); 1162 if (this.is('a')) { 1163 this.removeClass('loaded'); 1164 }; 1165 this.each(function () { 1166 if ($(this).height() > maxHeightFound) { 1167 maxHeightFound = $(this).height(); 1168 } 1169 }); 1170 this.css('min-height', maxHeightFound); 1171 if (this.is('a')) { 1172 this.addClass('loaded'); 1173 }; 1174}; 1175 1176jQuery.fn.adjustOuterHeight = function () { 1177 var maxHeightFound = 0; 1178 this.css('min-height', '1px'); 1179 this.each(function () { 1180 if ($(this).outerHeight(true) > maxHeightFound) { 1181 maxHeightFound = $(this).outerHeight(true); 1182 } 1183 }); 1184 this.css('min-height', maxHeightFound); 1185}; 1186 1187jQuery.fn.isInViewport = function () { 1188 var elementTop = $(this).offset().top; 1189 var elementBottom = elementTop + $(this).outerHeight(); 1190 1191 var viewportTop = $(window).scrollTop(); 1192 var viewportBottom = viewportTop + $(window).height(); 1193 1194 return elementBottom > viewportTop && elementTop < viewportBottom; 1195}; 1196 1197jQuery.fn.isInMiddleViewport = function () { 1198 var elementTop = $(this).offset().top; 1199 var elementBottom = elementTop + $(this).outerHeight(); 1200 1201 var viewportTop = $(window).scrollTop() + $(window).height() * 0.6; 1202 1203 return viewportTop > elementTop; 1204}; 1205 1206function isEmail(email) { 1207 var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/; 1208 return regex.test(email); 1209} 1210 1211/* Get cookie value by name */ 1212function getCookie(c_name) { 1213 var c_value = " " + document.cookie; 1214 var c_start = c_value.indexOf(" " + c_name + "="); 1215 if (c_start == -1) { 1216 c_value = null; 1217 } 1218 else { 1219 c_start = c_value.indexOf("=", c_start) + 1; 1220 var c_end = c_value.indexOf(";", c_start); 1221 if (c_end == -1) { 1222 c_end = c_value.length; 1223 } 1224 c_value = unescape(c_value.substring(c_start, c_end)); 1225 } 1226 return c_value; 1227} 1228 1229/* Set cookie value and expiry by name */ 1230function createCookie(name, value, days) { 1231 var expires; 1232 1233 if (days) { 1234 var date = new Date(); 1235 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 1236 expires = "; expires=" + date.toGMTString(); 1237 } else { 1238 expires = ""; 1239 } 1240 document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + expires + "; path=/"; 1241} 1242 1243/* Load checkout page with cookies value. */ 1244$(document).ready(function () { 1245 var current_path = window.location.pathname; 1246 1247 // Remove paypal for subscription for cart. 1248 if (current_path === '/my-bag/') { 1249 if ($('tr').hasClass('recurring-totals')) { 1250 $('.ppc-button-wrapper').remove(); 1251 $('.ppc-button-wrapper').css('display', 'none'); 1252 } 1253 } 1254 1255 // Remove paypal for subscription for checkout 1256 if (current_path === '/checkout/') { 1257 1258 if ($('tr').hasClass('recurring-total')) { 1259 console.log('yes'); 1260 $('.wc_payment_method.payment_method_ppcp-gateway').remove(); 1261 $('.wc_payment_method.payment_method_ppcp-gateway').css('display', 'none'); 1262 } 1263 } 1264 1265 // Add disclaimer for non AUS shipping. 1266 var ship_country = $('#shipping_country').val(); 1267 if (ship_country !== 'AU') { 1268 $('.m-out-shipping.m-out-box').append('<div class="shipping_disclaimer"><strong>Please note:</strong> The prices shown on this site are in AUD $. International purchases are not eligible for returns. Customers purchasing from outside Australia are responsible for the payment of international shipment and the duties that may occur.</div>') 1269 $('.shipping_disclaimer').css('margin-top', '10px'); 1270 $('.shipping_disclaimer').css('padding', '10px'); 1271 $('.shipping_disclaimer').css('font-size', '12px'); 1272 $('.shipping_disclaimer').css('border', '1px solid #CCC'); 1273 $('.shipping_disclaimer').css('background-color', '#EFEFEF'); 1274 $('.shipping_disclaimer').css('border-radius', '4px'); 1275 } 1276 1277 $('#custom-newsletter-register').on('change', function (e) { 1278 e.preventDefault(); 1279 $('#kl_newsletter_checkbox').prop('checked', $('#custom-newsletter-register').prop('checked')); 1280 }); 1281 1282 $('#kl_newsletter_checkbox').on('change', function (e) { 1283 e.preventDefault(); 1284 $('#custom-newsletter-register').prop('checked', $('#kl_newsletter_checkbox').prop('checked')); 1285 }); 1286 1287}); 1288 1289jQuery(document).ready(function($) { 1290 var selectedQuantity = 1; // Default selected tub quantity 1291 var quantityInput = 1; // Default input quantity 1292 var subscriptionDiscount = 0.85; 1293 1294 // Tiered discount promo (July 2026). window.intuPromo is localized from 1295 // include/tiered-promo.php; .onetime / .subscribe hold the fraction OFF per 1296 // tier ([0]=1 item, [1]=2 items, [2]=3+ items). Display only â the real 1297 // money-off is applied by Woo Discount Rules Pro. 1298 var promo = window.intuPromo || { active: false, onetime: [], subscribe: [], defaultSubscribe: false, syncFrequency: false }; 1299 1300 var isSubscription = !!(promo.active && promo.defaultSubscribe); // Flag to check if it's a subscription 1301 // Per-tier price multipliers (1 - fraction off), indexed by box order. 1302 var specialSaleQuantityPctOff = promo.active ? promo.onetime.map(function (f) { return 1 - f; }) : []; 1303 var specialSaleSubscriptionPctOff = promo.active ? promo.subscribe.map(function (f) { return 1 - f; }) : []; 1304 var specialSaleSubscriptionDiscount = 0; 1305 var specialSaleSubscriptionSavingsLabel = ''; //Sale Messaging for subscription 1306 var specialSaleSavingsLabel = []; //Sale Messaging for subscription 1307 1308 // Tier index (0-based) for the currently selected total quantity, c
1308apped at 3. 1309 function promoTierIndex() { 1310 return Math.min(Math.max(selectedQuantity * quantityInput, 1), 3) - 1; 1311 } 1312 1313 // Robustly read a price out of an element, whatever the markup variant. 1314 // .m-price-main may contain the amount directly, or nested in <del>/<ins> 1315 // when a display discount (e.g. "40% OFF" sku badge) is active â the first 1316 // .amount inside is always the original/base price. 1317 function readPrice(selector) { 1318 var el = $(selector).first(); 1319 if (!el.length) { return 0; } 1320 var v = parseFloat(el.text().replace(/[^0-9.]/g, '')); 1321 return isNaN(v) ? 0 : v; 1322 } 1323 1324 // Update the live "X% off" badge next to Quantity for the selected tier. 1325 function updateTierBadge() { 1326 if (!promo.active) { return; } 1327 var arr = isSubscription ? promo.subscribe : promo.onetime; 1328 var pct = Math.round((arr[promoTierIndex()] || 0) * 100); 1329 $('.js-tier-badge').text(pct + '% off').show(); 1330 } 1331 1332 // Live main price (top of summary) for the promo. The original 1333 // .m-price-main / .m-price-offer elements stay in the DOM untouched â 1334 // other scripts read prices out of them â but are hidden via CSS while 1335 // the promo row (struck base total, discounted total, % badge) shows. 1336 var promoBasePrice = 0; 1337 function updateMainPromoPrice() { 1338 if (!promo.active) { return; } 1339 var wrap = $('.summary .m-price'); 1340 if (!wrap.length) { return; } 1341 if (!promoBasePrice) { 1342 promoBasePrice = readPrice('.summary .m-price .m-price-main .amount bdi'); 1343 if (!promoBasePrice) { return; } 1344 } 1345 var totalQty = Math.max(selectedQuantity * quantityInput, 1); 1346 var arr = isSubscription ? promo.subscribe : promo.onetime; 1347 var frac = arr[Math.min(totalQty, 3) - 1] || 0; 1348 var baseTotal = promoBasePrice * totalQty; 1349 var discTotal = baseTotal * (1 - frac); 1350 1351 if (!wrap.find('.js-promo-price').length) { 1352 wrap.addClass('promo-price-active'); 1353 wrap.append('<span class="js-promo-strike"></span><span class="js-promo-price"></span><span class="js-promo-pct"></span>'); 1354 } 1355 wrap.find('.js-promo-strike').text('$' + baseTotal.toFixed(2)); 1356 wrap.find('.js-promo-price').text('$' + discTotal.toFixed(2)); 1357 wrap.find('.js-promo-pct').text(Math.round(frac * 100) + '% off'); 1358 } 1359 1360 // Function to update prices based on quantity and purchase type 1361 function updatePrices() { 1362 var basePrice = readPrice('.summary .m-price .m-price-main .amount bdi'); 1363 var subscriptionPrice = readPrice('.summary .m-price .m-price-offer .amount bdi'); 1364 if (!basePrice) { updateTierBadge(); return; } 1365 1366 var index = 0; 1367 $('.quantity-box').each(function() { 1368 var quantity = $(this).data('quantity'); 1369 var numTubs = $(this).data('num_tubs'); 1370 var verboseName = $(this).data('verbose_name'); 1371 var verboseNamePlural = $(this).data('verbose_name_plural'); 1372 var totalPrice, pricePerTub, savings; 1373 1374 if (isSubscription) { 1375 if (promo.active && specialSaleSubscriptionPctOff[index]) { 1376 totalPrice = (basePrice * specialSaleSubscriptionPctOff[index]) * quantity; 1377 pricePerTub = totalPrice / quantity; 1378 } else if (specialSaleSubscriptionDiscount) { 1379 totalPrice = (basePrice * specialSaleSubscriptionDiscount) * quantity; 1380 pricePerTub = totalPrice / quantity; 1381 } else { 1382 totalPrice = subscriptionPrice * quantity; 1383 pricePerTub = subscriptionPrice; 1384 } 1385 1386 savings = (basePrice * quantity) - totalPrice; 1387 } else { 1388 if (quantity === 1) { 1389 totalPrice = basePrice; 1390 if(specialSaleQuantityPctOff[index]) { 1391 totalPrice = basePrice * specialSaleQuantityPctOff[index]; 1392 } 1393 pricePerTub = totalPrice; 1394 savings = 0; 1395 } else {
1396 if(specialSaleQuantityPctOff[index]) { 1397 totalPrice = (basePrice * specialSaleQuantityPctOff[index]) * quantity; 1398 } else { 1399 totalPrice = (basePrice * subscriptionDiscount) * quantity; 1400 } 1401 pricePerTub = totalPrice / quantity; 1402 savings = (basePrice * quantity) - totalPrice; 1403 } 1404 } 1405 1406 $(this).find('.box-price-per-tub').text('$' + totalPrice.toFixed(2) + ' Total'); 1407 if (numTubs > 1) { 1408 $(this).find('.box-price').html('$' + (pricePerTub / numTubs).toFixed(2) + '<small>/' + verboseName + '</small>'); 1409 } else { 1410 $(this).find('.box-price').html('$' + pricePerTub.toFixed(2) + '<small>/' + verboseName + '</small>'); 1411 } 1412 1413 // Update savings label 1414 if(isSubscription && specialSaleSubscriptionSavingsLabel) { 1415 $(this).find('.savings-label').text(specialSaleSubscriptionSavingsLabel).show(); 1416 } else if (!isSubscription && specialSaleSavingsLabel[index]) { 1417 $(this).find('.savings-label').text(specialSaleSavingsLabel[index]).show(); 1418 } else { 1419 1420 if (savings > 0) { 1421 $(this).find('.savings-label').text('Save $' + savings.toFixed(2)).show(); 1422 } else { 1423 $(this).find('.savings-label').hide(); 1424 } 1425 } 1426 1427 // Per-box "X% off" label (promo only). 1428 if (promo.active) { 1429 var boxFraction = isSubscription ? promo.subscribe[index] : promo.onetime[index]; 1430 if (boxFraction) { 1431 $(this).find('.js-box-pct').text(Math.round(boxFraction * 100) + '% off').show(); 1432 } 1433 } 1434 index++; 1435 }); 1436 1437 updateTierBadge(); 1438 updateMainPromoPrice(); 1439 } 1440 1441 // Initialize prices on page load 1442 updatePrices(); 1443 1444 // Initialize stepper display next to Add to bag with current qty 1445 if ($('.purchase-actions .stepper > div').length) { 1446 var currentQty = parseInt($('input.qty').val() || 1); 1447 $('.purchase-actions .stepper > div').text(currentQty); 1448 } 1449 1450 // Handle purchase type selection 1451 $('input[name="purchase-type"]').on('change', function() { 1452 isSubscription = ($(this).val() === 'subscribe'); 1453 updatePrices(); 1454 }); 1455 1456 // Handle quantity box selection 1457 $('.quantity-box').on('click', function() { 1458 $('.quantity-box').removeClass('active'); 1459 $(this).addClass('active'); 1460 selectedQuantity = parseInt($(this).data('quantity')); 1461 $('input[name="selected-quantity"]').val(selectedQuantity); 1462 // Auto-match delivery frequency to quantity (1 -> 30d, 2 -> 60d, 3 -> 90d). 1463 if (promo.active && promo.syncFrequency) { 1464 $('#custom-subscription-period').val(Math.min(selectedQuantity, 3)).trigger('change'); 1465 } 1466 updatePrices(); 1467 }); 1468 1469 // Handle stepper increase 1470 $('body').on('click', '.stepper-increase', function (e) { 1471 e.preventDefault(); 1472 var el = $(this).closest('.stepper'); 1473 var qtyDisplay = el.find('> div'); 1474 quantityInput = parseInt(qtyDisplay.text()) + 1; 1475 qtyDisplay.text(quantityInput); 1476 // Update quantity input 1477 $('input.qty').val(quantityInput).trigger('change'); 1478 updatePrices(); 1479 }); 1480 1481 // Handle stepper decrease 1482 $('body').on('click', '.stepper-decrease', function (e) { 1483 e.preventDefault(); 1484 var el = $(this).closest('.stepper'); 1485 var qtyDisplay = el.find('> div'); 1486 quantityInput = parseInt(qtyDisplay.text()); 1487 if (quantityInput > 1) { 1488 quantityInput -= 1; 1489 qtyDisplay.text(quantityInput); 1490 // Update quantity input 1491 $('input.qty').val(quantityInput).trigger('change'); 1492 updatePrices(); 1493 } 1494 }); 1495 1496 // Keep stepper display in sync if qty input changes elsewhere 1497 $('body').on('change keyup', 'input.qty', function() { 1498 var val = parseInt($(this).val() || 1);
1499 $('.purchase-actions .stepper > div').text(val); 1500 quantityInput = val; 1501 }); 1502 1503 // Before form submission, compute total quantity 1504 $('form.cart').on('submit', function(e) { 1505 var totalQuantity = selectedQuantity * quantityInput; 1506 $('input.qty').val(totalQuantity); 1507 }); 1508 1509 // Auto-select Subscribe & save on load when the promo is running. 1510 if (promo.active && promo.defaultSubscribe && $('#purchase-type-subscribe').length) { 1511 $('.purchase-button').removeClass('active'); 1512 $('.purchase-button[data-purchase-type="subscribe"]').addClass('active'); 1513 $('.m-subscribe-select').show(); 1514 $('#purchase-type-subscribe').prop('checked', true).trigger('change'); 1515 isSubscription = true; 1516 if (promo.syncFrequency) { 1517 $('#custom-subscription-period').val(Math.min(selectedQuantity, 3)).trigger('change'); 1518 } 1519 updatePrices(); 1520 } 1521});
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.