Call a Wordpress shortcode with AJAX - javascript

I have a shortcode in Wordpress which I want to call it with jQuery with the click of a button. I read a few websites and tutorials, but I cannot figure exactly what happen.
I put this on function.php:
add_action( 'init', function() {
ps_register_shortcode_ajax( 'ps_get_survey_form', 'ps_get_survey_form' );
} );
function ps_register_shortcode_ajax( $callable, $action ) {
if ( empty( $_POST['action'] ) || $_POST['action'] != $action )
return;
call_user_func( $callable );
}
function ps_get_survey_form() {
echo do_shortcode( '[dopbsp id=6 lang=el]' );
die();
}
And this on the page-template.php I use:
<button id="testonclick" onclick="test()"></button>
<div id="testresults"></div>
<script>
function test() {
jQuery.ajax({
url: "http://localhost/myweb" + "/wp-admin/admin-ajax.php",
data : {action: 'ps_get_survey_form'},
success: function(results){
jQuery("#testresults").html(results)
},
error: function(errorThrown){console.log(errorThrown);}
});// end of ajax
}
</script>
However, the results is 0. Any idea what happened wrong?

I believe you want to be using something like
add_action('wp_ajax_nopriv_ps_get_survey_form', 'ps_get_survey_form' );
add_action( 'wp_ajax_ps_get_survey_form', 'ps_get_survey_form' );
instead of your
add_action( 'init', function() { ps_register_shortcode_ajax( 'ps_get_survey_form', 'ps_get_survey_form' ); } );
You can read more about that on this Codex page.
As far as I know, what you wrote doesn't make your function available via AJAX at all. I certainly don't know everything though. This is just the method that I use.

You should look over this article on WP and AJAX. It is best to 'tie' the ajax call to the admin ajax script.
http://www.smashingmagazine.com/2011/10/18/how-to-use-ajax-in-wordpress/
add_action("wp_ajax_my_user_vote", "my_user_vote");
add_action("wp_ajax_nopriv_my_user_vote", "my_must_login");
and
wp_register_script( "my_voter_script", WP_PLUGIN_URL.'/my_plugin/my_voter_script.js', array('jquery') );
wp_localize_script( 'my_voter_script', 'myAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' )));
be aware though that the shortcode may load css or js that is needed for the form, which won't get loaded via the ajax call.

Related

How to add Google Ads conversion purchase event to my WooCommerce Thank you Page

I saw this
Adding Google Ads Event Snippet To Conversion Page (thank you.php)
But I have a different situation. I am using " Auto Complete Processing WooCommerce orders on Thank you Page" and "Redirect WooCommerce checkout page" all these are inside my functions.php file.
This is what my functions.php file looks like. I hid my site with " ********* "
//Auto Complete Processing WooCommerce orders on Thankyou Page
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_order' );
function custom_woocommerce_auto_complete_order( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
if ( $order->has_status('processing') ) {
$order->update_status( 'completed' );
}
}
// Redirect WooCommerce checkout page to ******************** after the payament
add_action( 'woocommerce_thankyou', 'pfwp_redirect_woo_checkout');
function pfwp_redirect_woo_checkout( $order_id ){
$order = wc_get_order( $order_id );
$url = 'https://*********/*********/*********/';
if ( ! $order->has_status( 'failed' ) ) {
wp_safe_redirect( $url );
exit;
}
}
And I want to add the Event snippet inside the Thank You for google ads.
<!-- Event snippet for Purchase conversion page -->
<script>
gtag('event', 'conversion', {
'send_to': 'AW-***********/********kDENy8vL4o',
'value': 1.0,
'currency': 'SAR',
'transaction_id': ''
});
</script>
<!-- End Event snippet for Purchase conversion page -->
Because I am redirecting the thank you page to another page, the script will trigger? Or not?
And how and where do I add the Event snippet at the functions.php because I have a lot of code that control WooCommerce?
Since you're redirecting to another page, you have to add the conversion code on that page. To do that, I set a transient to pass that value.
Your functions for thank_you can be combined.
This is tested and should work for you.
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_order' );
function custom_woocommerce_auto_complete_order( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
if ( $order->has_status( 'processing' ) ) {
$order->update_status( 'completed' );
}
$url = 'https://*******/'; // Your redirect URL.
if ( ! $order->has_status( 'failed' ) ) {
ob_start();
set_transient( 'wc_order_total_for_google', $order->get_total( 'edit' ), 1 * MINUTE_IN_SECONDS );
wp_safe_redirect( $url );
exit;
}
}
add_action( 'wp_print_footer_scripts', 'dd_add_conversion_code' );
function dd_add_conversion_code() {
if ( is_page( your_custom_page_id ) ) { //Set your custom page ID here.
if ( false !== get_transient( 'wc_order_total_for_google' ) ) {
$order_total = get_transient( 'wc_order_total_for_google' );
?>
<!-- Event snippet for Purchase conversion page -->
<script>
gtag('event', 'conversion', {
'send_to': 'AW-***********/********kDENy8vL4o',
'value': <?php echo esc_attr( $order_total ); ?>,
'currency': 'SAR',
'transaction_id': ''
});
</script>
<!-- End Event snippet for Purchase conversion page -->
<?php
delete_transient( 'wc_order_total_for_google' );
}
}
}
If you add your script with the other tutorial:
add_action( 'woocommerce_thankyou', 'ds_checkout_analytics' );
And your redirection with:
add_action( 'woocommerce_thankyou', 'pfwp_redirect_woo_checkout');
Simply do this to make the tracking trigger before the redirection:
add_action( 'woocommerce_thankyou', 'pfwp_redirect_woo_checkout', 12 );
add_action( 'woocommerce_thankyou', 'ds_checkout_analytics', 11 );
By specifying the hook "priority", we've just told WordPress to run ds_checkout_analytics() before pfwp_redirect_woo_checkout(). Default priority is = 10

