0

I've been looking around for this for a while but haven't found anything as of yet.

I have a custom post type - "books" and this post type has a custom meta field of "availability".

I would like to have a column for the post type that you can click on the availability link and it would change the custom meta value from "yes" to "no" and update the text link to display either "yes" for the value being yes or "no" for the value being no.

I have made the post column, and I have got the column displaying the value, just need to get it to work with ajax which is where I have no idea where to start!

I have studied a plugin I found on here not long back about changing a post status from a column using ajax but I cant see how to change this to work with custom meta values - Custom column for changing post status via ajax

I would love any help or even pointing in the right direction with this as it has been eating away at me for days now!

1 Answer 1

1

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.

1
  • Thank you, this is perfect! After some adaptation this is working perfectly! May 4, 2013 at 17:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.