简体   繁体   English

Woocommerce - 产品页面 - 如何在“添加到购物车”按钮上创建 AJAX?

[英]Woocommerce - Product Page - How to create AJAX on "Add To Cart" button?

I want to make an "Add To Cart" button on a product page that would work with AJAX.我想在可以使用 AJAX 的产品页面上制作一个“添加到购物车”按钮。 How can I do it?我该怎么做? When I add to cart on a product page - it refreshes the page, how can I make it work by AJAX?当我在产品页面上添加到购物车时 - 它会刷新页面,我如何通过 AJAX 使其工作?

The "Add to cart" button on "Quick View" on archive works by ajax - and it's great, but how can I do the same on product page?存档中“快速查看”上的“添加到购物车”按钮由 ajax 工作 - 这很棒,但我如何在产品页面上做同样的事情?

I want to click on "Take me Home" on the product page which would then add the product with the selected attributes to my cart by ajax and will open that cart (like when you hover onto the bag image on menu) and shakes the bag image.我想单击产品页面上的“带我回家”,然后通过 ajax 将具有选定属性的产品添加到我的购物车,并打开该购物车(就像当您将鼠标悬停在菜单上的袋子图像上时)并摇晃袋子图片。

We can use ajax from archive page.我们可以从存档页面使用ajax。 it's easy -这很简单 -

Remove old button which submiting form:删除提交表单的旧按钮:

remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );

Add ajax-link from archive page to single product page:将 ajax-link 从存档页面添加到单个产品页面:

add_action( 'woocommerce_single_product_summary', 'woocommerce_template_loop_add_to_cart', 30 );

PS JS Callback. PS JS 回调。 For example you can show popup with links "Back to shop" and "Cart" or "Checkout"例如,您可以显示带有“返回商店”和“购物车”或“结帐”链接的弹出窗口

$('body').on('added_to_cart',function(){
    // Callback -> product added
    //$('.popup').show();
});

Just add the following attributes to the Add to Cart button to enable the Ajax button.只需将以下属性添加到 Add to Cart 按钮即可启用 Ajax 按钮。

<a href="<?php echo $product->add_to_cart_url() ?>" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button" data-product_id="<?php echo get_the_ID(); ?>" data-product_sku="<?php echo esc_attr($sku) ?>" aria-label="Add “<?php the_title_attribute() ?>” to your cart"> Add to Cart </a>

The ajax_add_to_cart add_to_cart_button classes, and the data-product_id="<?php echo get_the_ID(); ?>" data-product_sku="<?php echo esc_attr($sku) ?>" attributes are required. ajax_add_to_cart add_to_cart_button类和data-product_id="<?php echo get_the_ID(); ?>" data-product_sku="<?php echo esc_attr($sku) ?>"属性是必需的。

No need to apply any action or filter.无需应用任何操作或过滤器。

Please start by reading this page:请先阅读此页面:

http://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_(action) http://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_(action)

First you need to add some code to your functions.php for example:首先你需要在你的functions.php中添加一些代码,例如:

add_action( 'wp_ajax_add_foobar', 'prefix_ajax_add_foobar' );
add_action( 'wp_ajax_nopriv_add_foobar', 'prefix_ajax_add_foobar' );

function prefix_ajax_add_foobar() {
   $product_id  = intval( $_POST['product_id'] );
// add code the add the product to your cart
die();
}

Then you have to add some javascript code that triggers the add to cart and makes a call to the function:然后,您必须添加一些 javascript 代码来触发添加到购物车并调用该函数:

  jQuery( ".add-to-cart" ).each(function() 
{


    var product_id = jQuery(this).attr('rel');
    var el = jQuery(this);

    el.click(function() {

            var data = {
                action: 'add_foobar',
                product_id: product_id
            };

            jQuery.post('/wp-admin/admin-ajax.php' , data, function(response) {
                if(response != 0) {
                    // do something
                } else {
                    // do something else
                }

            });


        return false;

    });

});

This is just an example of how it can be done.这只是如何做到这一点的一个例子。 Although its very basic.虽然它非常基础。 This javascript checks for links with the classname .add-to-cart and checks the rel attribute for the corresponding product.这个 javascript 检查类名 .a​​dd-to-cart 的链接,并检查相应产品的 rel 属性。 It then sends the product id to the php class.然后它将产品 id 发送到 php 类。 There you need to add code to add the corresponding product to the cart.在那里您需要添加代码以将相应的产品添加到购物车。

I suggest you search some more about the topic to make it suit your needs.我建议您搜索有关该主题的更多信息,以使其适合您的需求。 Good luck.祝你好运。

