jQuery(function($) { // 1) Remove existing theme/plugin handlers on product add-to-cart $(document).off('click', '.single_add_to_cart_button'); $(document).off('submit', 'form.cart'); // 2) Our custom AJAX add-to-cart handler $(document).on('click', 'form.cart .single_add_to_cart_button', function(e) { e.preventDefault(); var $button = $(this); var $form = $button.closest('form.cart'); if (!$form.length) { return; } // Use FormData so Advanced Product Fields (and any files/blobs) work correctly var formData = new FormData($form[0]); // WooCommerce AJAX endpoint var ajaxUrl; if (typeof wc_add_to_cart_params !== 'undefined') { ajaxUrl = wc_add_to_cart_params.wc_ajax_url.replace('%%endpoint%%', 'add_to_cart'); } else { // Fallback: use the form action if params are missing ajaxUrl = $form.attr('action'); } $button.prop('disabled', true).addClass('loading'); $.ajax({ url: ajaxUrl, type: 'POST', data: formData, processData: false, // important for FormData / Blobs contentType: false, // let browser set multipart/form-data success: function(response) { // If Woo returns fragments, let WooCommerce JS update the mini cart if (response && response.fragments) { $(document.body).trigger('added_to_cart', [ response.fragments, response.cart_hash, $button ]); } else { // Fallback: force a fragment refresh $(document.body).trigger('wc_fragment_refresh'); } // Prevent "Confirm Form Resubmission" on refresh if (window.history && window.history.replaceState) { window.history.replaceState(null, null, window.location.href); } }, error: function(xhr, status, error) { console.error('Add to cart AJAX error:', error); // As a fallback, try normal submit so the cart still works try { $form[0].submit(); } catch (e2) {} }, complete: function() { $button.prop('disabled', false).removeClass('loading'); } }); }); // 3) If user presses Enter on the form, route it to our click handler $(document).on('submit', 'form.cart', function(e) { e.preventDefault(); $(this).find('.single_add_to_cart_button').trigger('click'); }); });