Woocommerce ajax return empty shipping packages - ajax

Am trying to get the shipping packages with ajax but its always returning empty value.
same issue while trying to call get the zones with: WC_Shipping_Zones::get_zones();
am using the same code in woocommerce_checkout_before_order_review and its working without any issue!
function jsforwp_add_like() {
check_ajax_referer( 'jsforwp_likes_nonce' );
$packages = WC()->shipping->get_packages();
if(empty($packages)){
$check = 'empty';
}else{
$check = $packages;
}
$success = true;
if( true == $success ) {
$response['type'] = 'success';
$response['zone'] = $check;
}
$response = json_encode( $response );
echo $response ;
die();
}
add_action( 'wp_ajax_jsforwp_add_like', 'jsforwp_add_like' );
add_action( 'wp_ajax_nopriv_jsforwp_add_like', 'jsforwp_add_like' );
My javascript
add_action('wp_footer','my_custom_ajax');
function my_custom_ajax(){
?>
<script>
(function($){
$( document.body ).on( 'updated_checkout', function(){
$.ajax({
type : 'post',
dataType : 'json',
url : jsforwp_globals.ajax_url,
data : {
action: 'jsforwp_add_like',
_ajax_nonce: jsforwp_globals.nonce
},
success: function( response ) {
if( 'success' == response.type ) {
console.log( response );
}
else {
console.log( 'Something went wrong, try logging in!' );
}
}
});
} );
} )( jQuery );
</script>
<?php
}
returned value
{type: "success", zone: "empty"}

Related

How to enable more than one fee with ajax in Woocommerce checkout?

I'm trying to add more than one fee to the order total amount checkout using ajax.
So far, the first fee, insurance_shipping_fee, is working correctly, but when checking the second one, premium_gift_box, I receive a 400 error ("xxx.com/wp-admin/admin-ajax.php").
Any ideas on why?
Any help appreciated
This is the full code:
// Calculate insurance fee
function as_calculate_insurance_fee() {
$shipping_country = WC()->customer->get_shipping_country();
$cart_subtotal = WC()->cart->subtotal;
$cart_subtotal_rounded = ceil($cart_subtotal / 100) * 100;
if($shipping_country == 'AU') {
if($cart_subtotal <= 5000) $insurance_fee = $cart_subtotal_rounded/100 + 1;
} else {
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_shipping = $chosen_methods[0];
if ($chosen_shipping == 'free_shipping:12' || $chosen_shipping == 'starshipit_4') {
if($cart_subtotal <= 5000) $insurance_fee = $cart_subtotal_rounded/100 * 3;
} else if($chosen_shipping == 'starshipit_5') {
$insurance_fee = ($cart_subtotal_rounded - 1000)/100 * 3 + 25;
}
}
return $insurance_fee;
}
// Add a Shipping Insurance checkbox field
function add_custom_checkout_checkbox() {
$insurance_fee = as_calculate_insurance_fee();
if( WC()->session->get('enable_fee') ) $checked = true;
else $checked = false;
woocommerce_form_field( 'insurance_fee', array(
'type' => 'checkbox',
'label' => __('<span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">'.get_woocommerce_currency().' </span>'.$insurance_fee.'</bdi></span>'),
'class' => array( 'form-row-wide' ),
), $checked );
}
add_action( 'as_review_order_after_shipping', 'add_custom_checkout_checkbox', 20 );
// Add Signature Gift Box checkbox field
function add_custom_checkout_checkbox_2() {
if( WC()->session->get('enable_fee_2') ) $checked = true;
else $checked = false;
woocommerce_form_field( 'premium_giftbox_fee', array(
'type' => 'checkbox',
'label' => __('<span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">'.get_woocommerce_currency().' </span>9</bdi></span>'),
'class' => array( 'form-row-wide' ),
), $checked );
}
add_action( 'as_review_order_before_shipping', 'add_custom_checkout_checkbox_2', 20 );
// Add custom fees
function custom_fee( $cart ) {
// Only on checkout
if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) || ! is_checkout() )
return;
$insurance_fee = as_calculate_insurance_fee();
if( WC()->session->get('enable_fee') )
$cart->add_fee( __( 'Insurance fee', 'woocommerce'), $insurance_fee );
if( WC()->session->get('enable_fee_2') )
$cart->add_fee( __( 'Siganture Gift Box fee', 'woocommerce'), 9 );
}
add_action( 'woocommerce_cart_calculate_fees', 'custom_fee', 20, 1 );
// Remove "(optional)" label on checkbox field
function remove_order_comments_optional_fields_label( $field, $key, $args, $value ) {
// Only on checkout page for Order notes field
if( ( 'insurance_fee' === $key || 'premium_giftbox_fee' === $key ) && is_checkout() ) {
$optional = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
$field = str_replace( $optional, '', $field );
}
return $field;
}
add_filter( 'woocommerce_form_field' , 'remove_order_comments_optional_fields_label', 10, 4 );
// jQuery - Ajax script
function checkout_fees_script() {
// Only on Checkout
if( is_checkout() && ! is_wc_endpoint_url() ) :
if( WC()->session->__isset('enable_fee') )
WC()->session->__unset('enable_fee');
if( WC()->session->__isset('enable_fee_2') )
WC()->session->__unset('enable_fee_2');
?>
<script type="text/javascript">
jQuery( function($){
if (typeof wc_checkout_params === 'undefined')
return false;
$('form.checkout').on('change', 'input[name=insurance_fee]', function(e){
var fee = $(this).prop('checked') === true ? '1' : '';
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'enable_fee',
'enable_fee': fee,
},
success: function (result) {
$('body').trigger('update_checkout');
},
});
});
$('form.checkout').on('change', 'input[name=premium_giftbox_fee]', function(e){
var fee2 = $(this).prop('checked') === true ? '1' : '';
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'enable_fee_2',
'enable_fee_2': fee2,
},
success: function (result) {
$('body').trigger('update_checkout');
},
});
});
});
</script>
<?php
endif;
}
add_action( 'wp_footer', 'checkout_fees_script' );
// Get Ajax request and saving to WC session
function get_enable_fee() {
if ( isset($_POST['enable_fee']) ) {
WC()->session->set('enable_fee', ($_POST['enable_fee'] ? true : false) );
}
if ( isset($_POST['enable_fee_2']) ) {
WC()->session->set('enable_fee_2', ($_POST['enable_fee_2'] ? true : false) );
}
die();
}
add_action( 'wp_ajax_enable_fee', 'get_enable_fee' );
add_action( 'wp_ajax_nopriv_enable_fee', 'get_enable_fee' );
```
You forgot to register the second fee ajax action.
It should be like that.
add_action( 'wp_ajax_enable_fee', 'get_enable_fee' );
add_action( 'wp_ajax_nopriv_enable_fee', 'get_enable_fee' );
add_action( 'wp_ajax_enable_fee_2', 'get_enable_fee' );
add_action( 'wp_ajax_nopriv_enable_fee_2', 'get_enable_fee' );

Add a fee for specific user roles when "Ship to a different address?" has been checked on WooCommerce checkout

I have a wholesale site with different user roles & want to allow employees to start ordering online from here also.
I want to only add a $5 fee if the user roles 'team' and 'team2' select ship to a different address (they get free shipping if sent to their billing address).
No other user role should see the fee if selecting the ship to a different address.
This is the closest solution I've found to make this happen but need help configuring this code to apply to only those two user roles and no one else.
// send as gift for Team & Team2 role add $5 fee
add_filter( 'woocommerce_form_field' , 'remove_order_comments_optional_fields_label', 10, 4 );
function remove_order_comments_optional_fields_label( $field, $key, $args, $value ) {
// Only on checkout page for Order notes field
if( 'ship_to_different_address' === $key && is_checkout() ) {
$optional = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
$field = str_replace( $optional, '', $field );
}
return $field;
}
// Ajax / jQuery script
add_action( 'wp_footer', 'ship_to_different_address_script' );
function ship_to_different_address_script() {
// On checkoutpage
if( ( is_checkout() && ! is_wc_endpoint_url() ) ) :
?>
<script type="text/javascript">
jQuery( function($){
if (typeof woocommerce_params === 'undefined')
return false;
console.log('defined');
$('input[name=ship_to_different_address]').click( function(){
var fee = $(this).prop('checked') === true ? '1' : '';
$.ajax({
type: 'POST',
url: woocommerce_params.ajax_url,
data: {
'action': 'ship_to_different_address',
'ship_to_different_address': fee,
},
success: function (result) {
$('body').trigger('update_checkout');
console.log(result);
},
});
});
});
</script>
<?php
endif;
}
// Get the ajax request and set value to WC session
add_action( 'wp_ajax_ship_to_different_address', 'get_ajax_ship_to_different_address' );
add_action( 'wp_ajax_nopriv_ship_to_different_address', 'get_ajax_ship_to_different_address' );
function get_ajax_ship_to_different_address() {
if ( isset($_POST['ship_to_different_address']) ) {
WC()->session->set('ship_to_different_address', ($_POST['ship_to_different_address'] ? '1' : '0') );
echo WC()->session->get('ship_to_different_address');
}
die();
}
// Add / Remove a custom fee
add_action( 'woocommerce_cart_calculate_fees', 'add_remove_ship_to_different_address', 10, 1 );
function add_remove_ship_to_different_address( $cart )
{
// Only on checkout
if ((is_admin() && !defined('DOING_AJAX')) || is_cart())
return;
$fee_amount = 5.00;
if (WC()->session->get('ship_to_different_address'))
$cart->add_fee(__('Shipping fee', 'woocommerce'), $fee_amount);
}
Your code contains some mistakes, missing pieces, and unnecessary steps.
This answer shows (without any user restrictions) how to add a fee when "Ship to a different address?" has been checked:
// The jQuery Ajax request
function action_wp_footer() {
// Only checkout page
if ( is_checkout() && ! is_wc_endpoint_url() ) :
// Remove "ship_different" custom WC session on load
if ( WC()->session->get( 'ship_different' ) ) {
WC()->session->__unset( 'ship_different' );
}
// jQuery Ajax code below
?>
<script type="text/javascript">
jQuery( function($) {
if ( typeof wc_checkout_params === 'undefined' )
return false;
var a = '#ship-to-different-address-checkbox', b = '';
// Ajax function
function triggerSTDA( value ) {
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'ship_different_address',
'ship_different': value,
},
success: function (result) {
$( 'body' ).trigger( 'update_checkout' );
// console.log( result ); // For testing (to be removed)
}
});
}
$( a ).on( 'change', function() {
b = $( this ).prop('checked') === true ? 'yes' : 'no';
triggerSTDA( b );
});
});
</script>
<?php
endif;
}
add_action( 'wp_footer', 'action_wp_footer' );
// The Wordpress Ajax PHP receiver
function get_ajax_ship_different_address() {
if ( isset( $_POST['ship_different'] ) ) {
WC()->session->set( 'ship_different', esc_attr( $_POST['ship_different'] ) );
echo $_POST['ship_different'];
}
die();
}
add_action( 'wp_ajax_ship_different_address', 'get_ajax_ship_different_address' );
add_action( 'wp_ajax_nopriv_ship_different_address', 'get_ajax_ship_different_address' );
// Add / remove a custom fee
function action_woocommerce_cart_calculate_fees( $cart ) {
// Only on checkout
if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) || is_cart() )
return;
$fee_amount = 5;
if ( WC()->session->get( 'ship_different' ) == 'yes' ) {
$cart->add_fee( __( 'Shipping fee', 'woocommerce'), $fee_amount );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );
However, your question was to only apply this based on certain user roles:
So you get:
// The jQuery Ajax request
function action_wp_footer() {
// Only for logged in users
if ( ! is_user_logged_in() )
return;
// Only checkout page
if ( is_checkout() && ! is_wc_endpoint_url() ) :
// Remove "ship_different" custom WC session on load
if ( WC()->session->get( 'ship_different' ) ) {
WC()->session->__unset( 'ship_different' );
}
// jQuery Ajax code below
?>
<script type="text/javascript">
jQuery( function($) {
if ( typeof wc_checkout_params === 'undefined' )
return false;
var a = '#ship-to-different-address-checkbox', b = '';
// Ajax function
function triggerSTDA( value ) {
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'ship_different_address',
'ship_different': value,
},
success: function (result) {
$( 'body' ).trigger( 'update_checkout' );
// console.log( result ); // For testing (to be removed)
}
});
}
$( a ).on( 'change', function() {
b = $( this ).prop('checked') === true ? 'yes' : 'no';
triggerSTDA( b );
});
});
</script>
<?php
endif;
}
add_action( 'wp_footer', 'action_wp_footer' );
// The Wordpress Ajax PHP receiver
function get_ajax_ship_different_address() {
if ( isset( $_POST['ship_different'] ) ) {
WC()->session->set( 'ship_different', esc_attr( $_POST['ship_different'] ) );
echo $_POST['ship_different'];
}
die();
}
add_action( 'wp_ajax_ship_different_address', 'get_ajax_ship_different_address' );
add_action( 'wp_ajax_nopriv_ship_different_address', 'get_ajax_ship_different_address' );
// Add / remove a custom fee
function action_woocommerce_cart_calculate_fees( $cart ) {
// Only on checkout
if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) || is_cart() )
return;
// Only for logged in users
if ( ! is_user_logged_in() )
return;
// Get current WP_User Object
$user = wp_get_current_user();
// Roles to check, adapt to your specific needes
$roles_to_check = array( 'team', 'team2', 'administrator' );
// User roles
$roles = ( array ) $user->roles;
// Compare
$compare = array_diff( $roles, $roles_to_check );
// Result is empty
if ( empty ( $compare ) ) {
// Amount
$fee_amount = 5;
if ( WC()->session->get( 'ship_different' ) == 'yes' ) {
$cart->add_fee( __( 'Shipping fee', 'woocommerce'), $fee_amount );
}
}
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );
Partly used in this answer
Show hide payment gateways based on checkout fields in Woocommerce
Checkbox field that add / remove a custom fee in WooCommerce
Check WooCommerce User Role and Payment Gateway and if they match - Apply fee

Get post meta in the Ajax not working in Wordpress

I am doing an Ajax call and return the value. The post id is coming. But when i tried with this code, It is return blank
function visa_status() {
$postid = $_POST['appid'];
// args
$args = array(
'numberposts' => 1,
'post_type' => 'cpt_15',
'meta_key' => 'application_number',
'meta_value' => $postid
);
$metaarry = array();
// query
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$posti = get_the_ID();
endwhile;
//echo $posti;
echo get_post_meta( $posti, 'given_name');
exit();
}
In the above code, $posti is coming. But get_post_meta() is not working.
This is my JS part
onStepChanging: function (event, currentIndex, newIndex) {
if ( newIndex === 1 ) {
jQuery('.wizard > .steps ul').addClass('step-2');
appId = jQuery('#appid').val();
jQuery.ajax({
type: 'POST',
dataType: 'json',
url: my_ajax_object.ajax_url,
data: {
'action': 'visa_status',
'appid': appId,
},
success: function (msg) {
console.log(msg);
}
});
} else {
jQuery('.wizard > .steps ul').removeClass('step-2');
}
if ( newIndex === 2 ) {
jQuery('.wizard > .steps ul').addClass('step-3');
} else {
jQuery('.wizard > .steps ul').removeClass('step-3');
}
return true;
},
Is there any mistake i have done. Please help me in this.
Try this
$given_name = get_post_meta( $posti, 'given_name', true );
echo $given_name;
OR Try this
echo get_post_meta( $posti, 'given_name', true );
Check here what get_post_meta function returns based on 3rd parameter.

stop page reloading when using ajax

I've created a wordpress plugin to vote on a post, using ajax.
When you click the 'vote' link the jquery popup works, your vote is added but then the page reloads
add_action("wp_ajax_my_user_vote", "my_user_vote");
add_action("wp_ajax_nopriv_my_user_vote", "my_must_login");
function my_user_vote() {
if ( !wp_verify_nonce( $_REQUEST['nonce'], "my_user_vote_nonce")) {
exit("No naughty business please");
}
$user_id = get_current_user_id();
date_default_timezone_set('GMT+2');
$dateVoted = get_user_meta($user_id, 'date');
$today = date('d M Y');
if ($dateVoted === $today){
//Already Voted
echo '<script language="javascript">';
echo 'alert("already voted")';
/*
echo 'alert("User ID: ' . $user_id . '")';
echo 'alert("Date Voted: ' . $dateVoted . '")';
echo 'alert("Today: ' . $today . '")';
*/
echo '</script>';
}else{
$vote_count = get_post_meta($_REQUEST["post_id"], "votes", true);
$vote_count = ($vote_count == '') ? 0 : $vote_count;
$new_vote_count = $vote_count + 1;
$vote = update_post_meta($_REQUEST["post_id"], "votes", $new_vote_count);
if($vote === false) {
$result['type'] = "error";
$result['vote_count'] = $vote_count;
}
else {
$result['type'] = "success";
$result['vote_count'] = $new_vote_count;
}
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
$result = json_encode($result);
echo $result;
}
else {
header("Location: ".$_SERVER["HTTP_REFERER"]);
}
update_user_meta( $user_id, 'date', $today );
}
die();
}
function my_must_login() {
echo "You must log in to vote";
die();
}
add_action( 'init', 'my_script_enqueuer' );
function my_script_enqueuer() {
wp_register_script( "my_voter_script", WP_PLUGIN_URL.'/video-of-the- day/my_voter_script.js', array('jquery') );
wp_localize_script( 'my_voter_script', 'myAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' )));
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'my_voter_script' );
}
I also have a jquery file:
jQuery(document).ready( function() {
jQuery(".user_vote").click( function() {
post_id = jQuery(this).attr("data-post_id")
nonce = jQuery(this).attr("data-nonce")
jQuery.ajax({
type : "post",
dataType : "json",
url : myAjax.ajaxurl,
data : {action: "my_user_vote", post_id : post_id, nonce: nonce},
success: function(response) {
if(response.type == "success") {
}
else {
alert("Your vote could not be added")
}
}
});
})
});
why is the ajax not working?
Try this
jQuery(".user_vote").click( function(e) {
e.PreventDefault();
});

Returning JSON data with ajax in wordpress

Ok so a fairly long question here. I'm fairly new to AJAX and especially using it in the context of WordPress, but I've been following along some tutorials online and I think I'm almost there.
I'll paste what I have so far and explain my thinking.
Ok so to start, the JS.
jQuery(document).ready(function(){
jQuery('.gadgets-menu').mouseenter(function(){
doAjaxRequest();
});
});
Mouse enters .gadgets-menu and the request triggers, using mouseenter so it fires once.
The request itself.
function doAjaxRequest(){
// here is where the request will happen
jQuery.ajax({
url: 'http://www.mysite.com/wp-admin/admin-ajax.php',
data:{
'action':'do_ajax',
'fn':'get_latest_posts',
'count':5
},
dataType: 'JSON',
success:function(data){
//Here is what I don't know what to do.
},
error: function(errorThrown){
alert('error');
console.log(errorThrown);
}
});
}
Now the php function.
add_action('wp_ajax_nopriv_do_ajax', 'our_ajax_function');
add_action('wp_ajax_do_ajax', 'our_ajax_function');
function our_ajax_function(){
switch($_REQUEST['fn']){
case 'get_latest_posts':
$output = ajax_get_latest_posts($_REQUEST['count']);
break;
default:
$output = 'No function specified, check your jQuery.ajax() call';
break;
}
$output=json_encode($output);
if(is_array($output)){
print_r($output);
}
else{
echo $output;
}
die;
}
And the ajax_get_latest_posts function
function ajax_get_latest_posts($count){
$posts = get_posts('numberposts='.'&category=20'.$count);
return $posts;
}
So, if I've done this right the output should be $posts = get_posts('numberposts='.'&category=20'.$count); ie. the number of posts (5), from category 20.
I don't know what to do with that now, how do I get the title and the thumbnail?
I'm sorry if this is silly, I'm just fumbling around here.
Amended php
add_action('wp_ajax_nopriv_do_ajax', 'our_ajax_function');
add_action('wp_ajax_do_ajax', 'our_ajax_function');
function our_ajax_function(){
$output = ajax_get_latest_posts($_REQUEST['count']); // or $_GET['count']
if($output) {
echo json_encode(array('success' => true, 'result' => $output));
}
else {
wp_send_json_error(); // {"success":false}
// Similar to, echo json_encode(array("success" => false));
// or you can use, something like -
// echo json_encode(array('success' => false, 'message' => 'Not found!'));
}
$output=json_encode($output);
if(is_array($output)){
print_r($output);
}
else{
echo $output;
}
die;
}
function ajax_get_latest_posts($count)
{
$args = array( 'numberposts' => $count, 'order' => 'DESC','category' => 20 );
$post = wp_get_recent_posts( $args );
if( count($post) ) {
return $post;
}
return false;
}
This does not work.
jQuery(document).ready(function(){
jQuery('.gadgets-menu').mouseenter(function(){
doAjaxRequest();
});
});
function doAjaxRequest(){
// here is where the request will happen
jQuery.ajax({
url: 'http://localhost:8888/wp-admin/admin-ajax.php',
data:{
'action':'do_ajax',
'fn':'get_latest_posts',
'count':5
},
dataType: 'JSON',
success:function(data){
if(data.success) {
alert("It works");
}
else {
// alert(data.message); // or whatever...
}
}
});
}
No alert is shown.
In your code get_posts('numberposts='.'&category=20'.$count); is wrong, but you can use wp_get_recent_posts function instead (though it uses get_posts anyway), for example
function ajax_get_latest_posts($count)
{
$args = array( 'numberposts' => $count, 'order' => 'DESC','category' => 20 );
$post = wp_get_recent_posts( $args );
if( count($post) ) {
return $post;
}
return false;
}
Then in your our_ajax-function you can use
$output = ajax_get_latest_posts($_REQUEST['count']); // or $_GET['count']
if($output) {
echo json_encode(array('success' => true, 'result' => $output));
}
else {
wp_send_json_error(); // {"success":false}
// Similar to, echo json_encode(array("success" => false));
// or you can use, something like -
// echo json_encode(array('success' => false, 'message' => 'Not found!'));
}
In you success callback function, you can then check
success:function(data){
if(data.success) {
// loop the array, and do whatever you want to do
$.each(data.result, function(key, value){
// you can use $(this) too
// console.log($(this)); // check this for debug and get an idea
});
}
else {
// alert(data.message); // or whatever...
}
}
You can read here about wp_send_json_error helper function to learn more about helper functions.
Update :
Also remember that, after $output=json_encode($output); the $output is not an array anymore, instead, it's a json string, so is_array($output) will return false but if you use is_array() just before you encode it using $output=json_encode($output); like
if( is_array( $output ) ) {
$output = json_encode( $output );
}
In this case, is_array( $output ) will return true.
An example/simulation.

Resources