6

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>
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
David Maranga
  • 149
  • 1
  • 2
  • 12

2 Answers2

9

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.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • This works! Thank you very much. I appreciate your help :) – David Maranga Jun 01 '18 at 05:14
  • Thanks, it worked. But when it comes to multiple variations but without chosen 2nd option then it's not working. Example my product "T-shirt" - Variation 1. size: M, color: green (in this case it worked). Variation 2. size: XL, color: any (in this case it's not working, even if I select a color from any) – Naiem Jun 26 '21 at 17:27
0

You could use this plugin ("Woocommerce Ajax add to cart for variable products") to Ajaxify the "Add to cart" button which is supposed to be pressed after selecting variation's attributes (e.g. Color) and quantity on the front-end. Without this plugin by default, the page refreshes when you press "Add to cart"

enter image description here

Vadim H
  • 717
  • 5
  • 12