if (!window.Giftify) { window.Giftify = { checkoutButton: false, validationErrors: {}, init: function() { this.reset(); this.insertStyle(); this.initiateButton(); }, reset: function() { var xhr = new XMLHttpRequest(); xhr.open('POST', window.Shopify.routes.root + 'cart/update.js'); xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); xhr.send(JSON.stringify({ attributes: { 'Giftify • To': '', 'Giftify • From': '', 'Giftify • Message': '' } })); }, insertStyle: function() { var head = document.head || document.getElementsByTagName('head')[0], style = document.createElement('style'); style.type = 'text/css'; var validationCSS = '.giftify-popup__field--error input, .giftify-popup__field--error textarea { border-color: #dc3545; } .giftify-popup__error { color: #dc3545; font-size: 12px; margin-top: 4px; display: none; } .giftify-popup__field--error .giftify-popup__error { display: block; }'; style.appendChild(document.createTextNode("\n .giftify-wrapper { width: 100% }\n .giftify-button { \n margin: 5px 0px 5px 0px; \n display: inline-block;\n transition: all .2s ease;\n }\n a.giftify-button,\n .giftify-button[role=\"button\"] {\n text-decoration: none;\n }\n /* Mini cart specific alignment - scoped to cart drawer/mini cart only */\n .cart-drawer .giftify-button-container,\n .mini-cart .giftify-button-container,\n [class*=\"cart-drawer\"] .giftify-button-container,\n [class*=\"mini-cart\"] .giftify-button-container {\n width: 100%;\n display: block;\n margin-bottom: 10px;\n }\n .cart-drawer .giftify-actions-container,\n .mini-cart .giftify-actions-container,\n [class*=\"cart-drawer\"] .giftify-actions-container,\n [class*=\"mini-cart\"] .giftify-actions-container {\n width: 100%;\n display: flex;\n gap: 10px;\n }\n .cart-drawer .giftify-actions-container > *,\n .mini-cart .giftify-actions-container > *,\n [class*=\"cart-drawer\"] .giftify-actions-container > *,\n [class*=\"mini-cart\"] .giftify-actions-container > * {\n flex: 1;\n }\n .cart-drawer .giftify-button-container .giftify-button,\n .mini-cart .giftify-button-container .giftify-button,\n [class*=\"cart-drawer\"] .giftify-button-container .giftify-button,\n [class*=\"mini-cart\"] .giftify-button-container .giftify-button {\n display: block;\n width: 100%;\n box-sizing: border-box;\n }\n .giftify-button span {\n background: #af60bc;\n color: #ffffff;\n border-radius: 0px;\n border: 2px solid #af60bc;\n padding: 10px 20px 10px 20px; \n display: flex;\n white-space: nowrap;\n transition: all .2s ease;\n align-items: center;\n justify-content: center;\n }\n .giftify-button svg { \n fill: #ffffff;\n display: inline-block; \n margin-right: 5px;\n width: 24px;\n height: 24px;\n transition: all .2s ease;\n }\n .giftify-button:hover span {\n background: #384963;\n color: #ffffff;\n border-color: #384963;\n }\n .giftify-button:hover svg {\n fill: #ffffff;\n }\n .giftify-popup {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 999;\n opacity: 0;\n visibility: hidden;\n pointer-events: none;\n transition: all .5s ease;\n }\n .giftify-popup.giftify-popup--loading {\n pointer-events: none;\n }\n .giftify-popup.giftify-popup--active {\n opacity: 1;\n visibility: visible;\n pointer-events: all;\n }\n .giftify-popup.giftify-popup--active .giftify-popup__inside {\n transition-delay: .3s;\n opacity: 1;\n margin-top: 0;\n }\n .giftify-popup .giftify-popup__bg {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0,0,0,.6);\n z-index: 1;\n display: block;\n }\n .giftify-popup__inside {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: #fff;\n width: 90%;\n max-width: 920px;\n display: flex;\n align-items: stretch;\n z-index: 2;\n transition: margin .5s Cubic-bezier(0.3, 0, 0.3, 1), opacity .3s ease;\n margin-top: 50px;\n opacity: 0;\n }\n .giftify-popup__close {\n position: absolute;\n top: 0;\n right: 0;\n width: 48px;\n height: 48px;\n z-index: 3;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .giftify-popup__close svg {\n fill: #191919;\n width: 24px;\n }\n .giftify-popup__grid {\n display: flex;\n width: 100%;\n flex-wrap: nowrap;\n }\n .giftify-popup .giftify-popup__right {\n width: 50%;\n display: block;\n background-size: cover;\n background-position: center;\n background-repeat: no-repeat;\n }\n .giftify-popup__left {\n width: 50%;\n padding: 50px 50px 75px;\n position: relative;\n }\n .giftify-popup__header {\n text-align: center;\n }\n .giftify-popup__header img {\n max-height: 50px;\n }\n .giftify-popup__title {\n color: #191919;\n font-size: 32px;\n margin: 20px 0;\n }\n .giftify-popup__steps + div {\n font-size: 13px;\n position: absolute;\n left: 0;\n width: 100%;\n bottom: 10px;\n text-align: center;\n }\n .giftify-popup__steps + div a {\n color: #191919;\n border-bottom: 1px solid transparent;\n }\n .giftify-popup__steps + div a:hover {\n border-bottom-color: #191919;\n }\n .giftify-popup__step {\n display: none;\n }\n .giftify-popup__step--active {\n display: block;\n }\n .giftify-popup__action {\n margin-top: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .giftify-popup .giftify-popup__button { \n margin: 5px; \n display: inline-block;\n transition: all .2s ease;\n padding: 0;\n border: 0;\n cursor: pointer;\n }\n .giftify-popup button.giftify-popup__button,\n .giftify-popup .giftify-popup__button[type=\"button\"],\n .giftify-popup .giftify-popup__button[type=\"submit\"] {\n border-radius: 0;\n background: none;\n }\n .giftify-popup__button span {\n border-radius: 0px;\n padding: 10px 20px 10px 20px; \n display: flex;\n white-space: nowrap;\n transition: all .2s ease;\n position: relative;\n }\n .giftify-popup__next span {\n background: #af60bc;\n color: #ffffff;\n border: 2px solid #af60bc;\n position: relative;\n }\n .giftify-popup__next:hover span {\n background: #384963;\n color: #ffffff;\n border-color: #384963;\n }\n .giftify-popup__prev span {\n background: #cbc8c8;\n color: #ffffff;\n border: 2px solid #d2d2d2;\n }\n .giftify-popup__prev:hover span {\n background: #d2d2d2;\n color: #191919;\n border-color: #d2d2d2;\n }\n .giftify-popup__next span::after {\n content: \"\";\n position: absolute;\n top: 50%;\n left: 50%;\n width: 20px;\n height: 20px;\n border: 3px solid #ffffff;\n border-top: 3px solid transparent!important;\n border-radius: 50%;\n margin-left: -10px;\n margin-top: -10px;\n opacity: 0;\n -webkit-animation: giftify_spin .7s linear infinite;\n animation: giftify_spin .7s linear infinite;\n }\n @-webkit-keyframes giftify_spin { \n 100% { -webkit-transform: rotate(360deg); } \n }\n @keyframes giftify_spin { \n 100% { \n -webkit-transform: rotate(360deg); \n transform:rotate(360deg); \n } \n }\n .giftify-popup__step ol {\n counter-reset: giftify;\n list-style: none;\n padding: 0;\n }\n .giftify-popup__step li {\n color: #191919;\n font-size: 16px;\n counter-increment: giftify;\n position: relative;\n padding-left: 30px;\n display: block;\n }\n .giftify-popup__step li + li {\n margin-top: 5px;\n }\n .giftify-popup__step li::before {\n content: counter(giftify)\".\";\n font-weight: bold;\n top: 0;\n left: 0;\n position: absolute;\n }\n .giftify-popup__label { \n font-weight: bold;\n text-align: center;\n }\n .giftify-popup__field {\n margin: 5px 0 10px;\n }\n .giftify-popup__grid > .giftify-popup__field {\n width: 50%;\n padding-right: 2px;\n }\n .giftify-popup__grid > .giftify-popup__field + .giftify-popup__field {\n padding-left: 2px;\n }\n .giftify-popup__field > * {\n width: 100%;\n }\n .giftify-popup__field input,\n .giftify-popup__field textarea {\n padding: 10px;\n border: 1px solid #d2d2d2;\n }\n .giftify-popup--loading .giftify-popup__next span {\n color: transparent!important;\n }\n .giftify-popup--loading .giftify-popup__next span::after {\n opacity: 1;\n }\n @media (max-width: 768px) {\n .giftify-popup .giftify-popup__inside {\n width: 95%;\n max-width: 95%;\n max-height: 90vh;\n overflow-y: auto;\n top: 50%;\n transform: translate(-50%, -50%);\n -webkit-overflow-scrolling: touch;\n }\n .giftify-popup .giftify-popup__grid {\n flex-direction: column;\n display: flex;\n }\n .giftify-popup .giftify-popup__left {\n width: 100%;\n padding: 30px 20px 50px;\n flex: 1 1 auto;\n }\n .giftify-popup .giftify-popup__right {\n width: 100%;\n min-height: 200px;\n order: -1;\n flex: 0 0 auto;\n }\n .giftify-popup__title {\n font-size: 24px;\n margin: 15px 0;\n line-height: 1.3;\n }\n .giftify-popup__step li {\n font-size: 14px;\n line-height: 1.5;\n }\n .giftify-popup .giftify-popup__grid > .giftify-popup__field {\n width: 100%;\n padding-right: 0;\n padding-left: 0;\n }\n .giftify-popup .giftify-popup__grid > .giftify-popup__field + .giftify-popup__field {\n padding-left: 0;\n margin-top: 10px;\n }\n .giftify-popup .giftify-popup__action {\n flex-direction: column;\n gap: 10px;\n }\n .giftify-popup .giftify-popup__button {\n width: 100%;\n margin: 0;\n }\n .giftify-popup__button span {\n width: 100%;\n justify-content: center;\n }\n .giftify-popup__close {\n width: 44px;\n height: 44px;\n min-width: 44px;\n min-height: 44px;\n }\n .giftify-popup__close svg {\n width: 20px;\n }\n }\n @media (max-width: 480px) {\n .giftify-popup .giftify-popup__inside {\n width: 100%;\n max-width: 100%;\n max-height: calc(100vh - env(safe-area-inset-top) - env(safe-area-inset-bottom));\n border-radius: 0;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n .giftify-popup .giftify-popup__left {\n padding: 25px 20px 50px;\n padding-top: max(25px, env(safe-area-inset-top));\n padding-bottom: max(50px, env(safe-area-inset-bottom));\n padding-left: max(20px, env(safe-area-inset-left));\n padding-right: max(20px, env(safe-area-inset-right));\n }\n .giftify-popup .giftify-popup__right {\n min-height: 180px;\n max-height: 40vh;\n width: 100%;\n }\n .giftify-popup__title {\n font-size: 22px;\n margin: 12px 0;\n line-height: 1.3;\n }\n .giftify-popup__step li {\n font-size: 14px;\n padding-left: 28px;\n line-height: 1.6;\n margin-bottom: 8px;\n }\n .giftify-popup__step li + li {\n margin-top: 8px;\n }\n .giftify-popup__field input,\n .giftify-popup__field textarea {\n padding: 12px;\n font-size: 16px;\n -webkit-appearance: none;\n border-radius: 4px;\n }\n .giftify-popup .giftify-popup__button {\n min-height: 44px;\n width: 100%;\n }\n .giftify-popup .giftify-popup__button span {\n min-height: 44px;\n width: 100%;\n padding-top: 12px;\n padding-bottom: 12px;\n }\n .giftify-popup .giftify-popup__close {\n top: max(10px, env(safe-area-inset-top));\n right: max(10px, env(safe-area-inset-right));\n width: 44px;\n height: 44px;\n }\n .giftify-popup__header {\n margin-bottom: 20px;\n }\n .giftify-popup__header img {\n max-height: 40px;\n }\n .giftify-popup__label {\n margin-top: 15px;\n margin-bottom: 8px;\n font-size: 14px;\n }\n .giftify-popup__action {\n margin-top: 25px;\n gap: 12px;\n }\n }\n @media (max-width: 390px) {\n .giftify-popup .giftify-popup__left {\n padding: 20px 18px 45px;\n }\n .giftify-popup .giftify-popup__title {\n font-size: 20px;\n margin: 10px 0;\n }\n .giftify-popup .giftify-popup__step li {\n font-size: 13px;\n padding-left: 26px;\n }\n .giftify-popup .giftify-popup__right {\n min-height: 160px;\n max-height: 35vh;\n width: 100%;\n }\n .giftify-popup .giftify-popup__grid {\n flex-direction: column;\n }\n }\n " + validationCSS)); head.appendChild(style); }, validateEmail: function(email) { const trimmedEmail = email.trim(); const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/; if (!emailRegex.test(trimmedEmail)) { return false; } if (trimmedEmail.endsWith('.')) { return false; } const parts = trimmedEmail.split('@'); if (parts.length !== 2) { return false; } const domain = parts[1]; const domainParts = domain.split('.'); if (domainParts.length < 2) { return false; } const tld = domainParts[domainParts.length - 1]; if (tld.length < 2 || !/^[a-zA-Z]+$/.test(tld)) { return false; } if (domainParts.some(part => part.length === 0)) { return false; } return true; }, validateField: function(field) { const fieldWrapper = field.closest('.giftify-popup__field'); const fieldName = field.name; const fieldValue = field.value.trim(); let isValid = true; let errorMessage = ''; fieldWrapper.classList.remove('giftify-popup__field--error'); this.validationErrors[fieldName] = null; if (!fieldValue && field.hasAttribute('required')) { isValid = false; errorMessage = 'This field is required'; } else if (field.type === 'email' && fieldValue && !this.validateEmail(fieldValue)) { isValid = false; errorMessage = 'Please enter a valid email address'; } if (!isValid) { fieldWrapper.classList.add('giftify-popup__field--error'); this.validationErrors[fieldName] = errorMessage; this.showFieldError(fieldWrapper, errorMessage); } else { this.hideFieldError(fieldWrapper); } return isValid; }, showFieldError: function(fieldWrapper, message) { let errorEl = fieldWrapper.querySelector('.giftify-popup__error'); if (!errorEl) { errorEl = document.createElement('div'); errorEl.className = 'giftify-popup__error'; fieldWrapper.appendChild(errorEl); } errorEl.textContent = message; }, hideFieldError: function(fieldWrapper) { const errorEl = fieldWrapper.querySelector('.giftify-popup__error'); if (errorEl) { errorEl.remove(); } }, validateForm: function(form) { const fields = form.querySelectorAll('input[required], input[type="email"], textarea[required]'); let isFormValid = true; fields.forEach(field => { if (!this.validateField(field)) { isFormValid = false; } }); return isFormValid; }, createWrappersForCheckoutButtons: function(checkoutButtons) { var self = this; if (!checkoutButtons || checkoutButtons.length === 0) return false; self.checkoutButton = checkoutButtons[0]; var needsRender = false; checkoutButtons.forEach(function(checkoutButton) { var existingWrapper = checkoutButton.parentNode.querySelector('.giftify-wrapper'); if (!existingWrapper) { var el = document.createElement('div'); el.classList.add('giftify-wrapper'); checkoutButton.parentNode.insertBefore(el, checkoutButton); needsRender = true; } }); return needsRender; }, checkWrappersForButtons: function() { var wrappers = document.querySelectorAll('.giftify-wrapper'); return Array.from(wrappers).some(function(wrapper) { return !wrapper.querySelector('a.giftify-button'); }); }, wrapActionButtons: function(wrapper) { var self = this; var parent = wrapper.parentNode; if (!parent) return; // Check if already wrapped if (parent.querySelector('.giftify-actions-container')) return; // Function to find and wrap buttons function findAndWrapButtons() { // Find checkout button var checkoutButton = window.Giftify.checkoutButton || parent.querySelector('[name="checkout"]'); // Find chat button - simple search var chatButton = parent.querySelector('[class*="chat" i], [id*="chat" i], [aria-label*="chat" i]'); if (!chatButton) { var allBtns = parent.querySelectorAll('button, a'); for (var j = 0; j < allBtns.length; j++) { var btn = allBtns[j]; var text = (btn.textContent || '').toLowerCase(); if (text.indexOf('chat') !== -1 && btn !== checkoutButton && !btn.closest('.giftify-wrapper')) { chatButton = btn; break; } } } // Only proceed if we have buttons to wrap if (!checkoutButton && !chatButton) return false; // Check if actions container already exists var actionsContainer = parent.querySelector('.giftify-actions-container'); if (actionsContainer) return true; // Create actions container actionsContainer = document.createElement('div'); actionsContainer.classList.add('giftify-actions-container'); if (wrapper.nextSibling) { parent.insertBefore(actionsContainer, wrapper.nextSibling); } else { parent.appendChild(actionsContainer); } // Move buttons to container if (checkoutButton && checkoutButton.parentNode === parent) { actionsContainer.appendChild(checkoutButton); } if (chatButton && chatButton !== checkoutButton && chatButton.parentNode === parent) { actionsContainer.appendChild(chatButton); } return true; } // Try immediately first if (findAndWrapButtons()) { return; // Successfully wrapped, no need for observer } // Use MutationObserver to watch for buttons appearing var observer = new MutationObserver(function(mutations) { if (findAndWrapButtons()) { observer.disconnect(); // Stop observing once buttons are wrapped } }); // Start observing the parent for child additions observer.observe(parent, { childList: true, subtree: true }); // Also check periodically as fallback (with timeout to prevent infinite watching) var checkCount = 0; var maxChecks = 20; // 20 checks = 10 seconds max var checkInterval = setInterval(function() { checkCount++; if (findAndWrapButtons() || checkCount >= maxChecks) { clearInterval(checkInterval); observer.disconnect(); } }, 500); }, initiateButton: function() { var self = this; // Function to try initializing the button function tryInitiateButton() { var wrappers = document.querySelectorAll('.giftify-wrapper'), checkoutButtons = document.querySelectorAll('[name="checkout"]'); if (wrappers.length) { self.renderButton(); return true; } else if (checkoutButtons.length) { if (self.createWrappersForCheckoutButtons(checkoutButtons)) { self.renderButton(); return true; } } return false; } // Try immediately if DOM is ready if (document.readyState === 'loading') { // Wait for DOM to be ready document.addEventListener('DOMContentLoaded', function() { if (!tryInitiateButton()) { // If button still not found, set up observer self.observeForCheckoutButton(); } }); } else { // DOM is already ready, try immediately if (!tryInitiateButton()) { // If button still not found, set up observer this.observeForCheckoutButton(); } } }, observeForCheckoutButton: function() { var self = this; // Wait for body to exist if it doesn't yet if (!document.body) { var bodyCheck = setInterval(function() { if (document.body) { clearInterval(bodyCheck); self.observeForCheckoutButton(); } }, 100); return; } // Variables for cleanup - defined here so both observer and interval can access them var checkInterval = null; var observer = null; // Function to handle checkout button found function handleCheckoutButtonsFound() { var checkoutButtons = document.querySelectorAll('[name="checkout"]'); if (checkoutButtons.length) { // Button found! Initialize it var needsRender = self.createWrappersForCheckoutButtons(checkoutButtons); if (needsRender) { self.renderButton(); cleanup(); // Stop both observer and interval return true; } else { // Check if wrappers exist but don't have buttons if (self.checkWrappersForButtons()) { self.renderButton(); cleanup(); // Stop both observer and interval return true; } } } return false; } // Use MutationObserver to watch for checkout buttons appearing observer = new MutationObserver(function(mutations) { handleCheckoutButtonsFound(); }); // Start observing the document body for changes observer.observe(document.body, { childList: true, subtree: true }); // Also check periodically as a fallback (in case observer misses it) checkInterval = setInterval(function() { handleCheckoutButtonsFound(); }, 500); // Create cleanup function using shared helper var cleanup = self.createObserverCleanup(observer, checkInterval); // Stop checking after 10 seconds to avoid infinite polling setTimeout(function() { cleanup(); // Stop both observer and interval }, 10000); }, renderButton: function(wrappers = null) { if (!wrappers) { wrappers = document.querySelectorAll('.giftify-wrapper'); } if (wrappers && wrappers.length) { // Check if button already exists globally to prevent duplication var existingButton = document.querySelector('a.giftify-button'); if (existingButton) return; // Button already exists, don't create duplicates // Only create button in the first wrapper that doesn't have one var firstWrapper = null; for (var i = 0; i < wrappers.length; i++) { if (!wrappers[i].querySelector('a.giftify-button')) { firstWrapper = wrappers[i]; break; } } if (firstWrapper) { // Create container for gift button var giftContainer = document.createElement('div'); giftContainer.classList.add('giftify-button-container'); var buttonEl = document.createElement('a'); buttonEl.href = '#'; buttonEl.setAttribute('role', 'button'); buttonEl.setAttribute('tabindex', '0'); var iconStrValue = ""; var buttonTextValue = "Is this a gift?"; buttonEl.setAttribute('aria-label', buttonTextValue); var buttonContent = '' + iconStrValue + ' ' + buttonTextValue + ''; buttonEl.innerHTML = buttonContent; buttonEl.classList.add('giftify-button'); buttonEl.addEventListener('click', window.Giftify.openPopup); buttonEl.addEventListener('keydown', function(e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); window.Giftify.openPopup(e); } }); giftContainer.appendChild(buttonEl); firstWrapper.appendChild(giftContainer); // Wrap checkout and chat buttons in actions container using MutationObserver this.wrapActionButtons(firstWrapper); } } if (!document.querySelector('.giftify-popup')) { var saved = { to: { name: '', email: '' }, from: { name: '', email: '' }, message: '' }; if (localStorage.getItem('giftify')) { saved = JSON.parse(localStorage.getItem('giftify')); } var popupHTML = "\n
\n
\n \n \t
\n \t\t
\n \t\t\t
\n \t\t\t\t\n \t\t\t\t
Sending a gift is easy!
\n \t\t\t
\n \t\t\t
\n \t\t\t\t
\n \t\t\t\t\t
    \n
  1. Add your recipient’s information, including email.
  2. \n
  3. Complete your purchase using the recipient’s shipping address.
  4. \n
  5. You'll receive an email confirming your order.
  6. \n
  7. We'll send your recipient an email with your message and let them know your gift is on its way!
  8. \n \t\t\t\t\t
\n
\n \n
\n \t\t\t\t
\n
\n
\n
To
\n
\n
\n \n
\n
\n \n
\n
\n
From
\n
\n
\n \n
\n
\n \n
\n
\n
Message
\n
\n \n
\n
\n \n \n
\n
\n
\n \t\t\t
\n
Powered by Giftify
\n \t\t
\n \t\t
\n \t
\n
\n "; popupHTML = popupHTML.replace('{saved.to.name}', saved.to.name); popupHTML = popupHTML.replace('{saved.to.email}', saved.to.email); popupHTML = popupHTML.replace('{saved.from.name}', saved.from.name); popupHTML = popupHTML.replace('{saved.from.email}', saved.from.email); popupHTML = popupHTML.replace('{saved.message}', saved.message); var popupEl = document.createElement('div'); popupEl.classList.add('giftify-popup'); popupEl.innerHTML = popupHTML; document.body.appendChild(popupEl); this.initiatePopupListeners(); } }, initiatePopupListeners: function() { document.querySelector('.giftify-popup__bg').addEventListener('click', this.closePopup); document.querySelector('.giftify-popup__close').addEventListener('click', this.closePopup); document.querySelector('.giftify-popup__step[data-step="1"] .giftify-popup__next').addEventListener('click', this.buttonNext); document.querySelector('.giftify-popup__step[data-step="2"] .giftify-popup__prev').addEventListener('click', this.buttonPrev); document.querySelector('.giftify-popup__step[data-step="2"] form').addEventListener('submit', this.submitGift); const form = document.querySelector('.giftify-popup__step[data-step="2"] form'); const fields = form.querySelectorAll('input[required], input[type="email"], textarea[required]'); fields.forEach(field => { field.addEventListener('blur', () => { this.validateField(field); }); field.addEventListener('input', () => { const fieldWrapper = field.closest('.giftify-popup__field'); if (fieldWrapper.classList.contains('giftify-popup__field--error')) { fieldWrapper.classList.remove('giftify-popup__field--error'); this.hideFieldError(fieldWrapper); this.validationErrors[field.name] = null; } }); }); }, openPopup: function(e) { e.preventDefault(); var popup = document.querySelector('.giftify-popup'); if (popup) { popup.classList.add('giftify-popup--active'); } }, closePopup: function(e) { e.preventDefault(); var popup = document.querySelector('.giftify-popup'); if (popup) { popup.classList.remove('giftify-popup--active'); window.Giftify.validationErrors = {}; popup.querySelectorAll('.giftify-popup__field--error').forEach(field => { field.classList.remove('giftify-popup__field--error'); }); popup.querySelectorAll('.giftify-popup__error').forEach(error => { error.remove(); }); } }, buttonNext: function(e) { e.preventDefault(); var step = document.querySelector('.giftify-popup__step[data-step="1"]'); step.classList.remove('giftify-popup__step--active'); step.nextElementSibling.classList.add('giftify-popup__step--active'); }, buttonPrev: function(e) { e.preventDefault(); var step = document.querySelector('.giftify-popup__step[data-step="2"]'); step.classList.remove('giftify-popup__step--active'); step.previousElementSibling.classList.add('giftify-popup__step--active'); }, submitGift: function(e) { e.preventDefault(); var form = e.target; if (!window.Giftify.validateForm(form)) { const firstError = form.querySelector('.giftify-popup__field--error input, .giftify-popup__field--error textarea'); if (firstError) { firstError.focus(); } return; } var attrs = { to: { name: form.rname.value.trim(), email: form.remail.value.trim() }, from: { name: form.yname.value.trim(), email: form.yemail.value.trim() }, message: form.ymessage.value.trim() }; localStorage.setItem('giftify', JSON.stringify(attrs)); document.querySelector('.giftify-popup').classList.add('giftify-popup--loading'); var xhr = new XMLHttpRequest(); xhr.open('POST', window.Shopify.routes.root + 'cart/update.js'); xhr.onload = function() { if (window.Giftify.checkoutButton) { window.Giftify.checkoutButton.click(); } else { location.href = '/checkout'; } }; xhr.onerror = function() { document.querySelector('.giftify-popup').classList.remove('giftify-popup--loading'); alert('An error occurred. Please try again.'); }; xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); xhr.send(JSON.stringify({ attributes: { 'Giftify • To': attrs.to.name + ' (' + attrs.to.email + ')', 'Giftify • From': attrs.from.name + ' (' + attrs.from.email + ')', 'Giftify • Message': (attrs.message ? attrs.message : '-') } })); } }; // Helper function to wait for DOM ready function initWhenReady(callback) { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', callback); } else { callback(); } } // Wait for DOM to be ready before initializing initWhenReady(function() { window.Giftify.init(); }); }