wocommerce calculate shipping not being called - php

Hi have a wocommerce plugin, While changing the payment method. the cost for shipping my function calculate_shipping is not being called. and therefore shipping methods are not updating with appropriate cost
here are some samples from my code.
public function __construct() {
add_action('woocommerce_review_order_before_payment', array($this, 'update_shipping_charges'), 1);
}
public function update_shipping_charges() {
// jQuery code
?>
<script type="text/javascript">
(function ($) {
$('form.checkout').on('change', 'input[name^="payment_method"]', function () {
// Set the select value in a variable
$('body').trigger('update_checkout');
//testing
$('body').on('updated_checkout', function() {
console.log('updated');
});
});
})(jQuery);
</script>
<?php
}

Try wrapping everything inside the init hook. Maybe the code gets executed too early:
public function __construct() {
add_action( 'init', [ $this, 'init_action' ] );
}
public function init_action(): void {
add_action( 'woocommerce_review_order_before_payment', [ $this, 'update_shipping_charges' ], 1 );
}
public function update_shipping_charges(): void {
// jQuery code
?>
<script type="text/javascript">
(function ( $ ) {
$( 'form.checkout' ).on( 'change', 'input[name^="payment_method"]', function () {
// Set the select value in a variable
let body = $( 'body' );
body.trigger( 'update_checkout' );
//testing
body.on( 'updated_checkout', function () {
console.log( 'updated' );
} );
} );
})( jQuery );
</script>
<?php
}
You could try multiple hooks if init don't works:
woocommerce_loaded
woocommerce_init
plugins_loaded <- I use this one in my plugins for example

Please try the following (Add to functions.php or via Code Snippets plugin)
function kia_checkout_on_payment_change() {
wp_add_inline_script( 'wc-checkout', '
jQuery( document.body ).on( "payment_method_selected", function() {
jQuery( "form.checkout" ).trigger( "update_checkout", { update_shipping_method: true } );
console.log("payment selected");
} );
'
);
}
add_action( 'wp_enqueue_scripts', 'kia_checkout_on_payment_change' );
A couple notes....
We're adding the script right after the wc-checkout script is loaded.
We're listening for the WooCommerce checkout script's payment_method_selected (but yes, it's a core Woo trigger in the checkout) trigger which should fire when the payment method is changed
We're explicitly passing some arguments to the update_checkout function.
Don't have any shipping methods set up locally to test it properly, but I hope it points you in the right direction.

Related

Clear WooCommerce cart on Currency Switcher change

I'm using the currency switcher WordPress plugin to change currencies on my website, I want the cart to be cleared once I change the currency. I've been trying for some time now, but can't figure out why it isn't working.
This is my source code in the theme functions.php file
function currency_change_action_callback() {
global $woocommerce;
$url_data=$_POST['url_data'];
$woocommerce->cart->empty_cart();
echo $url_data;
die();
}
add_action( 'wp_ajax_currency_change_action', 'currency_change_action_callback' );
add_action( 'wp_ajax_nopriv_currency_change_action', 'currency_change_action_callback' );
I've also tried creating a javascript file and calling it to my functions.php file. here are my source codes
app.js
$('#alg_currency_select').on('change', function () {
function Clearcart(d){
jQuery.post(
"http://localhost/epay/wp-admin/admin-ajax.php",
//ajaxurl,
{
"action": "clearcart",
"data": d.getAttribute("data-product")
},
function(){
window.location = d.getAttribute("data-href");
}
);
})};
functions.php
function load_javascript() {
wp_register_script('custom', get_template_directory_uri().'/app.js', 'jquery', 1, true);
wp_enqueue_script('custom');
}
add_action('wp_enqueue_scripts', 'load_javascript');
would greatly appreciate it if someone can help me solve the issue of why my cart isn't clearing. thanks.
There are some mistakes in your code and unnecessary things.
In the code below, the jQuery code is now located in a php function and enqueued in WordPress using the WooCommerce wc_enqueue_js() function.
// The jQuery Ajax enqueued code
add_action('template_redirect', 'currency_change_trigger_clear_cart_js' );
function currency_change_trigger_clear_cart_js() {
wc_enqueue_js( "jQuery( function($){
$(document.body).on('change', '#alg_currency_select', function() {
$.ajax({
url: '" . admin_url('/admin-ajax.php') . "',
type: 'POST',
data: {
'action': 'currency_change_clear_cart'
},
success: function(response) {
if( response == 'cleared' ) {
$(document.body).trigger('wc_fragment_refresh'); // Refresh cart
}
// console.log(response);
}
});
});
});" );
}
// Php AJAX receiver: Empty cart
add_action( 'wp_ajax_currency_change_clear_cart', 'currency_change_clear_cart' );
add_action( 'wp_ajax_nopriv_currency_change_clear_cart', 'currency_change_clear_cart' );
function currency_change_clear_cart() {
if( count(WC()->cart->get_cart()) > 0 ) {
WC()->cart->empty_cart();
echo 'cleared';
}
die();
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.

Heartbeat refresh browser when page is updated

I am trying to automatically force a browser refresh on a specific page when the page is beeing updated in the backend. I'm trying to achieve by using the Heartbeat API.
I look through all Heartbeat examples i could find but I can't grasp the whole concept of it.
All I am able to do is console.log a string every 15 sec on this specific page.
What I have so far:
https://pastebin.com/ELQ9uJAw
<?PHP
//embed heartbeat api
function heartbeat_test_enqueue($hook_suffix) {
if ( is_page(1105)) {
// Make sure the JS part of the Heartbeat API is loaded.
wp_enqueue_script('heartbeat');
// Output the test JS in footer.
add_action( 'print_footer_scripts', 'heartbeat_test_js', 20 );
//Add filter to receive hook, and specify we need 2 parameters.
add_filter( 'heartbeat_received', 'dw_receive_heartbeat', 10, 2 );
}
}
add_action( 'wp_enqueue_scripts', 'heartbeat_test_enqueue' );
//clientside
function heartbeat_test_js() {
?>
<script>
jQuery(document).ready( function($) {
// Hook into the heartbeat-send
jQuery( document ).on( 'heartbeat-send', function( e, data ) {
//
});
// Listen for the custom event "heartbeat-tick" on $(document). This fire's once every minute that the page is open.
jQuery(document).on( 'heartbeat-tick', function(e, data) {
console.log("tick");
});
});
</script>
<?php
}
//change heartbeat interval time
function m_heartbeat_settings( $settings ) {
$settings['interval'] = 15; //only values between 15 and 60 seconds allowed
return $settings;
}
add_filter( 'heartbeat_settings', 'm_heartbeat_settings' );
//heartbeat api end
?>
I wanted to use the "post_updated" hook to check if the "post_date" has changed. But I dont get how I can use this hook in combination with the Heartbeat API.
Thanks in advance, I am really lost here.
Finally found a way.
//embed heartbeat api
function heartbeat_test_enqueue($hook_suffix) {
if ( is_page(1105)) {
// Make sure the JS part of the Heartbeat API is loaded.
wp_enqueue_script('heartbeat');
// Output the test JS in admin footer.
add_action( 'print_footer_scripts', 'heartbeat_update', 20 );
//Add filter to receive hook, and specify we need 2 parameters.
add_filter( 'heartbeat_received', 'dw_receive_heartbeat', 10, 2 );
}
}
add_action( 'wp_enqueue_scripts', 'heartbeat_test_enqueue' );
//write timestamp file
function write_timestamp($post_ID, $post_after, $post_before){
if ( $post_ID == 1105 ) {
$myfile = fopen("URLtoTextFile/tv.txt", "w") or die("Unable to open file!");
$txt = $post_after->post_modified;
fwrite($myfile, $txt);
fclose($myfile);
}
}
add_action( 'post_updated', 'write_timestamp', 10, 3 );
//clientside
function heartbeat_update() {
?>
<script>
jQuery(document).ready( function($) {
var current_timestamp;
jQuery.ajax({
url: "/tv.txt",
cache: false,
success: function (data){
current_timestamp = data;
}});
// Listen for the custom event "heartbeat-tick" on $(document). This fire's once every 15s that the page is open.
jQuery(document).on( 'heartbeat-tick', function(e, data) {
jQuery.ajax({
url: "/tv.txt",
cache: false,
success: function (data){
if (data != current_timestamp) {
jQuery('body').fadeOut(1000, function(){
location.reload(true);
});
}
}
});
});
});
</script>
<?php
}
//change heartbeat interval time
function m_heartbeat_settings( $settings ) {
$settings['interval'] = 15; //only values between 15 and 60 seconds allowed
return $settings;
}
add_filter( 'heartbeat_settings', 'm_heartbeat_settings' );
//heartbeat api end
What I am doing:
I write the modification date of the page in a .txt file and after every update i hook into the post_updated hook and check if the date changed. and then i just refresh the browser with jQuery.

Auto update cart on click in WooCommerce

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;
}