Woocommerce has come along way. Woocommerce 已经出现了。 I think the solution is quite easy now.我认为现在解决方案很简单。 In case I am missing something, all that is required it checking the "Enable AJAX add to cart buttons on archives" and using the woocommerce_template_loop_add_to_cart() function.如果我遗漏了一些东西,只需检查“在档案中启用 AJAX 添加到购物车按钮”并使用woocommerce_template_loop_add_to_cart()函数。

The checkbox option is under Woocommerce > Settings > Products > General.复选框选项位于 Woocommerce > 设置 > 产品 > 常规下。 复选框选项位于 Woocommerce > 设置 > 产品 > 常规下。

Then simply use woocommerce_template_loop_add_to_cart() wherever you wish to output the button.然后只需在您希望输出按钮的地方使用woocommerce_template_loop_add_to_cart()即可。

If you are using a custom loop like I was, you need to be sure to make the product global in order for the woocommerce_template_loop_add_to_cart() to work.如果您像我一样使用自定义循环,您需要确保将产品设为全局,以便woocommerce_template_loop_add_to_cart()工作。

Below is a small example of using the function:下面是一个使用该函数的小例子:

add_shortcode( 'buy_again' , 'msp_buy_again_shortcode' );
function msp_buy_again_shortcode(){
    $order_items = msp_get_customer_unique_order_items( get_current_user_id() );
    echo '<div class="owl-carousel owl-theme">';
    foreach( $order_items as $id ){
        $product = wc_get_product( $id );
        global $product;

        if( ! empty( $product ) ){
            ?>
            <div class="card buy-again-product">
                <a class="link-normal" href="<?php echo $product->get_permalink(); ?>">
                    <?php echo $product->get_image( 'woocommerce_thumbnail', array( 'class' => 'card-img-top' ) ) ?>
                    <div class="card-body">
                        <?php echo wc_get_rating_html( $product->get_average_rating(), $product->get_review_count() ) ?>
                        <h5><?php echo $product->get_name(); ?></h5>
                        <p><?php echo $product->get_price_html() ?></p>
                        <?php woocommerce_template_loop_add_to_cart(); ?>
                    </div>
                </a>
            </div>
            <?php
        }
    }
    // loop and display buy again.
    // try to use the official woocommerce loop.

    echo '</div>';

}

Copy this code into your file.将此代码复制到您的文件中。 For example: my-theme-wc-single-ajax-add-cart.js .例如: my-theme-wc-single-ajax-add-cart.js

function myThemeWc_SingleProductAddToCart(thisObj) {
    if (typeof($) === 'undefined') {
        var $ = jQuery.noConflict();
    }

    var thisForm = thisObj.closest('form');
    var button = thisForm.find('.button');
    var formUrl = thisForm.attr('action');
    var formMethod = thisForm.attr('method');
    if (typeof(formMethod) === 'undefined' || formMethod == '') {
        formMethod = 'POST';
    }
    var formData = new FormData(thisForm[0]);
    formData.append(button.attr('name'), button.val());

    button.removeClass('added');
    button.addClass('loading');

    myThemeWc_SingleProductCartAjaxTask = $.ajax({
        url: formUrl,
        method: formMethod,
        data: formData,
        cache: false,
        contentType: false,
        processData: false
    })
    .done(function(data, textStatus, jqXHR) {
        $(document.body).trigger('wc_fragment_refresh');

        $.when(myThemeWc_SingleProductCartAjaxTask)
        .then(myThemeWc_SingleProductUpdateCartWidget)
        .done(function() {
            button.removeClass('loading');
            button.addClass('added');
            setTimeout(function() {
                button.removeClass('added');
            }, 2000);
        });
    })
    .fail(function(jqXHR, textStatus, errorThrown) {
        button.removeClass('loading');
    })
    .always(function(jqXHR, textStatus, errorThrown) {
        $('.cart').off('submit');
        myThemeWc_SingleProductListenAddToCart();
    });
}// myThemeWc_SingleProductAddToCart


function myThemeWc_SingleProductListenAddToCart() {
    if (typeof($) === 'undefined') {
        var $ = jQuery.noConflict();
    }

    $('.cart').on('submit', function(e) {
        e.preventDefault();
        myThemeWc_SingleProductAddToCart($(this));
    });
}// myThemeWc_SingleProductListenAddToCart


/**
 * Update WooCommerce cart widget by called the trigger and listen to the event.
 * 
 * @returns {undefined}
 */
function myThemeWc_SingleProductUpdateCartWidget() {
    if (typeof($) === 'undefined') {
        var $ = jQuery.noConflict();
    }

    var deferred = $.Deferred();

    $(document.body).on('wc_fragments_refreshed', function() {
        deferred.resolve();
    });

    return deferred.promise();
}// myThemeWc_SingleProductUpdateCartWidget


var myThemeWc_SingleProductCartAjaxTask;