WordPress AJAX form / jQuery not updating user meta in the back-end

I'm trying to use an AJAX form on my Wordpress site to update a custom user meta (company_name) I created with ACF but it is not updating. If I use a built-in user meta such as first_name or last_name, it's working. But for whatever reason, custom user fields are not updating.
Thanks in advance
HTML form
<form id="um_form2" method="POST">
<p>
<label for="um_key">
Enter your last name:
<input type="text" name="um_key" id="um_key" value="" style="width:100%;" />
</label>
<input type="submit" value="Submit"/>
</p>
</form>
Snippet Script 1
function theme_enqueue2() {
$theme_url = get_template_directory_uri(); // Used to keep our Template Directory URL
$ajax_url = admin_url( 'admin-ajax.php' ); // Localized AJAX URL
// Register Our Script for Localization
wp_register_script(
'um-modifications2', // Our Custom Handle
"{$theme_url}/scripts/um-modifications2.js", // Script URL, this script is located for me in `theme-name/scripts/um-modifications.js`
array( 'jquery' ), // Dependant Array
'1.0', // Script Version ( Arbitrary )
true // Enqueue in Footer
);
// Localize Our Script so we can use `ajax_url`
wp_localize_script(
'um-modifications2',
'ajax_url',
$ajax_url
);
// Finally enqueue our script
wp_enqueue_script( 'um-modifications2' );
}
add_action( 'wp_enqueue_scripts', 'theme_enqueue2' );
Snippet 2
function um_modifications_callback2() {
// Ensure we have the data we need to continue
if( ! isset( $_POST ) || empty( $_POST ) || ! is_user_logged_in() ) {
// If we don't - return custom error message and exit
header( 'HTTP/1.1 400 Empty POST Values' );
echo 'Could Not Verify POST Values.';
exit;
}
$user_id = get_current_user_id(); // Get our current user ID
$um_val = sanitize_text_field( $_POST['company_name'] ); // Sanitize our user meta value
update_user_meta( $user_id, company_name, $um_val ); // Update our user meta
wp_update_user( array(
'ID' => $user_id,
// 'user_email' => $um_user_email,
)
);
echo "<script>window.close();</script>";
exit;
}
add_action( 'wp_ajax_nopriv_um_cb2', 'um_modifications_callback2' );
add_action( 'wp_ajax_um_cb2', 'um_modifications_callback2' );
Backend JavaScript
// Declare our JQuery Alias
jQuery( 'document' ).ready( function( $ ) {
// Form submission listener
$( '#um_form2' ).submit( function() {
// Grab our post meta value
var um_val2 = $( '#um_form2 #um_key' ).val();
// Do very simple value validation
if( $( '#um_form2 #um_key' ).val().length ) {
$.ajax( {
url : ajax_url, // Use our localized variable that holds the AJAX URL
type: 'POST', // Declare our ajax submission method ( GET or POST )
data: { // This is our data object
action : 'um_cb2', // AJAX POST Action
'company_name': um_val, // Replace `um_key` with your user_meta key name
}
} )
.success( function( results ) {
alert("success!");
window.location.href=window.location.href;
} )
.fail( function( data ) {
console.log( data.responseText );
console.log( 'Request failed: ' + data.statusText );
} );
} else {
// Show user error message.
}
return false; // Stop our form from submitting
} );
} );
Found the correct way...
update_field('company_name', $_POST['company_name'], 'user_'.$user_id.'');
instead of update_user_meta

Sitepoint "Redeem code" tutorial for Woocommerce problems

