// Helper function to detect DOM changes const waitForEl = (selector) => { return new Promise(resolve => { if (document.querySelector(selector)) { return resolve(document.querySelector(selector)); } const observer = new MutationObserver(mutations => { if (document.querySelector(selector)) { observer.disconnect(); resolve(document.querySelector(selector)); } }); // If you get "parameter 1 is not of type 'Node'" error, see https://stackoverflow.com/a/77855838/492336 observer.observe(document.body, { childList: true, subtree: true }); }); } (function($) { $(document).ready(function() { // Global variables let firstLoad = true; const params = new URLSearchParams(document.location.search); // Helper function to clear options and add loading class const fieldAddLoading = (field) => { field.html('') //Clear options for field field.parent().addClass('field-loading').siblings('label').addClass('noclick') //Add loading class to parent element and noclick class to label } // Helper function to remove loading class const fieldRemoveLoading = () => { $('.field-loading').removeClass('field-loading').siblings('label').removeClass('noclick') } // If any fields do not have options then remove tabindex // If any fields have negative tabindex that should not, remove tabindex const tabIndexCheck = () => { let selectsNoOptions = $('select:not(:has(option:not(option[value=""])))') let selectsOptionsNegTabindex = $('select[tabindex="-1"]:has(option:not(option[value=""]))') // If any fields do not have options, then remove tabindex from field and its label if (!!selectsNoOptions.length) { selectsNoOptions.each(function() { let thisID = $(this).attr('id') $(this).attr('tabindex', -1) $(`[for=${thisID}]`).addClass('noclick') }) } // If any fields have negative tabindex that should not, remove tabindex from field and its label if (!!selectsOptionsNegTabindex.length) { selectsOptionsNegTabindex.each(function() { let thisID = $(this).attr('id') $(this).removeAttr('tabindex') $(`[for=${thisID}]`).removeClass('noclick') }) } } // Call above on load tabIndexCheck() // CONTACT - Get City options based on state $('#store_state_select').change(function() { fieldAddLoading($('#store_city_select')) $('#store_select').html(''); //Clear options for Store Location select field $.ajax({ type: 'POST', url: ajax_obj.ajax_url, data: { action: 'get_store_location_cities', state: $(this).val(), _ajax_nonce: ajax_obj.ajax_nonce }, success: function(data) { let options = ''; JSON.parse(data).forEach(function(el) { options += ''; }); $('#store_city_select').html(options); fieldRemoveLoading() tabIndexCheck() } }); }); // CONTACT - Get Store Location options based on city $('#store_city_select').change(function() { fieldAddLoading($('#store_select')) //Add loading to store location field $.ajax({ type: 'POST', url: ajax_obj.ajax_url, data: { action: 'get_store_locations_for_city', city: $(this).val(), state: $('#store_state_select option:selected').val(), _ajax_nonce: ajax_obj.ajax_nonce }, success: function(data) { let options = ''; JSON.parse(data).forEach(function(el) { options += ''; }); $('#store_select').html(options); fieldRemoveLoading() tabIndexCheck() } }); }); // CONTACT - Get Complaint Type options based by category (aka topic) const fieldTopicChange = () => { fieldAddLoading($('#complaint-type')) //Add loading to complaint type field $.ajax({ type: 'GET', url: ajax_obj.ajax_url, data: { action: 'get_compliant_types_for_category', topic: $('#topic option:selected').val(), _ajax_none: ajax_obj.ajax_nonce }, //return the list of compliant types as options. success: function(data) { let options = ''; JSON.parse(data).forEach(function(el) { // If it's first load and the value is same as URL param 'complaint-type' then save as selected option // otherwise load all values into select field options if (!!firstLoad && el === params.get('complaint-type')) { options += ''; firstLoad = false; } else { options += ''; } }); //Add those options from a successful request to the field $('#complaint-type').html(options).trigger('change'); //Add trigger here to make sure JS change event fires (fixes issue with first load autopopulate) fieldRemoveLoading() tabIndexCheck() } }); } // Call above on load and topic field change fieldTopicChange() $('#topic').change(fieldTopicChange); // DSR - Get privacy request types for each state $('#customer-state').change(function() { fieldAddLoading($('#privacy_request_topic')) //Add loading to privacy request topic field $.ajax({ //Create an ajax get request filtered via the selected state. type: 'GET', url: ajax_obj.ajax_url, data: { action: 'get_privacy_requests_for_state', state: $('#customer-state option:selected').val(), _ajax_nonce: ajax_obj.ajax_nonce }, //return the list of privacy request topics as options in the form field. success: function(data) { let options = ''; JSON.parse(data).forEach(function(el) { options += ''; }); //Add options from the successful request to the form field. $('#privacy_request_topic').html(options); fieldRemoveLoading() tabIndexCheck() } }); }); // Display the appropriate confirmation message per CF7 form. $('.wpcf7').on('wpcf7mailsent', function(e) { if ('46158' == event.detail.contactFormId) { $(this).html( '

Thank you for submitting your US Data Subject Privacy request. You will receive a verification email shortly.

\

Please see our FAQs for answers to \ many of our most common questions, or click here to return to the homepage of the Sprouts website.

' ); $(this).addClass('wpcf7-mail-sent-ok'); } else { $(this).html( '

Thank you for your inquiry. We will read it as soon as possible, \ and in most cases, we will email you a reply within the next few days.

\

Please see our FAQs for answers to \ many of our most common questions, or click here to return to the homepage of the Sprouts website.

' ); $(this).addClass('wpcf7-mail-sent-ok'); } }); if (typeof UnataComm === 'function') { let ucomm = new UnataComm(); ucomm.listen('unata-logged-in', function(event) { let userData = event.data.payload; // If user logged in if (userData.authenticated) { let userLoyaltyId = userData.primaryLoyaltyCard.card_number; // Set Loyalty ID hidden field value after element exists waitForEl('#loyalty-id').then((el) => { $(el).val(userLoyaltyId); }) // Request customer info from Sprouts Customer API // **This doesn't seem to work at this time - API endpoint does not authorize and seems deprecated** $.ajax({ type: 'POST', url: ajax_obj.ajax_url, data: { action: 'get_customer_contact_info', loyaltyId: userLoyaltyId, _ajax_nonce: ajax_obj.ajax_nonce }, success: function(data) { let contactInfo = JSON.parse(data); if (!contactInfo) { return; } // Set name, email and phone number fields after name field exists waitForEl('#customer-name').then((el) => { $(el).val(contactInfo.name); $('#customer-email').val(contactInfo.email); $('#phone-number').val(contactInfo.phone); }) } }); } }); } }); })(jQuery);