// on page load --------------------------------------------
jQuery(function($) {
    $(document.body).on('wc_fragments_refreshed', function() {
        console.log('woocommerce event fired: wc_fragments_refreshed');
    });

    myThemeWc_SingleProductListenAddToCart();
});

You may need to replace function, variable prefix myThemeWc_ to what you want.您可能需要将函数、变量前缀myThemeWc_为您想要的。

This code use the original WooCommerce single product page add to cart button but stop its functional and then use ajax instead by remain all the values in the form.此代码使用原始的 WooCommerce 单个产品页面添加到购物车按钮但停止其功能,然后使用 ajax 代替保留表单中的所有值。

Then enqueue this js file.然后将这个js文件入队。

add_action('wp_enqueue_scripts', 'mythemewc_enqueue_scripts');
function mythemewc_enqueue_scripts() {
    if (class_exists('\\WooCommerce') && is_product()) {
        wp_enqueue_script('mythemewc-single-product', trailingslashit(get_stylesheet_directory_uri()) . 'assets/js/my-theme-wc-single-ajax-add-cart.js', ['jquery'], false, true);
    }
}

You may have to code your css button to make it show the loading, added icon.您可能需要对 css 按钮进行编码以使其显示加载的添加图标。
Here is css.这里是css。

.woocommerce #respond input#submit.added::after, 
.woocommerce a.btn.added::after, 
.woocommerce button.btn.added::after, 
.woocommerce input.btn.added::after,
.woocommerce .single_add_to_cart_button.added::after {
    font-family: WooCommerce;
    content: '\e017';
    margin-left: .53em;
    vertical-align: bottom;
}
.woocommerce #respond input#submit.loading, 
.woocommerce a.btn.loading, 
.woocommerce button.btn.loading, 
.woocommerce input.btn.loading,
.woocommerce .single_add_to_cart_button.loading {
    opacity: .25;
    padding-right: 2.618em;
    position: relative;
}
.woocommerce #respond input#submit.loading::after, 
.woocommerce a.btn.loading::after, 
.woocommerce button.btn.loading::after, 
.woocommerce input.btn.loading::after,
.woocommerce .single_add_to_cart_button.loading::after {
    font-family: WooCommerce;
    content: '\e01c';
    vertical-align: top;
    font-weight: 400;
    position: absolute;
    right: 1em;
    -webkit-animation: spin 2s linear infinite;
    animation: spin 2s linear infinite;
}

info: Tested with WooCommerce 2.4.10.信息:使用 WooCommerce 2.4.10 测试。

Hmm, well I did it in another way, used the woocommerce loop from add to cart (woocommerce/templates/loop/add-to-cart.php)嗯,我用另一种方式做到了,使用了从添加到购物车的 woocommerce 循环(woocommerce/templates/loop/add-to-cart.php)

  global $product;

echo apply_filters( 'woocommerce_loop_add_to_cart_link',
    sprintf( '<a href="%s" rel="nofollow" data-product_id="%s" data-product_sku="%s" data-quantity="%s" class="button %s product_type_%s">%s</a>',
        esc_url( $product->add_to_cart_url() ),
        esc_attr( $product->id ),
        esc_attr( $product->get_sku() ),
        esc_attr( isset( $quantity ) ? $quantity : 1 ),
        $product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
        esc_attr( $product->product_type ),
        esc_html( $product->add_to_cart_text() )
    ),
$product );

BUT the problem was that it was adding just 1 quantity, in fact, you can see in the code that is listed quantity : 1, so I had problems, until I bumped into this guys who saved me问题是它只添加了 1 个数量,事实上,您可以在列出数量的代码中看到:1,所以我遇到了问题,直到我遇到了救我的人

ps.附: leaving the 1st part where it adds just 1 product for people who don't need more than 1 product in the basket, but I added a solution for those who need more than just 1 product added to the cart.留下第一部分,它只为购物车中不需要超过 1 个产品的人添加 1 个产品,但我为那些需要将超过 1 个产品添加到购物车的人添加了一个解决方案。

You can replicate the behavour of the archives button in your single products您可以在单个产品中复制存档按钮的行为

add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');      function 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();
        }
add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');

function 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();
        }

you can see the full tutorial here你可以在这里看到完整的教程

https://quadmenu.com/add-to-cart-with-woocommerce-and-ajax-step-by-step/ https://quadmenu.com/add-to-cart-with-woocommerce-and-ajax-step-by-step/

add-to-cart.js添加到购物车.js

jQuery( document ).on( 'click', '.product_type_simple', function() { 

var post_id = jQuery(this).data('product_id');//store product id in post id variable
var qty = jQuery(this).data('quantity');//store quantity in qty variable

jQuery.ajax({
    url : addtocart.ajax_url, //ajax object of localization
    type : 'post', //post method to access data
    data : 
    {
        action : 'prefix_ajax_add_foobar', //action on prefix_ajax_add_foobar function
        post_id : post_id,
        quantity: qty
    },

    success : function(response){

            jQuery('.site-header .quantity').html(response.qty);//get quantity
            jQuery('.site-header .total').html(response.total);//get total

            //loaderContainer.remove();
            alert("Product Added successfully..");        
    }

});

return false;
});