Passing ajax variable to more than one wordpress plugin function

I'm trying to get information from the front end of my Wordpress site, I used ajax to do that, it gave me the ability to use the data in one of my plugin functions, but in my case I want to use this data in more than just one function.
add_action( 'admin_footer', 'my_action_javascript' );
function my_action_javascript() { ?>
<script type="text/javascript" >
jQuery(document).ready(function($) {
var data = {
'action': 'my_action',
'whatever': 1234
};
jQuery.post(ajaxurl, data);
});
</script> <?php
}
add_action( 'wp_ajax_my_action', 'my_action' );
function my_action() {
$whatever = $_POST['whatever'];
}
In other words I need to use $_POST['whatever'] in other functions in my plugin not only my_action() function, I tried using PHP global variables like so , but it didn't workout:
$whatever;
function my_action(){
global $whatever = $_POST['whatever'];
}
function my_other_function(){
global $whatever;
if(isset($whatever)){
echo $whatever;
}
}

How to get wp_ajax to work with jQuery $.post

Straight from WP Codex: http://codex.wordpress.org/AJAX_in_Plugins
I have this in my functions.php:
add_action( 'admin_footer', 'my_action_javascript' );
function my_action_javascript() {
?>
<script type="text/javascript" >
jQuery(document).ready(function($) {
var data = {
'action': 'my_action',
'whatever': 1234
};
// since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
$.post(ajaxurl, data, function(response) {
alert('Got this from the server: ' + response);
});
});
</script>
<?php
}
add_action( 'wp_ajax_my_action', 'my_action_callback' );
function my_action_callback() {
global $wpdb; // this is how you get access to the database
$whatever = intval( $_POST['whatever'] );
$whatever += 10;
echo $whatever;
die(); // this is required to return a proper result
}
And I don't get a response. I do get an alert saying 'Got this from the server: ', but no response. What gives?
Running your code on two separate wordpress installs from within a plugin file (plugin-name.php) and from within functions.php in my theme, it returns the proper value both times. There do not seem to be any errors in your code either.
Is this the only javascript you're including in the admin area?

Categories