Woocommerce Add to Cart via Ajax in Vriable Product

Woo Commerce is a great e-commerce plugin for WordPress.It Has Very Nice Feature But Add to Cart via Ajax in Variable/Variation/Single Product Feature Not Available.Found this Solution & Share with You.

First of all Repalce Your Add-to-cart-variation.min.js in this snippets.

</code>
/*!
* Variations Plugin
*/
(function (e, t, n, r) {
e.fn.wc_variation_form = function () {
e.fn.wc_variation_form.find_matching_variations = function (t, n) {
var r = [];
for (var i = 0; i < t.length; i++) {
var s = t[i],
o = s.variation_id;
e.fn.wc_variation_form.variations_match(s.attributes, n) && r.push(s)
}
return r
};
e.fn.wc_variation_form.variations_match = function (e, t) {
var n = !0;
for (attr_name in e) {
var i = e[attr_name],
s = t[attr_name];
i !== r && s !== r && i.length != 0 && s.length != 0 && i != s && (n = !1)
}
return n
};
this.unbind("check_variations update_variation_values found_variation");
this.find(".reset_variations").unbind("click");
this.find(".variations select").unbind("change focusin");
return this.on("click", ".reset_variations", function (t) {
e(this).closest("form.variations_form").find(".variations select").val("").change();
var n = e(this).closest(".product").find(".sku"),
r = e(this).closest(".product").find(".product_weight"),
i = e(this).closest(".product").find(".product_dimensions");
n.attr("data-o_sku") && n.text(n.attr("data-o_sku"));
r.attr("data-o_weight") && r.text(r.attr("data-o_weight"));
i.attr("data-o_dimensions") && i.text(i.attr("data-o_dimensions"));
return !1
}).on("change", ".variations select", function (t) {

$variation_form = e(this).closest("form.variations_form");
$variation_form.find("input[name=variation_id]").val("").change();
$variation_form.trigger("woocommerce_variation_select_change").trigger("check_variations", ["", !1]);
e(this).blur();
e().uniform && e.isFunction(e.uniform.update) && e.uniform.update()
}).on("focusin", ".variations select", function (t) {
$variation_form = e(this).closest("form.variations_form");
$variation_form.trigger("woocommerce_variation_select_focusin").trigger("check_variations", [e(this).attr("name"), !0])
}).on("check_variations", function (n, r, i) {
var s = !0,
o = !1,
u = !1,
a = {},
f = e(this),
l = f.find(".reset_variations");
f.find(".variations select").each(function () {
e(this).val().length == 0 ? s = !1 : o = !0;
if (r && e(this).attr("name") == r) {
s = !1;
a[e(this).attr("name")] = ""
} else {
value = e(this).val();
a[e(this).attr("name")] = value
}
});
var c = parseInt(f.data("product_id")),
h = f.data("product_variations");
h || (h = t.product_variations[c]);
h || (h = t.product_variations);
h || (h = t["product_variations_" + c]);
var p = e.fn.wc_variation_form.find_matching_variations(h, a);
if (s) {
var d = p.pop();
if (d) {
f.find("input[name=variation_id]").val(d.variation_id).change();
f.trigger("found_variation", [d])
} else {
f.find(".variations select").val("");
i || f.trigger("reset_image");
alert(woocommerce_params.i18n_no_matching_variations_text)
}
} else {
f.trigger("update_variation_values", [p]);
i || f.trigger("reset_image");
r || f.find(".single_variation_wrap").slideUp("200")
}
o ? l.css("visibility") == "hidden" && l.css("visibility", "visible").hide().fadeIn() : l.css("visibility", "hidden")
}).on("reset_image", function (t) {
var n = e(this).closest(".product"),
r = n.find("div.images img:eq(0)"),
i = n.find("div.images a.zoom:eq(0)"),
s = r.attr("data-o_src"),
o = r.attr("data-o_title"),
u = i.attr("data-o_href");
s && r.attr("src", s);
u && i.attr("href", u);
if (o) {
r.attr("alt", o).attr("title", o);
i.attr("title", o)
}
}).on("update_variation_values", function (t, n) {
$variation_form = e(this).closest("form.variations_form");
$variation_form.find(".variations select").each(function (t, r) {
current_attr_select = e(r);
current_attr_select.data("attribute_options") || current_attr_select.data("attribute_options", current_attr_select.find("option:gt(0)").get());
current_attr_select.find("option:gt(0)").remove();
current_attr_select.append(current_attr_select.data("attribute_options"));
current_attr_select.find("option:gt(0)").removeClass("active");
var i = current_attr_select.attr("name");

for (num in n)
if (typeof n[num] != "undefined") {
var s = n[num].attributes;
for (attr_name in s) {
var o = s[attr_name];
if (attr_name == i) if (o) {
o = e("<div/>").html(o).text();
o = o.replace(/'/g, "\\'");
o = o.replace(/"/g, '\\"');
current_attr_select.find('option[value="' + o + '"]').addClass("active")
} else current_attr_select.find("option:gt(0)").addClass("active")
}
}
current_attr_select.find("option:gt(0):not(.active)").remove()
});
$variation_form.trigger("woocommerce_update_variation_values")
}).on("found_variation", function (t, n) {
var r = e(this),
i = e(this).closest(".product"),
s = i.find("div.images img:eq(0)"),
o = i.find("div.images a.zoom:eq(0)"),
u = s.attr("data-o_src"),
a = s.attr("data-o_title"),
f = o.attr("data-o_href"),
l = n.image_src,
c = n.image_link,
h = n.image_title;
r.find(".variations_button").show();
r.find(".single_variation").html(n.price_html + n.availability_html);
if (!u) {
u = s.attr("src") ? s.attr("src") : "";
s.attr("data-o_src", u)
}
if (!f) {
f = o.attr("href") ? o.attr("href") : "";
o.attr("data-o_href", f)
}
if (!a) {
a = s.attr("title") ? s.attr("title") : "";
s.attr("data-o_title", a)
}
if (l && l.length > 1) {
s.attr("src", l).attr("alt", h).attr("title", h);
o.attr("href", c).attr("title", h)
} else {
s.attr("src", u).attr("alt", a).attr("title", a);
o.attr("href", f).attr("title", a)
}
var p = r.find(".single_variation_wrap"),
d = i.find(".product_meta").find(".sku"),
v = i.find(".product_weight"),
m = i.find(".product_dimensions");
d.attr("data-o_sku") || d.attr("data-o_sku", d.text());
v.attr("data-o_weight") || v.attr("data-o_weight", v.text());
m.attr("data-o_dimensions") || m.attr("data-o_dimensions", m.text());
n.sku ? d.text(n.sku) : d.text(d.attr("data-o_sku"));

n.weight ? v.text(n.weight) : v.text(v.attr("data-o_weight"));
n.dimensions ? m.text(n.dimensions) : m.text(m.attr("data-o_dimensions"));
p.find(".quantity").show();
!n.is_in_stock && !n.backorders_allowed && r.find(".variations_button").hide();
n.min_qty ? p.find("input[name=quantity]").attr("min", n.min_qty).val(n.min_qty) : p.find("input[name=quantity]").removeAttr("min");
n.max_qty ? p.find("input[name=quantity]").attr("max", n.max_qty) : p.find("input[name=quantity]").removeAttr("max");
if (n.is_sold_individually == "yes") {
p.find("input[name=quantity]").val("1");
p.find(".quantity").hide()
}
p.slideDown("200").trigger("show_variation", [n])
})

.on('click', '.single_add_to_cart_button', function (event) {

// AJAX add to cart request
var $thisbutton = jQuery(this);

if ($thisbutton.is('.button')) {

var $variation_form = jQuery(this).closest('form.variations_form');
var $product_id = parseInt($variation_form.attr('data-product_id'));

if (!$product_id) return true;

$thisbutton.removeClass('added');
$thisbutton.addClass('loading');
var $vid = parseInt($variation_form.find('input[name=variation_id]').val());
var $quantity = parseInt($variation_form.find('input[name=quantity]').val());
var data = {
action: "woocommerce_add_to_cart",
product_id: $product_id,
variation_id: $vid,
quantity: $quantity,
security: woocommerce_params.add_to_cart_nonce

};
var h;
h = jQuery("#pack-size").attr("name");
data[h] = jQuery(".post-" + $product_id).find('form.cart').find("option:selected").val();

// Trigger event
jQuery('body').trigger('adding_to_cart');

// Ajax action
jQuery.post(woocommerce_params.ajax_url, data, function (data) {
if (!data) return;
var this_page = window.location.toString();
this_page = this_page.replace('add-to-cart', 'added-to-cart');
$thisbutton.removeClass('loading');
if (data.error && data.product_url) {
window.location = data.product_url;
return;
}

if (woocommerce_params.cart_redirect_after_add == "yes") {
window.location = woocommerce_params.cart_url;
return
}
fragments = data.fragments;
cart_hash = data.cart_hash;

// Block fragments class
fragments && jQuery.each(fragments, function (key, value) {
jQuery(key).addClass('updating');
});

jQuery(".shop_table.cart, .updating, .cart_totals").fadeTo("400", "0.6").block({
message: null,
overlayCSS: {
background: "transparent url(" + woocommerce_params.ajax_loader_url + ") no-repeat center",
backgroundSize: "16px 16px",
opacity: .6
}
});

// Changes button classes
$thisbutton.addClass('added');
$thisbutton.parent().find(".add_to_cart").size() == 0 && $thisbutton.after(' <a href="' + woocommerce_params.cart_url + '" title="' + woocommerce_params.i18n_view_cart + '">' + woocommerce_params.i18n_view_cart + "</a>");

// Replace fragments
fragments && jQuery.each(fragments, function (key, value) {
jQuery(key).replaceWith(value)
});

// Unblock
jQuery('.widget_shopping_cart, .updating').stop(true).css('opacity', '1').unblock();

// Cart page elements
jQuery('.shop_table.cart').load(this_page + ' .shop_table.cart:eq(0) > *', function () {

jQuery("div.quantity:not(.buttons_added), td.quantity:not(.buttons_added)").addClass("buttons_added").append('<input type="button" value="+" id="add1" />').prepend('<input type="button" value="-" id="minus1" />');

jQuery('.shop_table.cart').stop(true).css('opacity', '1').unblock();

jQuery('body').trigger('cart_page_refreshed');
});

jQuery('.cart_totals').load(this_page + ' .cart_totals:eq(0) > *', function () {
jQuery('.cart_totals').stop(true).css('opacity', '1').unblock();
});

// Trigger event so themes can refresh other areas
jQuery('body').trigger("added_to_cart", [fragments, cart_hash])

});

return false;

} else {
return true;
}

});

/**
* Initial states and loading
*/
jQuery('form.variations_form .variations select').change();

/**
* Helper functions for variations
*/

// Search for matching variations for given set of attributes

function find_matching_variations(product_variations, settings) {
var matching = [];

for (var i = 0; i < product_variations.length; i++) {
var variation = product_variations[i];
var variation_id = variation.variation_id;

if (variations_match(variation.attributes, settings)) {
matching.push(variation);
}
}
return matching;
}

// Check if two arrays of attributes match

function variations_match(attrs1, attrs2) {
var match = true;
for (attr_name in attrs1) {
var val1 = attrs1[attr_name];
var val2 = attrs2[attr_name];
if (val1 !== undefined && val2 !== undefined && val1.length != 0 && val2.length != 0 && val1 != val2) {
match = false;
}
}
return match;
}

};

e("form.variations_form").wc_variation_form();
e("form.variations_form .variations select").change()
})(jQuery, window, document); // JavaScript Document

<code>

Next Add Some  Code  with Woocommerce-ajax.php  in line 175. Old Code Remove.Repalce With This Code.

</code>

/**
 * AJAX add to cart
 *
 * @access public
 * @return void
 */
 function woocommerce_ajax_add_to_cart() {
 global $woocommerce;
 //check_ajax_referer( 'add-to-cart', 'security' );
 $product_id        = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_POST['product_id'] ) );
 $variation_id     = apply_filters( 'woocommerce_add_to_cart_variation_id', absint( $_POST['variation_id'] ) );
 $quantity          = empty( $_POST['quantity'] ) ? 1 : apply_filters( 'woocommerce_stock_amount', $_POST['quantity'] );
 $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity );
 $variation= apply_filters( 'woocommerce_add_to_cart_variation',  $_POST['attribute_pack-size']  );
 //$attri=$_POST['attri'];
 $att['Pack Size'] = $variation;
 if ($variation_id > 0)
 {
 $woocommerce->cart->add_to_cart( $product_id, $quantity, $variation_id ,$att);

do_action( 'woocommerce_ajax_added_to_cart', $product_id ,$quantity, $variation_id ,$variation);
 // Return fragments
 woocommerce_get_refreshed_fragments();
 if ( get_option( 'woocommerce_cart_redirect_after_add' ) == 'yes' ) {
 woocommerce_add_to_cart_message( $product_id );
 $woocommerce->set_messages();
 }
 }
 else{

if ( $passed_validation && $woocommerce->cart->add_to_cart( $product_id, $quantity) ) {
 do_action( 'woocommerce_ajax_added_to_cart', $product_id );

if ( get_option( 'woocommerce_cart_redirect_after_add' ) == 'yes' ) {
 woocommerce_add_to_cart_message( $product_id );
 $woocommerce->set_messages();
 }

// Return fragments
 woocommerce_get_refreshed_fragments();

} else {

header( 'Content-Type: application/json; charset=utf-8' );

// If there was an error adding to the cart, redirect to the product page to show any errors
 $data = array(
 'error' => true,
 'product_url' => apply_filters( 'woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id )
 );

$woocommerce->set_messages();

echo json_encode( $data );

}
 die();
 }
 }
 add_action('wp_ajax_woocommerce_add_to_cart', 'woocommerce_ajax_add_to_cart');
 add_action('wp_ajax_nopriv_woocommerce_add_to_cart', 'woocommerce_ajax_add_to_cart');

