This question already has answers here:
Run javascript code after ajax add to cart event in Woocommerce
(1 answer)
JS alert on ajax add to cart for specific product category count in Woocommerce
(1 answer)
Closed 4 years ago.
Every time a product is added to the basket by ajax and the mini cart is refreshed I need to be able to run some jQuery. I can't just simply create an even for add to cart because, I run some jQuery that checks if the mini cart has products inside it, but the add to cart even runs before the mini cart has added the products. This means that my if statement becomes false.
What can I do about this apart from creating a timeout in jQuery?
Here is the code I have modified from the current answers;
add_action( 'wp_footer', 'ajax_add_tocart_event' );
function ajax_add_tocart_event() {
?>
<script type="text/javascript">
jQuery( 'body' ).on( 'added_to_cart', function() {
if( $('#mini_wrap .cart_list').length ){
alert('hi');
}
} );
</script>
<?php
}
You can do using following code.
add_action( 'wp_footer', 'ajax_add_tocart_event' );
function ajax_add_tocart_event() {
?>
<script type="text/javascript">
jQuery( 'body' ).on( 'added_to_cart', function( e, fragments, cart_hash, this_button ) {
alert('product added to cart');
} );
</script>
<?php
} ?>
Put this code in functions.php file.
add_action( 'wp_footer', 'trigger_for_ajax_add_to_cart' );
function trigger_for_ajax_add_to_cart() {
?>
<script type="text/javascript">
(function($){
$('body').on( 'added_to_cart', function(){
//do some code
});
})(jQuery);
</script>
<?php
} ?>
Related
How can I hide a specific button, based on the stock status of my product?
The plugin is creating this class:
function wdm_pefree_init() {
// phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
if ( ! class_exists( 'Product_Enquiry_For_Woocommerce', false ) ) {
include_once WDM_PE_PLUGIN_PATH . '/includes/class-product-enquiry-for-woocommerce.php';
}
Product_Enquiry_For_Woocommerce::instance();
}
I only want to display this button the single product page of every product that is in backorder, but I can't get my code to work.
I'm not that great with PHP, so I'm trying to adapt some other code I have on my functions.php file, but without any luck.
Any help would be great, thanks!
I've tried this code:
add_filter('woocommerce_get_availability', 'wcs_custom_get_availability', 1, 2);
function wcs_custom_get_availability($availability, $_product) {
// Remove Enquiry Button
if (!$_product->is_in_stock()) {
remove_action('Product_Enquiry_For_Woocommerce');
}
return $availability;
}
I also see that the css class for the button is .pe-show-enq-modal, but I can't do a conditional "visibility: hidden" that only works for backorder products.
What you are looking for is this:
add_action( 'woocommerce_single_product_summary', 'remove_enquiry_button_if_out_of_stock', 30 );
function remove_enquiry_button_if_out_of_stock() {
global $product;
if ( ! $product->is_in_stock() ) {
remove_action( 'woocommerce_single_product_summary', array( Product_Enquiry_For_Woocommerce::instance(), 'enquiry_button' ), 25 );
}
}
Or Via CSS :
.product.out-of-stock .pe-show-enq-modal {
display: none;
}
The only way I got this (kinda) working was by using this JS:
function remove_enquiry() {
?>
<script type="text/javascript">
(function($){
$(document).ready(function(){
if($(".in-stock").length)
$(".pe-show-enq-modal").hide();
});
})(jQuery);
</script>
<?php
}
add_action('wp_head', 'remove_enquiry');
You can see it here.
But if you notice, it has a delay executing the JS, because when the page loads, the button still shows up for a brief moment (otherwise it seems to be working ok).
I have searched and searched on the forum but no right code to do the following job. The code below auto updates changes in quantity on the shopping cart. Yet, it is not working on the Off canvas flyout cart. See
How do I change the code so that it also works on that cart?
add_action( 'wp_footer', 'ava_cart_refresh_update_qty', 9999 );
function ava_cart_refresh_update_qty() {
if (is_cart()) {
?>
<script type="text/javascript">
(function($) {
var triggerUpdate = function() {
$('.woocommerce-cart-form .quantity').on('click', '.qty, .plus, .minus', function(){
console.log('test');
$("button[name='update_cart']").trigger("click");
});
}
triggerUpdate();
$(document).ajaxComplete(function() {
triggerUpdate();
});
})(jQuery);
</script>
<?php
}
}
I'm trying to get woocommerce cart content in ajax callback function but it returns empty.
I've also tried using global $woocommerce variable that also returns the same result. I'm trying to get the cart content and convert all product to autoship feature. I'm using wooautoship plugin for that. however, main query is, how to get the cart details in ajax callback.
My Code is as follow:
add_action('wp_footer', 'woo_cart_autoship_js', 99);
function woo_cart_autoship_js(){
?>
<script type="text/javascript">
(function($){
$(document).on('click', '#convert-to-autoship', function(e){
e.preventDefault();
$.post( "<?php echo admin_url('admin-ajax.php'); ?>", { action: "convert-to-autoship" })
.done(function( data ) {
alert( "Data Loaded: " + data );
});
});
})(jQuery);
</script>
<?php
}
add_action( 'wp_ajax_convert-to-autoship', 'convert_to_autoship', 99 );
add_action( 'wp_ajax_nopriv_convert-to-autoship', 'convert_to_autoship', 99 );
function convert_to_autoship(){
print_r(WC()->cart->get_cart());
wp_die();
}
I'm trying to show/hide some elements from my checkout page, based on the chosen shipping method. The page elements I'm trying to show/hide come from another plugin, so I tried to change the display properties for them. I've looked to many thread like:
Show or hide checkout fields based on shipping method in Woocommerce 3
But it's for checkout fields, and I'm not sure how to do it for page elements.
Then based on this answer thread Here's my code so far:
add_action( 'wp_footer', 'conditionally_hidding_order_delivery_date' );
function conditionally_hidding_order_delivery_date(){
// Only on checkout page
if( ! is_checkout() ) return;
// HERE your shipping methods rate ID "Home delivery"
$home_delivery = 'distance_rate_shipping';
?>
<script>
jQuery(function($){
// Choosen shipping method selectors slug
var shipMethod = 'input[name^="shipping_method"]',
shipMethodChecked = shipMethod+':checked';
// Function that shows or hide imput select fields
function showHide( actionToDo='show', selector='' ){
if( actionToDo == 'show' )
$(selector).show( 200, function(){
$(this).addClass("validate-required");
});
else
$(selector).hide( 200, function(){
$(this).removeClass("validate-required");
});
$(selector).removeClass("woocommerce-validated");
$(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
}
// Initialising: Hide if choosen shipping method is "Home delivery"
if( $(shipMethodChecked).val() != '<?php echo $home_delivery; ?>' ) {
showHide('hide','#e_deliverydate_field' );
showHide('hide','#time_slot_field' );
}
// Live event (When shipping method is changed)
$( 'form.checkout' ).on( 'change', shipMethod, function() {
if( $(shipMethodChecked).val() == '<?php echo $home_delivery; ?>' ) {
showHide('show','#e_deliverydate_field' );
showHide('show','#time_slot_field' );
}
else {
showHide('hide','#e_deliverydate_field' );
showHide('hide','#time_slot_field' );
}
});
});
</script>
<?php
}
But it's not working completely (the initializing function is not working.)
Any help is very much appreciated.
Additional edit:
<p class="form-row form-row-wide validate-required" id="e_deliverydate_field" data-priority="" style="display: block;"><label for="e_deliverydate" class="">Date<abbr class="required" title="required">*</abbr></label><span class="woocommerce-input-wrapper"><input class="input-text hasDatepicker" name="e_deliverydate" id="e_deliverydate" placeholder="Choose a Date" value="" style="cursor:text !important;" type="text"></span></p>
My objective is to change the display properties for p element from block to none, and vice versa.
The needed code is something much more simple, than the one used in my other answers, but you need to be sure that the targeted chosen shipping method is 'distance_rate_shipping' as I can't test it.
For initialization problem, see the solution exposed at the end of my answer.
The simplified needed code:
// Embedded jQuery script
add_action( 'wp_footer', 'checkout_delivery_date_script' );
function checkout_delivery_date_script() {
// Only checkout page
if( ! ( is_checkout() && ! is_wc_endpoint_url() ) ) return;
?>
<script type="text/javascript">
jQuery( function($){
var a = 'input[name^="shipping_method"]', b = a+':checked',
c = 'distance_rate_shipping',
d = '#e_deliverydate_field,#time_slot_field';
// Utility function that show or hide the delivery date
function showHideDeliveryDate(){
if( $(b).val() == c )
$(d).show();
else
$(d).hide('fast');
console.log('Chosen shipping method: '+$(b).val()); // <== Just for testing (to be removed)
}
// 1. On start
showHideDeliveryDate();
// 2. On live event "change" of chosen shipping method
$('form.checkout').on('change', a, function(){
showHideDeliveryDate();
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or theme). It should work.
The initialization problem:
It's certainly because the plugin you are using that generates the delivery date output is delayed after initialization
The solution can be to add some delay on initialization execution.
So should try to replace this:
// 1. On start
showHideDeliveryDate();
By the following in my code (adjusting the execution delay to something higher or lower than 500):
// 1. On start
setTimeout(function(){
showHideDeliveryDate();
}, 500);
I want to auto update the cart when quantity is changed. I got this working code in functions.php, but it's only working for the first click. How to adjust it so it's working for every click?
add_action( 'wp_footer', 'cart_update_qty_script' );
function cart_update_qty_script() {
if (is_cart()) :
?>
<script>
jQuery('div.woocommerce').on('click', '.quantity .button', function(){
jQuery("[name='update_cart']").trigger("click"); });
</script>
<?php
endif;
}
try it like this..
add_action( 'wp_footer', 'cart_update_qty_script' );
function cart_update_qty_script() {
if (is_cart()) :
?>
<script>
jQuery( 'div.woocommerce' ).on( 'change', '.qty', function () {
jQuery( "[name='update_cart']" ).trigger( "click" );
} );
</script>
<?php
endif;
}
I it's because the html is being replaced, div.woocommerce click event is no longer there... if you attached it to body, it might work...
The reason that is happening is because your dom is refreshed with the Ajax and events are flushed.
What you need to do is listen to the event 'updated_cart_totals' which will tell you that dom is updated and after that reactivate your listeners.
function quantity_upd() {
$(".woocommerce-cart-form").on("change", ".qty", function() {
$("[name='update_cart']").removeAttr('disabled');
$("[name='update_cart']").trigger("click");
});
}
$( document ).on( 'updated_cart_totals', function() {
quantity_upd();
}
Please adjust it for your theme and HTML, it can vary
The reason it only works on the first click is because everytime you update the form, it refreshes itself. So instead of doing:
jQuery('div.woocommerce').on('click', '.quantity .button', function() {
You need to switch div.woocommerce to document:
jQuery('document').on('click', '.quantity .button', function() {
You can use plugin like below.
https://wordpress.org/plugins/woo-update-cart-on-quantity-change/
Also this plugin is working for you.
https://wordpress.org/plugins/woocommerce-ajax-cart/
Please use plugin for your safe side because plugin works in every wordpress version and woocommerce version.
OR
You can try custom code with minor modifications like below.
add_action( 'wp_footer', 'cart_update_qty_script' );
function cart_update_qty_script() {
if (is_cart()) :
?>
<script type="text/javascript">
jQuery(document).on("click", "div.woocommerce .quantity .button", function(e) {
jQuery("[name='update_cart']").trigger("click");
});
OR
jQuery("body").on("click", "div.woocommerce .quantity .button", function(e) {
jQuery("[name='update_cart']").trigger("click");
});
</script>
<?php
endif;
}
As I don't know your HTML structure so I built a sample jQuery which is working on storefront theme.
Here is a sample code.
add_action( 'wp_footer', 'cart_update_qty_script' );
function cart_update_qty_script() {
if (is_cart()) :
?>
<script>
jQuery('div.woocommerce').on('keyup', '.quantity .qty', function(){
//console.log('clicked');
jQuery("[name='update_cart']").trigger("click"); });
</script>
<?php
endif;
}
Rather than try to trigger the click, how about removing the "disabled" attribute from the Update Cart button so the user can click it. The cart page already works this way where when the quantity is changed on an item, the Update Cart button becomes clickable.
add_action( 'wp_footer', 'cart_update_qty_script' );
function cart_update_qty_script() {
if (is_cart()) :
?>
<script>
jQuery('body').on('click', 'div.woocommerce .quantity .button', function(){
jQuery("[name='update_cart']").prop("disabled", false);
});
</script>
<?php
endif;
}
The update button is actually disabled when the page loads, so you need basically to enable it, right before triggering the click event.
Use this code:
add_action( 'wp_footer', 'cart_update_qty_script' );
function cart_update_qty_script() {
if (is_cart()) :
?>
<script>
jQuery('div.woocommerce').on('change', '.qty', function(){
jQuery("[name='update_cart']").removeAttr('disabled');
jQuery("[name='update_cart']").trigger("click");
});
</script>
<?php
endif;
}
Copy this code to functions:
function bbloomer_cart_refresh_update_qty() {
if (is_cart()) {
?>
<script>
jQuery('div.woocommerce').on('change', '.qty', function(){
jQuery("[name='update_cart']").prop("disabled", false);
jQuery("[name='update_cart']").trigger("click");
});
</script>
<?php
}
}
End this to style:
button[name='update_cart'] {
display: none !important;
}