Question

I'm passing successfully an ajax object to the backend following this (the script in the JS really it does not matters because I'm getting it well):

add_action( 'wp_ajax_my_action', 'my_action_callback' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback' );
add_action( 'wp_enqueue_scripts', 'theme_name_scripts' );
add_shortcode('tagtest', 'timezone');

function theme_name_scripts() {
    wp_enqueue_script( 'script-name', plugins_url( '/assets/js/timezone.js', __FILE__ ), array('jquery'), '1.0.0', true );
    wp_localize_script( 'script-name', 'MyAjax', array(
        'ajaxurl' => admin_url( 'admin-ajax.php' ),
        'security' => wp_create_nonce( 'my-special-string' ),
    ));
}

function my_action_callback() {
    $whatever = strval( $_POST['whatever'] );
    echo $whatever;
    return $whatever;
    wp_die();
}

But I have the timezone function that is the function of the add_shortcode hook. I need to get the variable $whatever from my_action_callback in timezone function. How can I do that?

function timezone(){
    $whatever = //Here I need the result from my_action_callback function
}

Just in case here is my JS script and an image ensuring that the object is passing successfully

jQuery(document).ready(function($) {

  var data = {
    action: 'my_action',
    security : MyAjax.security,
    whatever: 'Hello there'
  };

  // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
  $.post(MyAjax.ajaxurl, data, function(response) {
    alert('Here is: ' + response);
    return response;
  });
});

Here is the XHR response:

action: my_action
security: f1860eab4b
whatever: Hello there

I'm getting this object without problems in the add_action callback

enter image description here

As I said before, the only thing that I need and that I haven't make it works is to get $whatever in timezone function (timezone is the function of add_shortcode) How can I achieve this? Thanks in advance.

Was it helpful?

Solution

You can't put AJAX into the callback for a shortcode. It doesn't make any sense to. If you're making an AJAX request then you're making it on the front-end and the shortcode has already rendered.

So anything you do with the response to the AJAX request needs to occur on the front-end. So what you need to do is output some HTML in the shortcode with a class or ID that your JavaScript can use to populate the data on the front-end.

So your shortcode could look like this:

function timezone(){
    echo '<div class="timezone"></div>';
}

Then your AJAX request should populate that div with the response on completion:

$.post(MyAjax.ajaxurl, data, function(response) {
    $('.timezone').html( response );
});

In that example we're using jQuery to set the HTML of that div to the value of the response.

If you want the shortcode to have a default value, then one approach would be to abstract out the function responsible for the output into its own function. Then just use that same function inside both the AJAX callback and the shortcode callback.

So lets create a function for outputting the text:

function wpse_301294_whatever() {
    return 'Whatever';
}

That function will return the string Whatever.

Then we can update the shortcode to use this function within the div:

function timezone(){
    echo '<div class="timezone">' . wpse_301294_whatever() . '</div>';
}

And the AJAX callback:

function my_action_callback() {
    echo wpse_301294_whatever();
    wp_die();
}

Now you have a function, wpse_301294_whatever(), responsible for outputting something, as well as a Shortcode and AJAX callback that can use that output in different contexts.

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top