Is there an easy way to AJAX-ify saving of post?

You can technically make a XHR to post.php via JavaScript. Below is a proof-of-concept for saving/editing posts only. I haven’t tested it at all, so I’m sure you will need to tweak it. I wanted to give you a basic workflow for accomplishing something like this. You can take it and run with it if you need to extend it.

Step 1: Add AJAX handler to admin_head for new and existing posts.

function my_post_type_xhr(){
    global $post;
    if('my_post_type' === $post->post_type){
        $post_url = admin_url('post.php'); #In case we're on post-new.php
        echo "
        <script>
            jQuery(document).ready(function($){
                //Click handler - you might have to bind this click event another way
                $('input#publish, input#save-post').click(function(){
                    //Post to post.php
                    var postURL = '$post_url';

                    //Collate all post form data
                    var data = $('form#post').serializeArray();

                    //Set a trigger for our save_post action
                    data.push({foo_doing_ajax: true});

                    //The XHR Goodness
                    $.post(postURL, data, function(response){
                        var obj = $.parseJSON(response);
                        if(obj.success)
                            alert('Successfully saved post!');
                        else
                            alert('Something went wrong. ' + response);
                    });
                    return false;
                });
            });
        </script>";
    }
}
add_action('admin_head-post.php', 'my_post_type_xhr');
add_action('admin_head-post-new.php', 'my_post_type_xhr');

Step 2: Hook into the save_post action.

This runs after the post has been saved to the database, so you can save whatever postmeta you need and halt the page render.

add_action('save_post', 'save_my_post_type');
function save_my_post_type($post_id){
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;

    #If this is your post type
    if('my_post_type' === $_POST['post_type']){
        //Save any post meta here

        #We conditionally exit so we don't return the full wp-admin load if foo_doing_ajax is true
        if(isset($_POST['foo_doing_ajax']) && $_POST['foo_doing_ajax'] === true){
            header('Content-type: application/json');
            #Send a response
            echo json_encode(array('success' => true));
            exit;
            #You should keep this conditional to degrade gracefully for no JS
        }
    }
}

The only major caveat I can see is that you will need to refresh nonces on the page somehow via XHR.

For deleting a post, I’m not sure why you would want to use AJAX when it’s a simple click of a link that does the job already. Deleting a page in every case will send you to another page, namely, edit.php. This defeats the purpose of using AJAX which is to keep everything asynchronous on one page load.

Hope this helps you out.

Leave a Comment