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

时间:2022-10-25 10:06:19

I want to make an "Add To Cart" button on a product page that would work with 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的产品页面上创建一个“添加到购物车”按钮。我该怎么做?当我在产品页面上添加到购物车时 - 它刷新页面,我如何通过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将带有所选属性的产品添加到我的购物车中并打开该购物车(就像当你将鼠标悬停在菜单上的包图片上时)并摇动包图片。

5 个解决方案

#1


14  

We can use ajax from archive page. it's easy -

我们可以使用归档页面中的ajax。这很容易 -

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

P.S. JS Callback. For example you can show popup with links "Back to shop" and "Cart" or "Checkout"

附: JS回调。例如,您可以显示带有“返回商店”和“购物车”或“结帐”链接的弹出窗口

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

#2


7  

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. It then sends the product id to the php class. There you need to add code to add the corresponding product to the cart.

这只是一个如何完成它的例子。虽然它很基础。此javascript检查带有类名.add-to-cart的链接,并检查相应产品的rel属性。然后它将产品ID发送到php类。在那里,您需要添加代码以将相应的产品添加到购物车。

I suggest you search some more about the topic to make it suit your needs. Good luck.

我建议你再搜索一下这个话题,以满足你的需求。祝你好运。

#3


1  

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.

PS。离开第一部分,它只为那些不需要超过1个产品的人添加了1个产品,但是我为那些需要不仅仅添加了1个产品的人添加了一个解决方案。

#4


0  

add-to-cart.js

添加到cart.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;
});

#5


0  

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.
Here is css.

您可能需要对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;
}

#1


14  

We can use ajax from archive page. it's easy -

我们可以使用归档页面中的ajax。这很容易 -

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

P.S. JS Callback. For example you can show popup with links "Back to shop" and "Cart" or "Checkout"

附: JS回调。例如,您可以显示带有“返回商店”和“购物车”或“结帐”链接的弹出窗口

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

#2


7  

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. It then sends the product id to the php class. There you need to add code to add the corresponding product to the cart.

这只是一个如何完成它的例子。虽然它很基础。此javascript检查带有类名.add-to-cart的链接,并检查相应产品的rel属性。然后它将产品ID发送到php类。在那里,您需要添加代码以将相应的产品添加到购物车。

I suggest you search some more about the topic to make it suit your needs. Good luck.

我建议你再搜索一下这个话题,以满足你的需求。祝你好运。

#3


1  

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.

PS。离开第一部分,它只为那些不需要超过1个产品的人添加了1个产品,但是我为那些需要不仅仅添加了1个产品的人添加了一个解决方案。

#4


0  

add-to-cart.js

添加到cart.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;
});

#5


0  

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.
Here is css.

您可能需要对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;
}