<code>

This code  Working Your Ajax Addtocart. Hope This is Help Full. Any Query Please Ask.

22 comments

  1. Yuvraj Khavad · · Reply

    Thank you for the great post …..,my problem solved…

  2. great work dude…:-)

  3. Ajax works fine (very nice job, congratulations), however – I don’t know it’s just for my case – the variation value isn’t showed in cart; it’s not placed inside it respective div. Product name is showed, and also quantity and price values. But variation isn’t. Does anybody here get the same issue?

  4. Hi achsanos,
    please see woocommerce_ajax_add_to_cart() function in $_POST[‘attribute_pack-size’].u should change ur select box name like $_POST[‘ur slelectbox name’].see ur variation pass into cart.

  5. Hi There. Can’t make it works for me either. I have variations “color”, “size” showing in my cart like this
    $variation_color = $values[“variation”][“pa_color”];
    $variation_size = $values[“variation”][“pa_size”];

    I’ve tried to replace like you told to achsanos

    $variation= apply_filters( ‘woocommerce_add_to_cart_variation’, $_POST[‘pa_color’] );
    $att[‘pa_color’] = $variation;

    but it doesn’t works for me 😦 Please help

    1. hi v,
      you should repalce line 204 to 206 in below code.

      var h;
      h=jQuery(“#pa_color”).attr(“name”); // put ur selectbox id in jq
      data[h]=jQuery(“.post-“+$product_id).find(‘form.cart’).find(“#pa_color”).val();

      var b;
      b=jQuery(“#pa_size”).attr(“name”);
      data[b]=jQuery(“.post-“+$product_id).find(‘form.cart’).find(“#pa_size”).val();

      and you should add this line and remove old line.

      $variation= apply_filters( ‘woocommerce_add_to_cart_variation’, $_POST[‘attribute_color’]);
      $variation1= apply_filters( ‘woocommerce_add_to_cart_variation’, $_POST[‘attribute_size’]);

      //$attri=$_POST[‘attri’];
      $att[‘color’] = $variation;
      $att[‘size’]=$variation1;

      and change line no 199 in woocommerce-ajax.php
      do_action( ‘woocommerce_ajax_added_to_cart’, $product_id ,$quantity, $variation_id ,$variation,$variation1);

      note:if u will post color & size choose ur selectbox name like $_POST[‘ur selectbox name’];

      1. Thank you, I will definitely try today. For now I a biggest issue I have with your script that is works only for various product, i my store I have both a various and simple products, so ajax works only for various now, but didn’t work for simple products.

        Please let me know if this can be easily fixed somehow?

      2. Thanks you so much, and happy holidays!

  6. Works fine for me:

    Attent to replace the “— —” fields suggested below, (without the — chars, obviously ;P)

    @ Add-to-cart-variation.min.js (above) in lines 204 to 206, replace:

    var h;
    h=jQuery("#pack-size").attr("name");
    data[h]=jQuery(".post-"+$product_id).find('form.cart').find("option:selected").val();

    by

    var h;
    h=jQuery("--- the selectbox id (e.g '#size') ---").attr("name");
    data[h]=jQuery(".post-"+$product_id).find('form.cart').find("option:selected").val();

    and,

    @ Woocommerce-ajax.php (above) in lines 16 to 18, replace:

    $variation= apply_filters( 'woocommerce_add_to_cart_variation', $_POST['attribute_pack-size'] );
    //$attri=$_POST['attri'];
    $att['Pack Size'] = $variation;

    by

    $variation= apply_filters( 'woocommerce_add_to_cart_variation', $_POST['--- the selectbox name (would be 'attribute_anything (e.g. attribute_size)') ---'] );
    //$attri=$_POST['attri'];
    $att['--- the variation name (e.g. 'size' or 'color') ---'] = $variation;

    Thanks again everyone.

  7. Thanks a lot for this script worked like a charm. I made few modifications to capture dynamic product variations. Hope this helps someone.

    // JS file

    (not sure line numbers, cus I formatted the above script and it changed lines)
    Instead of
    >>
    var data = {
    action: “woocommerce_add_to_cart”,
    product_id: $product_id,
    variation_id: $vid,
    quantity: $quantity,
    security: woocommerce_params.add_to_cart_nonce

    };
    var h;
    h = jQuery(“#pack-size”).attr(“name”);
    data[h] = jQuery(“.post-” + $product_id).find(‘form.cart’).find(“option:selected”).val();
    <$varV){
    $att[$varF]=$varV;
    }
    }

    Again thanks a lot for the script !

  8. Well that didnt work typing code in here… Here is what I changed http://snipt.org/BPhb4

    1. Mizzinc · · Reply

      This is a great starting point and Ive managed to apply this to Version 2.1.11. However the $_POST[‘variations’] data does not seem to be passing for ‘function add_to_cart’ to process.

  9. Hi Ashanjay – great code. I’ve been looking for something like this. Is there a good way to include your js so that I don’t have to edit the Woocommerce core files? I’d rather store all my mods in a plugin outside of the core.

  10. Thank you for this, looking for something similar for ages, really appreciate it. everything is working perfectly however the once I hit the add to cart button I have a “view cart” message pop up that I am unable to remove.

  11. Oh, there’s no more woocommerce-ajax.php file since 2.1 version; ajax add-to-cart was rewritten. Trying to solve it again…

  12. vividvilla · · Reply

    This is not working with Woocommerce 2.1..Any plans for the update ?

  13. After the woocommerce last update (2.1.2) they have removed the woocommerce-ajax.php. I tried using the .js snippet and the ajax works but doesn’t really include the selected attribute. And yes I did replace the select box ID and attribute name in the .js snippet.

  14. Says “undefined” when i add to cart. Probably because woocommerce-ajax.php is missing?

  15. Hey!

    can you please update your code for newest woocommerce version?

    For example: we don’t have “Woocommerce-ajax.php” file.

  16. sorry i have no time .i definitely solve this problem after some days.

  17. Did anyone ever get this solved in the latest version of Woocommerce? I’m really having some issues with this now… any help would be much appreciated.
    Cheers.

Leave a reply to ashanjay Cancel reply