I am trying to implement "redeem coupon" functionality in a Woocommerce store, I have already found useful tutorial, but I can't make it work properly.
This is the tutorial.
What I've already done:
Created new page template with this code:
<div class="redeem-coupon">
<form id="ajax-coupon-redeem">
<p>
<input type="text" name="coupon" id="coupon"/>
<input type="submit" name="redeem-coupon" value="Redeem Offer" />
</p>
<p class="result"></p>
</form><!-- #ajax-coupon-redeem -->
Added this to my theme's functions.php file:
add_action( 'wp_ajax_spyr_coupon_redeem_handler', 'spyr_coupon_redeem_handler' );
add_action( 'wp_ajax_nopriv_spyr_coupon_redeem_handler', 'spyr_coupon_redeem_handler' );
Added this to my theme's functions.php file:
function spyr_coupon_redeem_handler() {
// Get the value of the coupon code
$code = $_REQUEST['coupon_code'];
// Check coupon code to make sure is not empty
if( empty( $code ) || !isset( $code ) ) {
// Build our response
$response = array(
'result' => 'error',
'message' => 'Code text field can not be empty.'
);
header( 'Content-Type: application/json' );
echo json_encode( $response );
// Always exit when doing ajax
exit();
}
// Create an instance of WC_Coupon with our code
$coupon = new WC_Coupon( $code );
// Check coupon to make determine if its valid or not
if( ! $coupon->id && ! isset( $coupon->id ) ) {
// Build our response
$response = array(
'result' => 'error',
'message' => 'Invalid code entered. Please try again.'
);
header( 'Content-Type: application/json' );
echo json_encode( $response );
// Always exit when doing ajax
exit();
} else {
// Coupon must be valid so we must
// populate the cart with the attached products
foreach( $coupon->product_ids as $prod_id ) {
WC()->cart->add_to_cart( $prod_id );
}
// Build our response
$response = array(
'result' => 'success',
'href' => WC()->cart->get_cart_url()
);
header( 'Content-Type: application/json' );
echo json_encode( $response );
// Always exit when doing ajax
exit();
}
}
Created "kody.js":
jQuery( document ).ready( function() {
jQuery( '#ajax-coupon-redeem input[type="submit"]').click( function( ev ) {
// Get the coupon code
var code = jQuery( 'input#coupon').val();
// We are going to send this for processing
data = {
action: 'spyr_coupon_redeem_handler',
coupon_code: code
}
// Send it over to WordPress.
jQuery.post( woocommerce_params.ajax_url, data, function( returned_data ) {
if( returned_data.result == 'error' ) {
jQuery( 'p.result' ).html( returned_data.message );
} else {
// Hijack the browser and redirect user to cart page
window.location.href = returned_data.href;
}
})
// Prevent the form from submitting
ev.preventDefault();
});
});
Called the script from functions.php with this code:
function my_scripts_method() {
wp_register_script('kody',
get_template_directory_uri() . '/js/kody.js',
array('jquery'),
'1.0' );
enqueue the script
wp_enqueue_script('kody');
}
add_action('wp_enqueue_scripts', 'my_scripts_method');
And here's the weird thing: it's sort of working. I've setup a page where I can enter the coupon code, I paste the code, click "Redeem" and it adds products related to the coupon to the cart. It doesn't, however apply pre-defined discounts.
The "redeem coupon" page is also only half-working. It should display error messages when someone leaves the field empty or enters an incorrect code - and it only does the former. Entering incorrect code results in redirection to cart.
My knowledge on Ajax and JS is very limited, I tried to find some other tutorials, but without any luck.
Is something wrong with the code? It's from 2014, so something might have change in Wordpress engine, causing troubles.
Thank you in advance for any reply!
Regards
Problems solved, if anyone encounters similar issues with the tutorial provided, here's what you have to do:
To apply discount, add following code:
global $woocommerce;
WC()->cart->add_discount( $code );
Just below these lines:
// Coupon must be valid so we must
// populate the cart with the attached products
foreach( $coupon->product_ids as $prod_id ) {
WC()->cart->add_to_cart( $prod_id );
To display invalid code message change this:
// Check coupon to make determine if its valid or not
if( ! $coupon->id && ! isset( $coupon->id ) ) {
To this:
// Check coupon to make determine if its valid or not
if( ! $coupon->id && ! isset( $coupon_id ) ) {
Everything is working now.
(Also changed the title to make it easier to others to find this post in the future.)

Gravity Forms - Enqueue JS when form embedded?

I want to be able to only enqueue certain JavaScript when there is a form embedded (emedded with shortcode and php).
Is there an action hook for Gravity Forms that triggers when a form is embedded? Then I could do something like this.
add_action('some_gforms_hook', function() {
add_action('wp_enqueue_scripts', function() {
wp_enqueue_script( 'postcode', get_bloginfo('stylesheet_directory') . '/modules/Postcode/assets/js/postcode.js', array('jquery') );
wp_localize_script( 'postcode', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
});
});
If there is no such hook, is there another (non hacky) way of archiving what I want?
You're looking for gform_enqueue_scripts. It passes the $form object so you determine if your scripts should be loaded for the given form.
I found this example in the documentation.
add_action( 'gform_register_init_scripts', 'gform_format_money' );
function gform_format_money( $form ) {
$script = '(function($){' .
'$('.gf_money input').each(function(){' .
'$(this).val(gformFormatMoney($(this).val()));' .
'}).change(function(){' .
'$(this).val(gformFormatMoney($(this).val()));' .
'});' .
'})(jQuery);';
GFFormDisplay::add_init_script( $form['id'], 'format_money', GFFormDisplay::ON_PAGE_RENDER, $script );
}
The problem with this example is that I don't like the JS written in my PHP files and the add_init_script() function needs a string with JS as argument.
I could use file_get_contents() to get the JS from the file but then I will not be able to localize the script for injecting the AJAX url.
I now use the hook as in the question and it works perfect.
add_action( 'gform_register_init_scripts', function() {
add_action('wp_enqueue_scripts', function() {
wp_enqueue_script( 'postcode', get_bloginfo('stylesheet_directory') . '/modules/Postcode/assets/js/postcode.js', array('jquery') );
wp_localize_script( 'postcode', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
});
});

Can't get Wordpress AJAX working

I have been following multiple tutorials on this (including Wordpress's own) and its driving me a little crazy.
I am trying to get AJAX working on the front end in Wordpress, however it is simply not doing anything, I know the function works as I have tested this independently, your input will be really appreciated on this one. Many thanks in advance.
The code in functions.php
function call_ajax()
{
//assuming this is in a theme?
wp_enqueue_script( 'ajax_car_models', get_template_directory_uri() . '/js/ajax_car_models.js', array( 'jquery' ), null, true);
//loacalize the script using the same handle it was registered / enqueued with
wp_localize_script( 'ajax_car_models', 'my_ajax_script', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
//make a call to call_ajax at the right time
add_action( 'wp_enqueue_scripts', 'call_ajax' );
add_action( 'wp_ajax_ajax_car_models', 'ajax_car_models' );
add_action( 'wp_ajax_nopriv_ajax_car_models', 'ajax_car_models' );
function ajax_car_models() {
$args = array( 'post_type' => 'product', 'posts_per_page' => 1040 );
$loop1 = new WP_Query( $args );
$code = '';
$car_make = 26;
$all_models = array();
while ( $loop1->have_posts() ) : $loop1->the_post();
$terms_make = get_the_terms( get_the_id(), 'pa_car-make' );
foreach ( $terms_make as $make ) {
if ( $make->term_id == $car_make ) {
$the_car_model = get_the_terms( get_the_id(), 'pa_model' );
foreach ( $the_car_model as $the_model ) {
if ($all_models[$the_model->name] != 'true') {
$code .= '<br />'.$the_model->name.' ';
$all_models[$the_model->name] = 'true';
}
}
}
}
endwhile;
wp_reset_postdata();
header( 'Content-type: application/json' );
echo json_encode( $code );
die();
}
And the jQuery itself:
jQuery( document ).ready(function() {
jQuery('#car-make').change(my_js_function);
function my_js_function()
{
jQuery.ajax({
url: my_ajax_script.ajaxurl,
dataType: 'json', // add this line
data: ({action : 'ajax_car_models'}),
success: function() {
jQuery("#feedback").html(data);
}
});
}
});
If you include you javascript inline you will not be able to use localize pass it the ajax url.
You should move your javascript into a different file and then use wp_enqueue_script in order to properly use ajax.
function call_ajax()
{
//assuming this is in a theme?
wp_enqueue_script( 'ajax_car_models', get_template_directory_uri() . '/js/ajax_car_models.js', array( 'jquery' ), null, true);
//loacalize the script using the same handle it was registered / enqueued with
wp_localize_script( 'ajax_car_models', 'my_ajax_script', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
//make a call to call_ajax at the right time
add_action( 'wp_enqueue_scripts', 'call_ajax' );
You also need to send json headers in your response function
header( 'Content-type: application/json' );
echo json_encode( $code );
exit();
In your ajax call you are not passing the data to your success callback
success: function(data){
console.log(data);
//...
}
You can use the network tab on the chrome developer tools to look at what requests are actually made and check the response they receive.
According to the PHP manual json_encode needs string data to be UTF8 encoded.
Alternatively, you can try doing this instead in your functions.php...
$return_array = array(
'val' => $code
);
echo json_encode($return_array);
Then, in your jQuery script...
jQuery("#feedback").html(data.val);
Also, try adding to your ajax request one more option...
url: my_ajax_script.ajaxurl,
dataType: 'json', // add this line
data: ({action : 'ajax_car_models'}),
Hope these help!

Categories