Php WooCommerce-如何使用带有相同“添加到购物车”按钮的ajax向购物车添加多个不同的产品?

Php WooCommerce-如何使用带有相同“添加到购物车”按钮的ajax向购物车添加多个不同的产品?,php,jquery,ajax,wordpress,woocommerce,Php,Jquery,Ajax,Wordpress,Woocommerce,我正在尝试使用ajax,只需单击一个按钮,即可将多个不同的产品添加到购物车中。 AddToCart按钮位于非WooCommerce页面模板中 我认为可以通过等待第一个ajax帖子成功,然后迭代到下一个产品,等等,直到所有选定的产品都完成ajax帖子,然后最终成功 我只是不知道我是怎么做到的:)你知道怎么做吗 这是我的产品表单html: 2019年9月28日活动名称1(Noch Plätze frei) 2026年3月31日事件名称2 布肯 这是jQuery: (function ($) {

我正在尝试使用ajax,只需单击一个按钮,即可将多个不同的产品添加到购物车中。 AddToCart按钮位于非WooCommerce页面模板中

我认为可以通过等待第一个ajax帖子成功,然后迭代到下一个产品,等等,直到所有选定的产品都完成ajax帖子,然后最终成功

我只是不知道我是怎么做到的:)你知道怎么做吗

这是我的产品表单html:


2019年9月28日活动名称1(Noch Plätze frei)

2026年3月31日事件名称2

布肯
这是jQuery:

(function ($) {
    $( document ).on( 'click', '.single_add_to_cart_button', function(e) {
        e.preventDefault();
        var tickets = $('#buy-tickets input[name="product_id[]"]');
        var ticketsData = [];
        var $this, ticketId, ticketQty, ticketProd;  
        tickets.each(function() {
                    $this = $( this );
                    id = $this.val();
                    ticketQty = $('#quantity_'+id).val();
                    if(ticketQty > 0){
                        ticketProd = {
                            action: 'woocommerce_ajax_add_to_cart', 
                            product_id: id, 
                            product_sku: '',
                            quantity: ticketQty,
                            variation_id: 0,
                        };
                        ticketsData.push(ticketProd);
                    }   
            });
        console.log('tickets: ', ticketsData);

        var $thisform = $('#buy-tickets');
        var $thisbutton = $(this);

        $.each(ticketsData, function(index, value){
            $.each(this, function (index, value) {
                console.log(index + " :: " + value);
            });
            $(document.body).trigger('adding_to_cart', [$thisbutton, this]);

            $.ajax({
                type: 'post',
                url: wc_add_to_cart_params.ajax_url,
                data: this,
                beforeSend: function (response) {
                    $thisform.addClass('loading');
                    $thisbutton.removeClass('added');
                },
                complete: function (response) {
                    $thisform.removeClass('loading');
                    $thisbutton.addClass('added');
                },
                success: function (response) {

                    if (response.error & response.product_url) {
                        window.location = response.product_url;
                        return;
                    } else {
                        $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $thisbutton]);
                    }
                },
            });

            return false;

        });
    });
})(jQuery);
以及处理我的Ajax的php函数:

add_动作('wp_ajax_woocommerce_ajax_add_到购物车','tec_woocommerce_ajax_add_到购物车');
添加操作(“wp_ajax_nopriv_woocommerce_ajax_add_to_cart”、“tec_woocommerce_ajax_add_to_cart”);
函数tec\u woocommerce\u ajax\u add\u to\u cart(){
$product\U id=应用\U过滤器('WOOMCOMMERCE\U add\U to\U cart\U product\U id',absint($\U POST['product\U id'));
$quantity=空($_POST['quantity'])?1:wc_库存金额($_POST['quantity']);
$variation_id=absint($_POST['variation_id']);
$passed_validation=apply_过滤器('woocommerce_add_to_cart_validation',true,$product_id,$quantity);
$product\U status=获取\U post\U状态($product\U id);
如果($passed_validation&&WC()->cart->add_to_cart($product_id,$quantity,$variation_id)&&&publish'=$product_status){
do_action('woocommerce_ajax_added_to_cart',$product_id);
if('yes'==获取选项('woocommerce\u cart\u redirect\u after\u add')){
wc_add_to_cart_消息(数组($product_id=>$quantity),true);
}
WC_AJAX::获取刷新的片段();
}否则{
$data=数组(
“错误”=>true,
“产品url”=>应用过滤器(“woocommerce\u cart\u redirect\u after\u error”,get\u permalink($product\u id),$product\u id),
);
echo wp_send_json($data);
}
wp_die();
}
该代码已经运行良好,这是唯一的罪魁祸首:它只向购物车添加1个产品id及其设置数量,然后停止,即使通过设置其他产品的数量选择了多个产品

我正在寻找一个解决方案,将所有选定的产品添加到购物车根据任何数量是每个产品设置


有什么帮助吗?建议?

以下代码已添加到my functions.php。它展示了如何在一个AJAX请求中向WooCommerce发送多个产品。这只是一个框架,您需要添加实际将产品添加到购物车的PHP代码

add_action( 'woocommerce_after_main_content', function() {
?>
<button id="saskia-add_multiple_products" style="background-color: cyan; border: 3px solid red; margin:50px;">
    Add Multiple Products
</button>
<script>
    jQuery( 'button#saskia-add_multiple_products' ).click( function() {
        var productsToAdd = [
            { id: 2650, quantity: 1 },
            { id: 3060, quantity: 2 }
        ];
        // There are multiple ways of sending complex data from JavaScript to WordPress
        // JavaScript: JSON.stringify(), jQuery: .serialize() or the following bare-bones
        // way which is wordy but probably the easiest to understand. Since, your data
        // is already in a HTML form .serialize() is probably the best but I am too lazy
        // to make a form so I am testing from data in a JavaScript array.
        var data = { action: 'saskia_add_multiple_products', id: [], quantity: [] };
        jQuery.each(productsToAdd, function( index, value ) {
            data.id[index]       = value.id;
            data.quantity[index] = value.quantity;
        } );
        jQuery.post( 'http://localhost/wp-admin/admin-ajax.php', data, function(data){ /* process success response */} );
    } );
</script>
<?php
} );

add_action( 'wp_ajax_saskia_add_multiple_products', function() {
    error_log( 'ACTION:wp_ajax_nopriv_saskia_add_multiple_products:$_POST=' . print_r( $_POST, TRUE ) );
    for ( $i = 0; $i < count( $_POST['id'] ); $i++ ) {
        $product_id = $_POST['id'][$i];
        $quantity   = $_POST['quantity'][$i];
        error_log( 'ACTION:wp_ajax_nopriv_saskia_add_multiple_products:$product_id=' . $product_id );
        error_log( 'ACTION:wp_ajax_nopriv_saskia_add_multiple_products:$quantity='   . $quantity );
        /* add each individual product to cart */
    }
    // return the update cart HTML fragments
    WC_AJAX::get_refreshed_fragments();
} );
您可能希望在表单上尝试jQuery的.serialize()。我认为这将是最简明的解决办法。如果这还不够,请让我知道。现在,我已经激活了,很容易为这个答案添加更多细节

附录

我在HTML表单上尝试了jQuery的.serialize()。首先,必须添加一个隐藏的HTML
元素以提供AJAX操作参数:

<form id="buy-tickets" action="https://mydomain.de/cart/" class="cart" method="post" enctype="multipart/form-data" novalidate="">
    <input type="hidden" name="action" value="saskia_add_multiple_products" />
    ...
</form>
这将发送以下$\u POST:

$_POST=Array
(
    [action] => saskia_add_multiple_products
    [product_id] => Array
        (
            [0] => 5353
            [1] => 5354
        )

    [quantity_5353] => 0
    [stock] => 1989
    [quantity_5354] => 0
)
我不太理解其中的一些内容,但我认为如果调整表单,可以使用jQuery的.serialize()来批处理产品。考虑改变

name="quantity_5353" -> name="quantity[]"
name="quantity_5354" -> name="quantity[]"

我认为你不需要寄“股票”。我也不会直接将产品数据硬编码到表单中,而是使用PHP变量,这样表单就可以再次用于不同的产品。理想情况下,表单中产品的HTML应该使用foreach($products as$product){…}生成,因此表单可以用于任意数量的产品,而不仅仅是2个。

以下代码添加到my functions.php中。它展示了如何在一个AJAX请求中向WooCommerce发送多个产品。这只是一个框架,您需要添加实际将产品添加到购物车的PHP代码

add_action( 'woocommerce_after_main_content', function() {
?>
<button id="saskia-add_multiple_products" style="background-color: cyan; border: 3px solid red; margin:50px;">
    Add Multiple Products
</button>
<script>
    jQuery( 'button#saskia-add_multiple_products' ).click( function() {
        var productsToAdd = [
            { id: 2650, quantity: 1 },
            { id: 3060, quantity: 2 }
        ];
        // There are multiple ways of sending complex data from JavaScript to WordPress
        // JavaScript: JSON.stringify(), jQuery: .serialize() or the following bare-bones
        // way which is wordy but probably the easiest to understand. Since, your data
        // is already in a HTML form .serialize() is probably the best but I am too lazy
        // to make a form so I am testing from data in a JavaScript array.
        var data = { action: 'saskia_add_multiple_products', id: [], quantity: [] };
        jQuery.each(productsToAdd, function( index, value ) {
            data.id[index]       = value.id;
            data.quantity[index] = value.quantity;
        } );
        jQuery.post( 'http://localhost/wp-admin/admin-ajax.php', data, function(data){ /* process success response */} );
    } );
</script>
<?php
} );

add_action( 'wp_ajax_saskia_add_multiple_products', function() {
    error_log( 'ACTION:wp_ajax_nopriv_saskia_add_multiple_products:$_POST=' . print_r( $_POST, TRUE ) );
    for ( $i = 0; $i < count( $_POST['id'] ); $i++ ) {
        $product_id = $_POST['id'][$i];
        $quantity   = $_POST['quantity'][$i];
        error_log( 'ACTION:wp_ajax_nopriv_saskia_add_multiple_products:$product_id=' . $product_id );
        error_log( 'ACTION:wp_ajax_nopriv_saskia_add_multiple_products:$quantity='   . $quantity );
        /* add each individual product to cart */
    }
    // return the update cart HTML fragments
    WC_AJAX::get_refreshed_fragments();
} );
您可能希望在表单上尝试jQuery的.serialize()。我认为这将是最简明的解决办法。如果这还不够,请让我知道。现在,我已经激活了,很容易为这个答案添加更多细节

附录

我在HTML表单上尝试了jQuery的.serialize()。首先,必须添加一个隐藏的HTML
元素以提供AJAX操作参数:

<form id="buy-tickets" action="https://mydomain.de/cart/" class="cart" method="post" enctype="multipart/form-data" novalidate="">
    <input type="hidden" name="action" value="saskia_add_multiple_products" />
    ...
</form>
这将发送以下$\u POST:

$_POST=Array
(
    [action] => saskia_add_multiple_products
    [product_id] => Array
        (
            [0] => 5353
            [1] => 5354
        )

    [quantity_5353] => 0
    [stock] => 1989
    [quantity_5354] => 0
)
我不太理解其中的一些内容,但我认为如果调整表单,可以使用jQuery的.serialize()来批处理产品。考虑改变

name="quantity_5353" -> name="quantity[]"
name="quantity_5354" -> name="quantity[]"

我认为你不需要寄“股票”。我也不会直接将产品数据硬编码到表单中,而是使用PHP变量,这样表单就可以再次用于不同的产品。理想情况下,表单中产品的HTML应该使用foreach($products as$product){…}生成,这样表单就可以用于任意数量的产品,而不仅仅是2个。

是否有理由不将所有产品添加批处理到单个AJAX请求中?我认为这不仅会更有效率,而且会简化逻辑。关于为什么给定的代码不起作用-浏览器网络日志是否显示发送了多个AJAX请求?这正是我想要的:D但不知道如何将产品添加批处理到一个AJAX请求中。您可以使用JSON.stringify()将JavaScript数组作为字符串发送到WooCommerce,然后使用