To make ajax woocomerce work on another page you will need.要使 ajax woocomerce 在另一个页面上工作,您将需要。 goes in functions.php进入functions.php

paste this:粘贴这个:

remove_action ('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30);

add_action ('woocommerce_single_product_summary', 'woocommerce_template_loop_add_to_cart', 30);

in footer.php in the end paste this:在footer.php最后粘贴这个:

<script>
$ ('body'). on ('add_to_cart', function () {
     // Callback -> product added
     // $ ('. popup'). show ();
});
</script>

I used this plugin for the backend part https://wordpress.org/plugins/woo-ajax-add-to-cart/我在后端部分使用了这个插件https://wordpress.org/plugins/woo-ajax-add-to-cart/

I'm not using the product page, so I modified the script to work with any button:我没有使用产品页面,所以我修改了脚本以使用任何按钮:

 (function($) { $(document).on('click', '.btn', function(e) { var $thisbutton = $(this); try { var href = $thisbutton.prop('href').split('?')[1]; if (href.indexOf('add-to-cart') === -1) return; } catch (err) { return; } e.preventDefault(); var product_id = href.split('=')[1]; var data = { product_id: product_id }; $(document.body).trigger('adding_to_cart', [$thisbutton, data]); $.ajax({ type: 'post', url: wc_add_to_cart_params.wc_ajax_url.replace( '%%endpoint%%', 'add_to_cart' ), data: data, beforeSend: function(response) { $thisbutton.removeClass('added').addClass('loading'); }, complete: function(response) { $thisbutton.addClass('added').removeClass('loading'); }, 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 ]); $('a[data-notification-link="cart-overview"]').click(); } } }); return false; }); })(jQuery);

For me working exelent.对我来说工作出色。 I think this is the simplest solution with Ajax.我认为这是使用 Ajax 的最简单的解决方案。

<a href="<?php echo $product->add_to_cart_url() ?>" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button add-cart" data-product_id="<?php echo get_the_ID(); ?>" data-product_sku="<?php echo esc_attr($sku) ?>"> + Add to cart</a>

I used Eh Jewel's answer but then added some custom JS for once the product was added to the cart.我使用了Eh Jewel 的答案,但随后添加了一些自定义 JS,以便将产品添加到购物车中。 This completes the final AJAX process of being able to update the page however you want.这完成了能够以任何方式更新页面的最终 AJAX 过程。

For completeness, here is the HTML code I used (same as Eh Jewel's ):为了完整起见,这是我使用的 HTML 代码(与Eh Jewel 的相同):

<a href="<?php echo $product->add_to_cart_url() ?>" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button" data-product_id="<?php echo get_the_ID(); ?>" data-product_sku="<?php echo esc_attr($sku) ?>" aria-label="Add “<?php the_title_attribute() ?>” to your cart"> Add to Cart </a>

Then for the custom JS bit:然后对于自定义 JS 位:

$(window).on('load', function() {
  $('body').on( 'added_to_cart', function( button, data ){
    // Put custom functionality here. Debugging below shows you what you have to work with:
    console.log('added_to_cart');
    console.log(button);
    console.log(data);
  });
});

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

相关问题 在单个产品页面/ Wordpress / Woocommerce中禁用Ajax添加到购物车按钮 - Disable ajax for add to cart button in single product page / Wordpress / Woocommerce WooCommerce 3 中产品变化的 Ajax 添加到购物车按钮 - Ajax add to cart button for product variation in WooCommerce 3 Ajax 加入购物车 WooCommerce 产品页面 - Ajax add to cart on WooCommerce product page woocommerce 添加到单个产品页面上的购物车按钮 - woocommerce add to cart button on single product page AJAX添加到购物车按钮不工作自定义查询循环产品woocommerce - AJAX add to cart button not working on custom query loop product woocommerce WooCommerce AJAX放入购物车以获取可变产品,仍重定向到产品页面 - WooCommerce AJAX Add to Cart for Variable products, still redirecting to product page WooCommerce隐藏循环和产品页面上的“添加到购物车”按钮 - WooCommerce Hide Add To Cart Button on Loop & Product Page Woocommerce 产品页面重定向中断添加到购物车按钮 - Woocommerce product page redirect breaks add to cart button 添加到购物车按钮在 Woocommerce 的单个产品页面上不起作用 - Add to cart button not working on single product page in Woocommerce 如何在自定义页面(不是商店/产品页面)上添加到购物车按钮 Woocommerce - How to make add to cart button on custom page (not shop/product page) Woocommerce
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM