Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ajax add to cart button for product variation in WooCommerce 3

I have this button here. The use of this button is to add to cart a product has a product id of 237, variation id of 208673, and attribute_pa_option of bluetooth. Is there a way to AJAX this?

<div class="btnss">
    <span class="price">
        <span class="woocommerce-Price-amount amount">6,999&nbsp;
            <span class="woocommerce-Price-currencySymbol">kr</span>
        </span>
    </span>
    <div class="quantity buttons_added">
        <input type="button" value="-" class="minus">
        <label class="screen-reader-text" for="quantity_5b101f605f067">Quantity</label>
        <input type="number" id="quantity_5b101f605f067" class="input-text qty text" step="1" min="1" max="" name="quantity" value="1" title="Qty" size="4" pattern="[0-9]*" inputmode="numeric" aria-labelledby="">
        <input type="button" value="+" class="plus">
    </div>
    <a href="/?add-to-cart=237&variation_id=208673&attribute_pa_option=bluetooth" class="button product_type_simple add_to_cart_button ajax_add_to_cart">Add to cart</a>
</div>
like image 617
David Maranga Avatar asked May 31 '18 19:05

David Maranga


People also ask

How do I add AJAX add to cart button on WooCommerce product page?

Create Javascript File After adding the javascript, create a new folder in your child theme called “JS” and add a new javascript called “ajax-add-to-cart. js”. If you have doubts about how to create a child theme, you can consult the linked tutorial from wp.


1 Answers

To make it work I use a custom ajax add-to-cart for product variations exclusively.

1). I have first changed a bit your button html:

<div class="btnss">
    <span class="price">
        <span class="woocommerce-Price-amount amount">6,999&nbsp;
            <span class="woocommerce-Price-currencySymbol">kr</span>
        </span>
    </span>
    <div class="quantity buttons_added">
        <input type="button" value="-" class="minus">
        <label class="screen-reader-text" for="quantity_5b101f605f067">Quantity</label>
        <input type="number" id="quantity_5b101f605f067" class="input-text qty text" step="1" min="1" max="" name="quantity" value="1" title="Qty" size="4" pattern="[0-9]*" inputmode="numeric" aria-labelledby="">
        <input type="button" value="+" class="plus">
    </div>
    <a href="#" class="button product_type_variation add_to_cart_button ajax variation" data-product_id="237" data-variation_id="208673" data-quantity="1" data-variation="pa_option=bluetooth">Add to cart</a>
</div>

As you will see I don't use the button href attribute, as I post the data through ajax.

For your attributes, if you have more than one, you will separate each pair by a coma like:

data-variation="pa_option=bluetooth,pa_color=red-shiny"

2). The PHP (Wordpress-Ajax) and the jQuery (Ajax) code:

// Wordpress Ajax php: Adding variation to cart
add_action( 'wp_ajax_nopriv_variation_to_cart', 'product_variation_add_to_cart' );
add_action( 'wp_ajax_variation_to_cart', 'product_variation_add_to_cart' );
function product_variation_add_to_cart() {
    if( isset($_POST['pid']) && $_POST['pid'] > 0 ){
        $product_id   = (int) $_POST['pid'];
        $variation_id = (int) $_POST['vid'];
        $quantity     = (int) $_POST['qty'];
        $attributes   = explode(',', $_POST['var']);
        $variation    = array();
        foreach($attributes as $values){
            $values = explode('=', $values);
            $variation['attributes_'.$values[0]] = $values[1];
        }
        WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation );
        echo true;
    }
    die(); // To avoid server error 500
}

// The Jquery ajax script
add_action( 'wp_footer', 'custom_product_variation_script' );
function custom_product_variation_script() {
    // HERE set the page or the post ID
    $the_id = 102;

    if( ! ( is_page($the_id) || is_single($the_id) ) ) return;

    $view_cart = '<a href="'.wc_get_cart_url().'" class="added_to_cart wc-forward" title="View cart">View cart</a>';
    $adding    = __('Adding to cart…', 'woocommerce');
    ?>
    <script type="text/javascript">
    jQuery( function($){
        // wc_add_to_cart_params is required to continue
        if ( typeof wc_add_to_cart_params === 'undefined' )
            return false;

        var a = 'a.button.ajax.variation',
            b = $(a).html(),
            c = '<?php echo $view_cart; ?>',
            d = '<?php echo $adding; ?>';

        // Sync the data-quantity attribute
        $('input.minus,input.plus').on( 'click blur', function(){
            $(a).attr('data-quantity',$('input.qty').val());
        });
        $('input.qty').on('input click blur', function(){
            $(a).attr('data-quantity',$('input.qty').val());
        })

        $(a).on('click', function(e){
            e.preventDefault();

            $('a.wc-forward').remove();
            $(a).html(d);

            // The Ajax request
            $.ajax({
                type: 'POST',
                url: wc_add_to_cart_params.ajax_url,
                data: {
                    'action': 'variation_to_cart',
                    'pid'   : $(a).attr('data-product_id'),
                    'vid'   : $(a).attr('data-variation_id'),
                    'qty'   : $(a).attr('data-quantity'),
                    'var'   : $(a).attr('data-variation'),
                },
                success: function (response) {
                    if(response){
                        // Update button and refresh minicart fragments
                        setTimeout(function(){
                            $(a).addClass('added').html(b).after(c);
                            $(document.body).trigger('added_to_cart').trigger('wc_fragment_refresh');
                        }, 500);
                    }
                },
                error: function (error) {
                    $(a).addClass('failed').html('Add to cart failed!');
                    console.log(error);
                }
            });
        });
    });
    </script>
    <?php
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

like image 155
LoicTheAztec Avatar answered Sep 18 '22 13:09

LoicTheAztec