Woocommerce Adding Multiple Items to the Cart with Ajax

I use latest version of Wordpress and Woocommerce. I have some JavaScript that loops over DOM elements of class .selectable and grabs the product_id attribute from the ones with class .selected, and adds that item to the cart:

// selects the elements
$('.next').on('click', function() {
    var parent  = $(this).closest('.panel');
    var selectables = parent.children('.option.selectable.selected');

    $(selectables).each(function() {
        var product = $(this).attr('product');
        add_to_cart(product, 1);    
    });
}

// add to cart AJAX
function add_to_cart(product_id, qty) {
    $.ajax({
        type: "POST",
        url: base_url + '/wp-admin/admin-ajax.php',
        data: {action : 'cl_add_to_cart', 'product_id': product_id, 'qty': qty},
        success : function(response) {
            console.log(response);
        }
    });
}

And I have a PHP function in functions.php

add_action('wp_ajax_cl_add_to_cart', 'cl_add_to_cart');
add_action('wp_ajax_nopriv_cl_add_to_cart', 'cl_add_to_cart');

function cl_add_to_cart() {
    global $woocommerce;
    $product_id   = trim($_POST['product_id']);
    $qty = !empty($_POST['qty']) ? trim($_POST['qty']) : 1;
    $added = WC()->cart->add_to_cart($product_id, $qty);
    echo json_encode($added);
}

The AJAX call is hitting the PHP function just fine - I can echo out $added which gives me a hash. If I have two or more items in the selectables var, they both hit the PHP function (I get two hashes back) but only the first one gets added to the cart.

I can't for the life of me figure out why. Any ideas?

1

1 Answer

Is better to send all items to be added all together at once with Ajax, than send them separately in multiple Ajax requests, this will be lighter and more effective.

You need to be sure that $(selectables).each(function() { // ... }); is working as you expect.

The following will send a unique Ajax request for your click event.

The jQuery code

// Multi Ajax adda to cart
function multiAddToCart( productsData ) {
    $.ajax({
        url: base_url + '/wp-admin/admin-ajax.php',
        type: 'POST',
        dataType: 'JSON',
        data: {
            'action': 'multi_add_to_cart',
            'items' : Object.assign({}, productsData)
        },
        success : function(response) {
            $(document.body).trigger('wc_fragment_refresh'); // Refresh cart fragments
            console.log(response);
        },
        error : function(error) {
            console.log(error);
        }
    });
}

$('.next').on('click', function() {
    var productsData = [];
    var parent  = $(this).closest('.panel');
    var selectables = parent.children('.option.selectable.selected');

    $(selectables).each(function() {
        var productId = $(this).attr('product');
        productsData.push({'id': productId, 'qty': 1});
    });
    // Check the data before (number of items found)
    console.log(productsData); 

    multiAddToCart( productsData );
});

The php receiver function:

add_action('wp_ajax_multi_add_to_cart', 'multi_ajax_add_to_cart');
add_action('wp_ajax_nopriv_multi_add_to_cart', 'multi_ajax_add_to_cart');
function multi_ajax_add_to_cart() {
    if (isset($_POST['items']) ) {
        $item_keys = array();

        foreach( $_POST['items'] as $item ) {
            if( isset($item['id']) ) {
                $item_qty  = isset($item['qty']) && $item['qty'] > 1 ? $item['qty'] : 1;
                $item_keys[] = WC()->cart->add_to_cart($item['id'], $item_qty);
            }
        }
        echo json_encode($item_keys); // Send back cart item keys
    }
    die();
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

It should work adding all items at once.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Alexander Ross

Alexander Ross

Gaming, Esports & Interactive Media Writer

Alexander Ross has covered the video game industry for a decade, writing deep dives on game design, esports tournaments, VR developments, and gaming culture.

Share this article
Twitter Facebook Pinterest