Add custom JavaScript actions to WP e-Commerce cart updates, again

This post is more than 10 years old.

I previously wrote about adding your own custom JavaScript actions to the WP e-Commerce cart update event. Of course, things change, people change, hairstyles change, interest rates fluctuate, WP e-Commerce moves goalposts, so there is a new way to do this since version 3.8.11 came out.

Let’s say you have a mini-cart in your theme, showing the number of items in the cart and the total amount. Something like this:

<span id="theme-checkout-count">Items: <?php echo wpsc_cart_item_count(); ?></span> |
<span id="theme-checkout-total"><?php echo wpsc_cart_total_widget(); ?></span> |
<a href="<?php echo get_option('shopping_cart_url'); ?>">Checkout</a>

WP e-Commerce now has a custom JavaScript event that fires whenever you add an item to the cart. You can catch that event and get the new HTML for the total amount of the shopping cart, just like this:

/**
* catch WP e-Commerce cart update event
* @param {jQuery.Event} event
*/
jQuery(document).on("wpsc_fancy_notification", function(event) {
    jQuery("#theme-checkout-total").html(event.response.cart_total);
});

Easy as! But there’s a catch (of course — this is WP e-Commerce after all). It gives you the total amount, but not how many items, and most people with mini-carts in their themes like to show the number of items too.

And there’s another catch (of course — still WP e-Commerce). It only triggers this event when you add to cart. Clearing the cart, which is also done via AJAX from the main cart widget, extends no such favour.

To resolve both of these issues, we need to get a little creative. First, we can implement our own AJAX handler in WordPress to return whatever information we want for the mini-cart. We can hook that into the new wpsc_fancy_notification event handler. Second, we can intercept all AJAX success events and check for the cart_empty action, which tells us we need to update the mini-cart. Here’s what you need to add to your functions.php or plugin:

/**
* add a custom AJAX request handler
*/
function theme_wpsc_cart_update() {
    $data = array(
        'cart_count' => wpsc_cart_item_count(),
        'cart_total' => wpsc_cart_total_widget(),
    );
    echo json_encode($data);
    exit;
}
add_action('wp_ajax_theme_wpsc_cart_update', 'theme_wpsc_cart_update');
add_action('wp_ajax_nopriv_theme_wpsc_cart_update', 'theme_wpsc_cart_update');

/**
* add JavaScript event handler to the page footer
*/
function theme_wpsc_footer() {
    if (!is_admin()) {
    ?>

    <script>
    jQuery(function($) {
        /**
        * catch WP e-Commerce cart update event
        * @param {jQuery.Event} event
        */
        $(document).on("wpsc_fancy_notification", function(event) {
            updateMinicart();
        });

        /**
        * catch AJAX complete events, to catch clear cart
        * @param {jQuery.Event} event
        * @param {jqXHR} xhr XmlHttpRequest object
        * @param {Object} ajaxOpts options for the AJAX request
        */
        $(document).ajaxComplete(function(event, xhr, ajaxOpts) {
            // check for WP e-Commerce "empty_cart" action
            if ("data" in ajaxOpts && ajaxOpts.data.indexOf("action=empty_cart") != -1) {
                updateMinicart();
            }
        });

        /**
        * submit AJAX request to update mini-cart
        */
        function updateMinicart() {
            // ask server for updated data
            $.ajax({
                url: "<?php echo admin_url('admin-ajax.php'); ?>",
                cache: false,
                dataType: "json",
                data: { action: "theme_wpsc_cart_update" },
                success: function(data) {
                    // update our mini-cart elements
                    $("#theme-checkout-count").html(data.cart_count);
                    $("#theme-checkout-total").html(data.cart_total);
                }
            });
        }

    });
    </script>

    <?php
    }
}
add_action('wp_footer', 'theme_wpsc_footer');

So even when WP e-Commerce moves the goalposts, we can still get the job done!