当前位置: 首页 > 知识库问答 >
问题:

WooCommerce-我如何使用ajax和相同的add-to-cart-button将多个不同的产品添加到购物车?

苍元章
2023-03-14

我认为可以通过等待第一个ajax发布成功,然后迭代到下一个产品等方法来解决,直到所有选定的产品都完成ajax发布,然后最终成功。

我只是不知道我该怎么做:)你知道怎么做吗?

这是我的产品表单HTML:

<form id="buy-tickets" action="https://mydomain.de/cart/" class="cart" method="post" enctype="multipart/form-data" novalidate="">
<input type="hidden" name="product_id[]" value="5353"><div class="terminMain"><div class="terminDate">28.09.2019 Event Name 1<p><b>(Noch Plätze frei)</b></p></div><div class="personenNumber" id="personenNumber1">
                        <div class="inputField">
                            <input type="button" value="-" class="qtyminus" field="quantity_5353" id="qtyminus1">
                            <input type="text" id="quantity_5353" name="quantity_5353" value="0" class="qty">
                            <input type="button" value="+" class="qtyplus" field="quantity_5353" id="qtyplus1">
                            <input type="hidden" name="stock" value="1985" field="stock">
                        </div>
                    </div></div><input type="hidden" name="product_id[]" value="5354"><div class="terminMain"><div class="terminDate">31.03.2026 Event Name 2<p><b>(Noch Plätze frei)</b></p></div><div class="personenNumber" id="personenNumber2">
                        <div class="inputField">
                            <input type="button" value="-" class="qtyminus" field="quantity_5354" id="qtyminus2">
                            <input type="text" id="quantity_5354" name="quantity_5354" value="0" class="qty">
                            <input type="button" value="+" class="qtyplus" field="quantity_5354" id="qtyplus2">
                            <input type="hidden" name="stock" value="1989" field="stock">
                        </div>
                    </div></div>            <div class="buchenBtn">
                <div class="btns woocommerce add-to-cart"> 
                            <button type="submit" name="ticket_process" value="1" class="ajax_add_to_cart single_add_to_cart_button btn added" id="buchen-wootickets">Buchen</button> <a href="https://mydomain.de/cart/" class="added_to_cart wc-forward" title="Warenkorb anzeigen">Show Cart</a>

                </div>
            </div>
</form>

这是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_action( 'wp_ajax_woocommerce_ajax_add_to_cart', 'tec_woocommerce_ajax_add_to_cart' );
add_action( 'wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'tec_woocommerce_ajax_add_to_cart' );

function tec_woocommerce_ajax_add_to_cart() {

            $product_id        = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_POST['product_id'] ) );
            $quantity          = empty( $_POST['quantity'] ) ? 1 : wc_stock_amount( $_POST['quantity'] );
            $variation_id      = absint( $_POST['variation_id'] );
            $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity );
            $product_status    = get_post_status( $product_id );

    if ( $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' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
            wc_add_to_cart_message( array( $product_id => $quantity ), true );
        }

        WC_AJAX::get_refreshed_fragments();
    } else {

        $data = array(
            'error'       => true,
            'product_url' => apply_filters( 'woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id ),
        );

        echo wp_send_json( $data );
    }

            wp_die();
}

代码已经很好地工作了,只是罪魁祸首:它只是添加1个产品ID和它设置的数量到购物车,然后停止,即使通过设置其他产品的数量选择了一个以上的产品。

有人帮忙吗?建议?

共有1个答案

爱乐邦
2023-03-14

下面的代码被添加到我的functions.php中。它展示了如何在单个AJAX请求中向WooCommerce发送多个产品。它只是一个框架,您将需要添加实际将产品html" target="_blank">添加到购物车的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();
} );

此HTTP请求的$_POST为:

$_POST=Array
(
    [action] => saskia_add_multiple_products
    [id] => Array
        (
            [0] => 2650
            [1] => 3060
        )

    [quantity] => Array
        (
            [0] => 1
            [1] => 2
        )

)

您可能希望在表单上尝试jQuery的.serialize()。我认为那将是最简洁的解决办法。如果这还不够,请让我知道。现在我已经激活了WooCommerce,很容易为这个答案添加更多的细节。

<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>

使用.serialize()的jQuery AJAX调用是:

jQuery.post( 'http://localhost/wp-admin/admin-ajax.php',
    jQuery('form#buy-tickets').serialize(),
    function(data) { /* process success response */}
);

这将发送以下$_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[]"
 类似资料:
  • 至少我可以添加一个产品,但我想添加更多的函数,如: WooCommerce总是只拿最后一个。

  • 我有一些自定义代码,添加一个项目到购物车,一个可变产品。如果我把同样的产品加两次,它只是增加了数量。我希望它添加产品作为一个不同的项目在推车中再次。 我该怎么做呢?使用domain.com?add-to-cart=3434&variation_id=4434等链接将项目添加到购物车中。 当该代码将项目添加到购物车时,会导致以下情况: 警告:第291行/home/****/public_html/w

  • 我试图将Woocommerce中的Add to Cart按钮的功能设置为只允许将特定产品添加到Cart中一次。 一旦第一次将特定产品添加到cart中,就需要隐藏添加到cart中的内容。 在推车我可以有任何数量的产品-只是一个最大的数量为每一个产品1。 如何允许将特定产品添加到购物车中一次?

  • 我遵循了以下关于如何为单个产品将ajax添加到购物车的指南:https://aceplugins.com/ajax-add-to-cart-button-on-the-product-page-woocommerce/ 我在我的孩子主题function.php文件中有PHP,它应该工作。 我的问题是,我只想使用时,一个简单的产品,只有这样,它是可用于其他产品类型。 我尝试将其添加到函数中,如下所示

  • 目标:在一个按钮点击中添加多个可变产品到购物车。 我试着将这段代码放入循环中,但它不起作用。 但是这种方法不能解决问题,因为我需要在一个按钮点击中添加几个产品变体。 所有的建议都将不胜感激。多谢了。

  • 是否有一个简短的代码或另一种方法来解决这个问题,或者这是真的被限制在单个产品页面上使用?