2
votes

I am trying to get AJAX to work for the Add to Cart button on the WooCommerce product pages of my site. I am using the below code snippet to get AJAX functionality and it all works as it should, except for the last portion of the code. I don't see any success/notice/error messages when the Add to Cart button is clicked. The item(s) get added to the cart, but there's no visual notice (apart from the loading animation on the button) to let the user know that the item has been added successfully.

If I remove the last section of the code, below, "Add fragments for notices", I see the notifications when the item is added, but only AFTER I reload the page.

I am trying to make it so that when the Add to Cart button is hit, the item gets added to the cart and a success message is shown, or an error message accordingly. What am I doing wrong?

/**
 * JS for AJAX Add to Cart handling
 */

function product_page_ajax_add_to_cart_js() {
    ?><script type="text/javascript" charset="UTF-8">
        jQuery(function($) {

            $('form.cart').on('submit', function(e) {
                e.preventDefault();

                var form = $(this);
                form.block({ message: null, overlayCSS: { background: '#fff', opacity: 0.6 } });

                var formData = new FormData(form.context);
                formData.append('add-to-cart', form.find('[name=add-to-cart]').val() );

                // Ajax action.
                $.ajax({
                    url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'add_to_cart' ),
                    data: formData,
                    type: 'POST',
                    processData: false,
                    contentType: false,
                    complete: function( response ) {
                        response = response.responseJSON;

                        if ( ! response ) {
                            return;
                        }

                        if ( response.error && response.product_url ) {
                            window.location = response.product_url;
                            return;
                        }

                        // Redirect to cart option
                        if ( wc_add_to_cart_params.cart_redirect_after_add === 'yes' ) {
                            window.location = wc_add_to_cart_params.cart_url;
                            return;
                        }

                        var $thisbutton = form.find('.single_add_to_cart_button'); //
//                      var $thisbutton = null; // uncomment this if you don't want the 'View cart' button

                        // Trigger event so themes can refresh other areas.
                        $( document.body ).trigger( 'added_to_cart', [ response.fragments, response.cart_hash, $thisbutton ] );

                        // Remove existing notices
                        $( '.woocommerce-error, .woocommerce-message, .woocommerce-info' ).remove();

                        // Add new notices
                        form.closest('.product').before(response.fragments.notices_html)

                        form.unblock();
                    }
                });
            });
        });
    </script><?php
}
add_action( 'wp_footer', 'product_page_ajax_add_to_cart_js' );


/**
 * Add to cart handler.
 */

function ajax_add_to_cart_handler() {
    WC_Form_Handler::add_to_cart_action();
    WC_AJAX::get_refreshed_fragments();
}
add_action( 'wc_ajax_add_to_cart', 'ajax_add_to_cart_handler' );
add_action( 'wc_ajax_nopriv_add_to_cart', 'ajax_add_to_cart_handler' );

// Remove WC Core add to cart handler to prevent double-add
remove_action( 'wp_loaded', array( 'WC_Form_Handler', 'add_to_cart_action' ), 20 );

/**
 * Add fragments for notices.
 */

function ajax_add_to_cart_add_fragments( $fragments ) {
    $all_notices  = WC()->session->get( 'wc_notices', array() );
    $notice_types = apply_filters( 'woocommerce_notice_types', array( 'error', 'success', 'notice' ) );

    ob_start();
    foreach ( $notice_types as $notice_type ) {
        if ( wc_notice_count( $notice_type ) > 0 ) {
            wc_get_template( "notices/{$notice_type}.php", array(
                'messages' => array_filter( $all_notices[ $notice_type ] ),
            ) );
        }
    }
    $fragments['notices_html'] = ob_get_clean();

    wc_clear_notices();

    return $fragments;
}
add_filter( 'woocommerce_add_to_cart_fragments', 'ajax_add_to_cart_add_fragments' );
1

1 Answers

0
votes

Replace the below code.

 /**
 * Add fragments for notices.
 */

function ajax_add_to_cart_add_fragments( $fragments ) {
    $all_notices  = WC()->session->get( 'wc_notices', array() );
    $notice_types = apply_filters( 'woocommerce_notice_types', array( 'error', 'success', 'notice' ) );

    ob_start();
    foreach ( $notice_types as $notice_type ) {
        if ( wc_notice_count( $notice_type ) > 0 ) {
            wc_get_template( "notices/{$notice_type}.php", array(
                'notices' => array_filter( $all_notices[ $notice_type ] ),
            ) );
        }
    }
    $fragments['notices_html'] = ob_get_clean();

    // wc_clear_notices();

    return $fragments;
}
add_filter( 'woocommerce_add_to_cart_fragments', 'ajax_add_to_cart_add_fragments' );