简体   繁体   English

WooCommerce-如何使用具有相同购物车按钮的Ajax将多种不同的产品添加到购物车?

[英]WooCommerce - How can I add multiple, different products to cart using ajax with same add-to-cart-Button?

I am trying to use ajax to add multiple, different products to cart with one button click. 我正在尝试使用ajax,只需单击一下按钮即可将多个不同的产品添加到购物车。 The AddToCart-Button is living in a non-WooCommerce page template. AddToCart-Button位于非WooCommerce页面模板中。

I think it can be solved by waiting for the first ajax post to succeed, then iterate to the next product and so on until all selected products are done ajax posting and after that finally the succeed should happen. 我认为可以通过等待第一个ajax发布成功,然后迭代到下一个产品等等来解决,直到所有选定的产品都完成ajax发布,此后才应该成功。

I just don't know how I do that :) Do you maybe know how? 我只是不知道我该怎么做:)你也许知道如何吗?

This is my products form html: 这是我的产品表单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>

This is the jQuery: 这是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);

And the php function handling my Ajax: 和处理我的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();
}

The code is working already fine, only culprit: it merely adds 1 product-id and its set quantity to cart and stops after that, even though more than one product was selected by setting quantities for the other products as well. 该代码已经可以正常工作,仅是罪魁祸首:它只是在购物车中添加了1个产品ID及其设置的数量,然后停止运行,即使同时通过设置其他产品的数量选择了多个产品也是如此。

I am looking for a solution, that will add all selected products to cart according to whatever qty is set per product. 我正在寻找一种解决方案,它将根据每种产品设置的数量将所有选择的产品添加到购物车中。

Any help? 有什么帮助吗? suggestions? 建议?

The following code was added to my functions.php. 以下代码已添加到我的functions.php中。 It shows how to send multiple products to WooCommerce in a single AJAX request. 它显示了如何在单个AJAX请求中将多个产品发送到WooCommerce。 It is just a skeleton you will need to add the PHP code that actually adds the products to the cart. 这只是一个骨架,您需要添加实际上将产品添加到购物车的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();
} );

The $_POST for this HTTP request is: 此HTTP请求的$ _POST为:

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

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

)

You may want to try jQuery's .serialize() on your form. 您可能想在表单上尝试jQuery的.serialize()。 I think that will be the most concise solution. 我认为这将是最简洁的解决方案。 If this is not sufficient please let me know. 如果还不够,请通知我。 Now that I have WooCommerce activated it is easy to add more details to this answer. 现在,我已经激活了WooCommerce,可以轻松地为该答案添加更多详细信息。

ADDENDUM 附录

I tried jQuery's .serialize() on your HTML form. 我在您的HTML表单上尝试了jQuery的.serialize()。 First you must add a hidden HTML <input> element to provide the AJAX action parameter: 首先,您必须添加一个隐藏的HTML <input>元素以提供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>

The jQuery AJAX call using .serialize() is: 使用.serialize()的jQuery AJAX调用为:

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

This sends the following $_POST: 这将发送以下$ _POST:

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

    [quantity_5353] => 0
    [stock] => 1989
    [quantity_5354] => 0
)

I don't quite understand some of this but I think if you tweak your form you can get jQuery's .serialize() to batch your products. 我不太了解其中的一些内容,但我认为,如果您对表格进行调整,则可以获取jQuery的.serialize()来批量处理产品。 Consider changing 考虑改变

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

I don't think you need to send "stock". 我认为您不需要发送“库存”。 I would also not hard code the product data directly into the form but use PHP variables so the form can be used again with different products. 我也不会将产品数据直接硬编码到表单中,而是使用PHP变量,以便可以将表单再次用于其他产品。 Ideally the HTML for the products in the form should be generated using a foreach ( $products as $product ) { ... } so the form can work for any number of products not just 2. 理想情况下,表单中产品的HTML应该使用foreach($ products as $ product){...}生成,以便表单可以用于任意数量的产品,而不仅仅是2种产品。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Woocommerce 中的产品自定义循环上启用 Ajax 添加到购物车按钮 - Enable Ajax add to cart button on products custom loop in Woocommerce WooCommerce AJAX 添加到购物车 - 仅限简单产品 - WooCommerce AJAX add to cart - simple products only WooCommerce:更改多个产品的添加到购物车按钮文本,并重定向到结帐 - WooCommerce: Change add to cart button text for multiple products with a redirection to checkout 禁用特定 WooCommerce 产品的添加到购物车按钮 - Disabling Add to Cart Button for Specific WooCommerce Products 隐藏WooCommerce变量产品上的“添加到购物车”按钮 - Hiding 'Add to Cart' button on WooCommerce variable products 隐藏大多数产品的添加到购物车按钮-Woocommerce - Hide the add to cart button for most products - Woocommerce Woocommerce使用单个“添加到购物车”按钮将产品分组 - Woocommerce Grouped Products with Individual “Add To Cart” Button 如何从WooCommerce中的相关产品中删除“添加到购物车”按钮? - How to remove Add to Cart button from Related Products in WooCommerce? 我如何用图标替换“添加到购物车”文本(添加到购物车按钮woocommerce) - How can i replace text “Add to cart” with an icon (Add to cart button woocommerce) 在访问WooCommerce时自动将多种产品添加到购物车 - Automatically add multiple products to cart on visit WooCommerce
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM