The correct method to pass query vars in AJAX using ajaxurl

OK, I had no idea how to title this topic.

I’m trying to override the default behavior with ajax. The problem here is not actually a problem, but a wish more.

I have this url:

<a href="http://example.com/?reaction=smk_remove_post&id=1226&_nonce=7be82cd4a0" class="smk-remove-post">Remove post</a>

In the functions.php I have this function and the call right after:

function smk_remove_post(){
    if( !empty( $_GET['reaction'] ) && 'smk_remove_post' == $_GET['reaction'] && !empty( $_GET['id'] ) ){
        if( current_user_can('edit_others_posts') && !empty($_GET['_nonce']) ){
            if( wp_verify_nonce( esc_html( $_GET['_nonce'] ), 'smk_remove_post' ) ){
                // Delete the post
                wp_delete_post( absint( $_GET['id'] ), true );
            }
        }
    }
}
smk_remove_post();

Now if I click on the link the post with ID 1226 will be removed. All is ok. The task is done successfuly and the page is reloaded.

Here is where I need the AJAX. I want to process this URL using ajax and not reload the page, and get a proper response.

I’ve added this jQuery script:

function smk_remove_post(){
    $('.smk-remove-post').on( 'click', function( event ){
        event.preventDefault();
        var _this = $(this);

        jQuery.ajax({
            type: "GET",
            url: _this.attr('href'),
            success: function(response){
                console.log(response);
                _this.text('All great, the post is removed.');
            }
        });
    });
}
smk_remove_post();

Everything works as expected. The post is removed via ajax and no need to reload the page. But I can’t get a proper response, instead I get the full HTML source of the current page.

I know that I should use admin-ajax.php(ajaxurl), but how do I do it? I need to send the query from URL and get the response back.

Here is what I’ve tryied:

I have added this to the jQuery script above:

data: {
    'action': 'smk_remove_post_ajax',
},

And this to the PHP:

function smk_remove_post_ajax(){
    smk_remove_post();
    die();
}
add_action('wp_ajax_smk_remove_post_ajax', 'smk_remove_post_ajax');

It does not work. It’s ignored, the previous call is executed insted, just like this would be done without ajax.

I understand that I need somehow to send the query to admin-ajax.php instead, but how?

3 s
3

I finally got it.

First mistake was to process the same function twice. I’ve called it once after the function and one more time in ajax action. So when using the ajax call, the function got executed twice. In the example from the OP, this is not a problem at all, because it is simplified to do only one thing, but in my real code it does much more and can result in lost of unwanted data.

Also, I just needed to stop the ajax and get a custom responce, nothing more. Here is what I’ve did:

1. I’ve changed this:

smk_remove_post();

to this:

add_action('parse_query', 'smk_remove_post');

It is better to run the function later when needed in special action.

2. Next, I’ve modified the ajax handler:
I’ve deleted this line smk_remove_post(); and changed the ajax action from wp_ajax_smk_remove_post_ajax to wp_ajax_smk_remove_post:

function smk_remove_post_ajax(){
    wp_die( 'ok' );
}
add_action('wp_ajax_smk_remove_post', 'smk_remove_post_ajax');

3. I’ve renamed the query string reaction to action. Changed it in the url, and function:

4. Finally modified the jQuery script. So it uses the admin-ajax.php and sends the url as data:

url: ajaxurl,
data: _this.attr('href'),

Here is the final code:

Link:

<a href="http://example.com/?action=smk_remove_post&id=1226&_nonce=7be82cd4a0" class="smk-remove-post">Remove post</a>

PHP code:

function smk_remove_post(){
    if( !empty( $_GET['action'] ) && 'smk_remove_post' == $_GET['action'] && !empty( $_GET['id'] ) ){
        if( current_user_can('edit_others_posts') && !empty($_GET['_nonce']) ){
            if( wp_verify_nonce( esc_html( $_GET['_nonce'] ), 'smk_remove_post' ) ){
                // Delete the post
                wp_delete_post( absint( $_GET['id'] ), true );
            }
        }
    }
}
add_action('parse_query', 'smk_remove_post');

function smk_remove_post_ajax(){
    wp_die( 'ok' );
}
add_action('wp_ajax_smk_remove_post', 'smk_remove_post_ajax');

Javascript:

function smk_remove_post(){
    $('.smk-remove-post').on( 'click', function( event ){
        event.preventDefault();
        var _this = $(this);

        jQuery.ajax({
            type: "GET",
            url: ajaxurl,
            data: _this.attr('href').split('?')[1],
            success: function(response){
                console.log(response); // ok
                _this.text('All great, the post is removed.');
            }
        });
    });
}
smk_remove_post();

Edit:
Also a small update to the code above. To process the query strings is required to delete the site path, else it may create unexpected problems. I’ve added this to data href:

.split('?')[1]

Leave a Comment