Change Post Meta via AJAX from the posts list table

There are some issues with the solution in the linked answer. But it is a good starting point for it.

Basically you have to change only the method ajax_change_status(). This method changes the post status, but you want to change a post meta.

In short, this is the final class with some fixings

/**
 * Plugin Name: Change Book Availability On Post List
 * Plugin URI:  http://wordpress.stackexchange.com/questions/98295/change-post-meta-via-ajax-from-the-posts-list-table
 * Description: Changing the status of availability in post list
 * Version:     0.1
 * Author:      Ralf Albert
 * Author URI:  http://yoda.neun12.de
 * License:     GPLv3
 */


if ( ! class_exists( 'Ajax_Book_Status' ) ) {

class Ajax_Book_Status
{

    public $metakey = 'book_status';

    //constarctor
    public function __construct() {

        global $pagenow,$typenow; //&& $typenow =='page'

        if ( is_admin()  && $pagenow=='edit.php' )
            add_filter('admin_footer',array( $this,'insert_ajax_status_script' ) );

        add_filter( 'manage_edit-post_columns', array( $this,'add_new_columns' ) );
        add_action( 'manage_post_posts_custom_column', array( $this, 'manage_columns' ), 10, 2 );

        //manage columns
        add_filter( 'manage_pages_columns', array( $this,'add_new_columns' ) );
        add_action( 'manage_pages_custom_column', array( $this, 'manage_columns' ), 10, 2 );

        //ajax function
        add_action( 'wp_ajax_change_book_status', array( $this,'ajax_change_book_status' ) );
    }

    /**
     * the function that will actually change the post status
     *
     * $post_id - The ID of the post you'd like to change.
     * $status -  The post status yes|no
     */
    public function ajax_change_book_status(){

        $result="";
        $new_postmeta="";
        $postid = filter_input( INPUT_GET, 'post_id', FILTER_SANITIZE_NUMBER_INT );

        if ( ! isset( $postid ) )
            $result="something went wrong ...";

        $old_postmeta = (string) get_post_meta( $postid, $this->metakey, true );

        // if no status was saved, predefine the new status to no.
        if ( ! in_array( $old_postmeta, array( 'yes', 'no' ) ) ) {
            $old_postmeta="no";
        }

        $new_postmeta = ( $old_postmeta === 'yes' ) ?
            'no' : 'yes';


        if ( empty( $result ) )
            $result="change status to " . $new_postmeta;

        update_post_meta( $postid, $this->metakey, $new_postmeta, $old_postmeta );

        header( 'Content-type: application/json' );
        die( json_encode( array( 'data' => $result, 'text' => ucfirst( $new_postmeta ) ) ) );
    }

    /*
     ****************************
    * manage columns functions *
    ****************************
    */

    //add new columns function
    public function add_new_columns( $columns ){
        $columns['status']= __('Status');
        return $columns;
    }

    //render columns function
    public function manage_columns( $column_name, $id ) {

        // bail if it is not our column
        if ( 'status' !== $column_name )
            return;

        $status = get_post_meta( $id, $this->metakey, true );

        if ( ! in_array( $status, array( 'yes', 'no' ) ) )
            $status="no";

        printf( '<div class="book-status"><a href="#" class="book-availability" pid="%d">%s</a></div>', $id, ucfirst( $status ) );

    }


    //js/jquery code to call ajax
    public function insert_ajax_status_script(){
        ?>
            <script type="text/javascript">

            jQuery(document).ready(
                function($){
                    $( '.book-availability' ).click(
                        function(){
                            link = $(this);
                            $.get(
                                ajaxurl,
                                {
                                    'action'  : 'change_book_status',
                                    'post_id' : $(this).attr( 'pid' )
                                },
                                function(result){
                                    if( '' !== result.text )
                                        link.text( result.text );
                                    else
                                        alert( result.data );
                                }
                            );
                        }
                    );
                }
            );

            </script>
            <?php
        }

}
}

add_action( 'plugins_loaded', 'bookstatuscolumn' );

function bookstatuscolumn(){
    new Ajax_Book_Status();
}

As you can see, the part with inserting the new column is nearly untouched. Just a few adjustments.

The basic changing is to register the method ajax_change_book_status() as an ajax callback. The method request the postmeta, switch between yes and no and store the new status. That’s all.

You have to adjust the metakey value at the beginning of the calss to the key you use in your own postmeta.