I've removed the standard "Added to cart" message given by WooCommerce. I have then added the code below which is using the Sweet Alert. The idea is to remove all "added to cart" messages and to only use the sweet alert.
Based on "JS alert on ajax add to cart for specific product category count in Woocommerce" answer code by #LoicTheAztec, my code works for the first product added, but not for the following ones. So it works fine when the cart is empty and when adding the first product.
Here's the code I'm using:
// remove add to cart woocommerce message
add_filter('wc_add_to_cart_message_html', '__return_null');
// Wordpress Ajax PHP
add_action('wp_ajax_nopriv_checking_items', 'atc_sweet_message');
add_action('wp_ajax_checking_items', 'atc_sweet_message');
function atc_sweet_message() {
if (isset($_POST['id']) && $_POST['id'] > 0) {
$count = 0;
$product_id = $_POST['id'];
foreach(WC()-> cart-> get_cart() as $cart_item) {
$count += $cart_item['quantity'];
}
}
echo $count;
die();
}
// jQuery Ajax
add_action('wp_footer', 'item_count_check');
function item_count_check() {
if (is_checkout())
return;
?>
<script src="https://unpkg.com/sweetalert2#7.20.1/dist/sweetalert2.all.js"></script>
<script type="text/javascript">
jQuery( function($) {
if ( typeof wc_add_to_cart_params === 'undefined' )
return false;
$(document.body).on( 'added_to_cart', function( event, fragments, cart_hash, $button ) {
$.ajax({
type: 'POST',
url: wc_add_to_cart_params.ajax_url,
data: {
'action': 'checking_items',
'id' : $button.data( 'product_id' )
},
success: function (response) {
if(response == 1 ){
const toast = swal.mixin({
toast: true,
showConfirmButton: false,
timer: 3000
});
toast({
type: 'success',
title: 'Product Added To Cart'
})
}
}
});
});
});
</script>
<?php
}
I tried removing if(response == 1 ){ without success. Any input on this is appreciated.
There was little mistakes in your code on the function for Wordpress Ajax PHP. Try the following:
// remove add to cart woocommerce message
add_filter('wc_add_to_cart_message_html', '__return_null');
// Wordpress Ajax PHP
add_action('wp_ajax_nopriv_item_added', 'addedtocart_sweet_message');
add_action('wp_ajax_item_added', 'addedtocart_sweet_message');
function addedtocart_sweet_message() {
echo isset($_POST['id']) && $_POST['id'] > 0 ? (int) esc_attr($_POST['id']) : false;
die();
}
// jQuery Ajax
add_action('wp_footer', 'item_count_check');
function item_count_check() {
if (is_checkout())
return;
?>
<script src="https://unpkg.com/sweetalert2#7.20.1/dist/sweetalert2.all.js"></script>
<script type="text/javascript">
jQuery( function($) {
if ( typeof wc_add_to_cart_params === 'undefined' )
return false;
$(document.body).on( 'added_to_cart', function( event, fragments, cart_hash, $button ) {
var $pid = $button.data('product_id');
$.ajax({
type: 'POST',
url: wc_add_to_cart_params.ajax_url,
data: {
'action': 'item_added',
'id' : $pid
},
success: function (response) {
if(response == $pid){
const toast = swal.mixin({
toast: true,
showConfirmButton: false,
timer: 3000
});
toast({
type: 'success',
title: 'Product Added To Cart'
})
}
}
});
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
It works now for all ajax added to cart items (and not just the first one).
Related
I made adding multiple items with quantity to the cart using AJAX.
After adding a product, the mini cart isn't updated, but WC_AJAX :: get_refreshed_fragments () is called in function.php and I have a hook to update the cart woocommerce_add_to_cart_fragments.
How to force to update the mini cart or what needs to be fixed in this code.
JS
productsToAdd // array with id and quantity
$(document).on('click', '.buy-tovar', function (e) {
e.preventDefault();
productsToAdd.forEach(function(item){
var data = {
action: 'woocommerce_ajax_add_to_cart',
product_id: item['id'],
quantity: item['quantity']
};
$.ajax({
type: 'post',
url: wc_add_to_cart_params.ajax_url,
data: data,
async: false,
success: function (response) {
$('.buy-tovar').addClass("added");
},
});
});
});
PHP
add_filter( 'woocommerce_add_to_cart_fragments', 'woocommerce_header_add_to_cart_fragment' );
function woocommerce_header_add_to_cart_fragment( $fragments ) {
ob_start();
?>
<a href="<?php echo wc_get_cart_url(); ?>" class="cart">
<div class="img-block">
<img src="<?php echo get_template_directory_uri();?>/image/cart.png" alt="">
<span><?php echo count( WC()->cart->get_cart()); ?></span>
</div>
</a>
<?php
$fragments['a.cart'] = ob_get_clean();
return $fragments;
}
//AJAX
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 = absint($_POST['quantity']);
$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) && '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();
}
I found a solution i added the line in my JS:
$(document.body).trigger('wc_fragment_refresh');
Full code JS
document).on('click', '.buy-tovar', function (e) {
e.preventDefault();
productsToAdd.forEach(function(item){
var data = {
action: 'woocommerce_ajax_add_to_cart',
product_id: item['id'],
quantity: item['quantity']
};
$.ajax({
type: 'post',
url: wc_add_to_cart_params.ajax_url,
data: data,
async: false,
success: function (response) {
$('.buy-tovar').addClass("added");
$(document.body).trigger('wc_fragment_refresh');
},
});
});
});
I am trying to create a function which replaces the head image with the variation image clicked. I did make a function but I am getting an error in the console. Here is the function:
// add this to functions.php
add_action('woocommerce_after_single_product','custom_woocommerce_additional_variation_images');
function custom_woocommerce_additional_variation_images(){
?>
<script type="text/javascript">
(function($) {
$(window).load(function(){
$( "a.swatch-anchor").click(function() {
//console.log(variation);
var atts = $(this).parent().attr('data-value');
var product_variations = $('form.variations_form').data('product_variations');
console.log(product_variations);
var variation_id = '';
for ( var i = 0; i < product_variations.length; i++ ) {
var variation = product_variations[i];
if( product_variations[i].attributes.attribute_pa_kleur == atts){
variation_id = product_variations[i].variation_id;
}
}
console.log(variation_id);
var data = {
security: wc_additional_variation_images_local.ajaxImageSwapNonce,
variation_id: variation_id,
post_id: $( 'form.variations_form' ).data( 'product_id' )
};
$.ajax({
type: "POST",
url: $.wc_additional_variation_images_frontend.getAjaxURL( 'get_images' ),
data: data,
cache: false,
success: function(data,response){
data = $.parseJSON(data);
console.log(data['main_images']);
$('.woocommerce-product-gallery').replaceWith(data['main_images']);
},
});
});
})
})(jQuery);
</script>
<?php
}
add_filter( 'wc_additional_variation_images_custom_swap', '__return_true');
add_filter( 'wc_additional_variation_images_custom_reset_swap', '__return_true' );
add_filter( 'wc_additional_variation_images_custom_original_swap', '__return_true' );
add_filter( 'wc_additional_variation_images_get_first_image', '__return_true' );
The console is returning: Uncaught ReferenceError: wc_additional_variation_images_local is not defined
Here is the website which I am using: https://www.dev.ruitershopboxmeer.nl/product/kingsland-zadeldekje-carin/
Does anyone know what I am doing wrong?
I'm trying to update my checkout cart's shipping with AJAX...
I've got the action in functions.php
function jwd_update_shipping()
{
WC()->cart->calculate_shipping();
echo "hi";
die();
}
add_action('jwd_update_shipping_callback', 'jwd_update_shipping');
Then in js I call it, like so
jQuery.ajax({
type: "POST",
url: 'MYSITE.com/wp-admin/admin-ajax.php',
data: ({
action: "jwd_update_shipping"
}),
success: function(response) {
console.log("got this: " + response);
if (response.type == "success") {
alert("here");
jQuery('body').trigger('update_checkout');
} else {
alert("fail");
}
},
error: function(request, status, error) {
alert(request.responseText);
}
});
I just get a 0 alerted back at me, which suggests that the AJAX call failed.
First your ajax request is not reaching the related php function… Also you need more things to refresh checkout… Try the following instead:
// The jQuery script that send the Ajax request
add_action( 'wp_footer', 'refresh_shipping_js' );
function refresh_shipping_js() {
// Only on checkout
if( is_checkout() && ! is_wc_endpoint_url() ):
?>
<script type="text/javascript">
jQuery( function($){
if (typeof wc_checkout_params === 'undefined')
return false;
var refresh = 'yes';
$.ajax({
type: "POST",
url: wc_checkout_params.ajax_url,
data: ({
'action': 'updating_shipping',
'refresh_shipping': refresh,
}),
success: function(response) {
if( response === '1' ) {
$(document.body).trigger('update_checkout');
console.log('Success: '+response); // For testing (to be removed)
} else {
console.log('Failled: '+response); // For testing (to be removed)
}
},
error:function(error) {
console.log('Error: '+error); // For testing (to be removed)
}
});
});
</script>
<?php
endif;
}
// function that gets the Ajax data
add_action( 'wp_ajax_updating_shipping', 'updating_shipping' );
add_action( 'wp_ajax_nopriv_updating_shipping', 'updating_shipping' );
function updating_shipping() {
if ( isset($_POST['refresh_shipping']) && $_POST['refresh_shipping'] === 'yes' ){
WC()->session->set('refresh_shipping', '1' );
} else {
WC()->session->set('refresh_shipping', '0' );
}
echo WC()->session->get('refresh_shipping');
die(); // Alway at the end (to avoid server error 500)
}
// Function that refresh session shipping methods data
add_action( 'woocommerce_checkout_update_order_review', 'refresh_shipping_methods', 10, 1 );
function refresh_shipping_methods( $post_data ){
if ( WC()->session->get('refresh_shipping' ) === '1' ) {
foreach ( WC()->cart->get_shipping_packages() as $package_key => $package ){
WC()->session->set( 'shipping_for_package_' . $package_key, false );
}
WC()->cart->calculate_shipping();
}
}
I need to calculate the cost of shipping without reloading the cart page. I'm trying to do this via AJAX but I did not succeed.
I started the code below and could not continue
var $warp_fragment_refresh = {
url: wc_cart_fragments_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_refreshed_fragments' ),
type: 'POST',
success: function( data ) {
if ( data && data.fragments ) {
jQuery.each(data.fragments, function(key, value){
jQuery(key).replaceWith(value);
});
jQuery( document.body ).trigger( 'wc_fragments_refreshed' );
}
}
};
jQuery( function( $ ){
$('form.woocommerce-cart-form').on('submit', function (e)
{
e.preventDefault();
$(".btn-calc-ship").addClass("loading");
var ship_calc = window.location,
form = $(this);
$(".btn-calc-shipp").removeClass("loading");
});
});
I'm looking for a way to update order review (shipping price) when client change country on checkout page.
I want to use jQuery. but wc_checkout_params wc_checkout_params is deprecated.
function custom_checkbox_checker() {
if (is_checkout()) {
wp_enqueue_script('jquery');
?>
<script type="text/javascript">
jQuery(document).ready(function (e) {
var $ = jQuery;
// wc_checkout_params is required to continue, ensure the object exists
if (typeof wc_checkout_params === 'undefined')
return false;
var updateTimer,
dirtyInput = false,
xhr;
function update_shipping(billingstate, billingcountry) {
if (xhr)
xhr.abort();
$('#order_methods, #order_review').block({message: null, overlayCSS: {background: '#fff url(' + wc_checkout_params.ajax_loader_url + ') no-repeat center', backgroundSize: '16px 16px', opacity: 0.6}});
var data = {
action: 'woocommerce_update_order_review',
security: wc_checkout_params.update_order_review_nonce,
billing_state: billingstate,
billing_country: billingcountry,
post_data: $('form.checkout').serialize()
};
xhr = $.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: data,
success: function (response) {
var order_output = $(response);
$('#order_review').html(response['fragments']['.woocommerce-checkout-review-order-table'] + response['fragments']['.woocommerce-checkout-payment']);
$('body').trigger('updated_checkout');
},
error: function (code) {
console.log('ERROR');
}
});
}
jQuery('.state_select').change(function (e, params) {
update_shipping(jQuery(this).val(), jQuery('#billing_country').val());
});
});
</script>
<?php
}
}
add_action('wp_footer', 'custom_checkbox_checker', 50);
any clue?
All solutions related to AJAX for WC like this are useless since wc_checkout_params removed on 3.x version.
Nothing useful found in woocommerce documentations.
nothing in stack overflow!
wondering why no one answered questions like this for 2 years+
Normally woocommerce do it itself, and nothing is needed…
But you can try the following instead, that should work in Woocommerce 3+ versions:
add_action('wp_footer', 'billing_country_update_checkout', 50);
function billing_country_update_checkout() {
if ( ! is_checkout() ) return;
?>
<script type="text/javascript">
jQuery(function($){
$('select#billing_country, select#shipping_country').on( 'change', function (){
var t = { updateTimer: !1, dirtyInput: !1,
reset_update_checkout_timer: function() {
clearTimeout(t.updateTimer)
},
trigger_update_checkout: function() {
t.reset_update_checkout_timer(), t.dirtyInput = !1,
$(document.body).trigger("update_checkout")
}
};
$(document.body).trigger('update_checkout');
console.log('Event: update_checkout');
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.