/** * Maple Carts - Frontend cart tracking. */ (function($) { 'use strict'; var MapleCarts = { saveTimeout: null, lastSavedData: '', init: function() { this.bindEvents(); this.showGdprNotice(); // Initial save after page load. setTimeout(function() { MapleCarts.saveCart(); }, 2000); }, bindEvents: function() { // Classic checkout fields. $(document).on('change keyup', '#billing_email', this.debounce(this.saveCart, 500)); $(document).on('change keyup', '#billing_first_name, #billing_last_name, #billing_phone', this.debounce(this.saveCart, 1000)); $(document).on('change', '#billing_address_1, #billing_city, #billing_state, #billing_postcode, #billing_country', this.debounce(this.saveCart, 1000)); // WooCommerce Blocks checkout. $(document).on('change keyup', '[id^="email"]', this.debounce(this.saveCart, 500)); $(document).on('change keyup', 'input[autocomplete="email"]', this.debounce(this.saveCart, 500)); // Save on blur for email field. $(document).on('blur', '#billing_email, [id^="email"], input[autocomplete="email"]', function() { MapleCarts.saveCart(); }); // Cart updates. $(document.body).on('updated_cart_totals', this.saveCart); $(document.body).on('updated_checkout', this.saveCart); // Consent checkbox - save when checked. $(document).on('change', '#maple_carts_consent', function() { if ($(this).is(':checked')) { MapleCarts.saveCart(); } }); }, showGdprNotice: function() { if (mapleCartsData.gdprNotice && mapleCartsData.gdprNotice.length > 0) { var notice = $('
' + mapleCartsData.gdprNotice + '
'); $('.woocommerce-checkout').prepend(notice); } }, getFormData: function() { var data = { session_id: mapleCartsData.sessionId }; // Check for consent checkbox if it exists. var consentCheckbox = $('#maple_carts_consent'); if (consentCheckbox.length > 0 && !consentCheckbox.is(':checked')) { // Consent required but not given - don't save. return null; } data.consent = consentCheckbox.length > 0 ? (consentCheckbox.is(':checked') ? '1' : '0') : '1'; // Get email - try multiple selectors for compatibility. var email = $('#billing_email').val() || $('[id^="email"]').val() || $('input[autocomplete="email"]').val() || $('input[type="email"]').first().val() || ''; data.email = email.trim().toLowerCase(); // Get billing fields. var billingFields = [ 'first_name', 'last_name', 'phone', 'address_1', 'address_2', 'city', 'state', 'postcode', 'country' ]; billingFields.forEach(function(field) { var value = $('#billing_' + field).val(); if (value) { data['billing_' + field] = value; } }); // Try Blocks checkout fields. if (!data.billing_first_name) { data.billing_first_name = $('input[autocomplete="given-name"]').val() || ''; } if (!data.billing_last_name) { data.billing_last_name = $('input[autocomplete="family-name"]').val() || ''; } if (!data.billing_phone) { data.billing_phone = $('input[autocomplete="tel"]').val() || ''; } return data; }, saveCart: function() { var data = MapleCarts.getFormData(); // Don't save if consent not given or data is null. if (!data) { return; } // Don't save without email or session. if (!data.email || !data.session_id) { return; } // Don't save if email is invalid. if (!MapleCarts.isValidEmail(data.email)) { return; } // Don't save if data hasn't changed. var dataHash = JSON.stringify(data); if (dataHash === MapleCarts.lastSavedData) { return; } data.action = 'maple_carts_save'; data.nonce = mapleCartsData.nonce; $.post(mapleCartsData.ajaxUrl, data, function(response) { if (response.success) { MapleCarts.lastSavedData = dataHash; } }); }, isValidEmail: function(email) { var re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return re.test(email); }, debounce: function(func, wait) { return function() { var context = this, args = arguments; clearTimeout(MapleCarts.saveTimeout); MapleCarts.saveTimeout = setTimeout(function() { func.apply(context, args); }, wait); }; } }; $(document).ready(function() { MapleCarts.init(); }); })(jQuery);