WordPress.org

Codex

Interested in functions, hooks, classes, or methods? Check out the new WordPress Code Reference!

Plugin API/Action Reference/quick edit custom box

Description

quick_edit_custom_box is an action that lets a plugin print inputs for custom columns when quick editing. This action is called one time for each custom column. Custom columns are added with the manage_edit-${post_type}_columns filter. To save the data from the custom inputs, hook the save_post action.

Parameters

A registered action function is passed the following parameters.

$column_name
(string) (required) The name of the column to edit.
Default: None
$post_type
(string) (required) The type of the posts.
Default: None

Note that the action function is passed neither the post ID nor any existing value for the column.

Examples

Creating Inputs

add_action( 'quick_edit_custom_box', 'display_custom_quickedit_book', 10, 2 );

function display_custom_quickedit_book( $column_name, $post_type ) {
    static $printNonce = TRUE;
    if ( $printNonce ) {
        $printNonce = FALSE;
        wp_nonce_field( plugin_basename( __FILE__ ), 'book_edit_nonce' );
    }

    ?>
    <fieldset class="inline-edit-col-right inline-edit-book">
      <div class="inline-edit-col column-<?php echo $column_name; ?>">
        <label class="inline-edit-group">
        <?php 
         switch ( $column_name ) {
         case 'book_author':
             ?><span class="title">Author</span><input name="book_author" /><?php
             break;
         case 'inprint':
             ?><span class="title">In Print</span><input name="inprint" type="checkbox" /><?php
             break;
         }
        ?>
        </label>
      </div>
    </fieldset>
    <?php
}

Saving Data

Data entered in custom inputs can be saved by hooking the save_post action.

add_action( 'save_post', 'save_book_meta' );

function save_book_meta( $post_id ) {
    /* in production code, $slug should be set only once in the plugin,
       preferably as a class property, rather than in each function that needs it.
     */
    $slug = 'book';
    if ( $slug !== $_POST['post_type'] ) {
        return;
    }
    if ( !current_user_can( 'edit_post', $post_id ) ) {
        return;
    }
    $_POST += array("{$slug}_edit_nonce" => '');
    if ( !wp_verify_nonce( $_POST["{$slug}_edit_nonce"],
                           plugin_basename( __FILE__ ) ) )
    {
        return;
    }

    if ( isset( $_REQUEST['book_author'] ) ) {
        update_post_meta( $post_id, 'author', $_REQUEST['book_author'] );
    }
    # checkboxes are submitted if checked, absent if not
    if ( isset( $_REQUEST['inprint'] ) ) {
        update_post_meta($post_id, 'inprint', TRUE);
    } else {
        update_post_meta($post_id, 'inprint', FALSE);
    }
}

Setting Existing Values

Populating inputs with existing values takes a bit of trickery. One can't simply access the $post global because when this action is run, $post refers only to the last post (the quick edit inputs are created only once, and cloned as needed when quick editing a column). There are two parts: storing the data on the page and hooking inlineEditPost.edit to set the input values. If the quick-edit columns are also displayed as custom columns, the data is already in the table. Otherwise, it can be added as hidden elements to an existing custom column.

Hooking inlineEditPost.edit must be done in a JS script, loaded after wp-admin/js/inline-edit-post.js. The original method is saved and replaced with a new one which calls the original. This particular technique is a simple example of aspect-oriented programming.

  • PHP:
    /* load script in the footer */
    if ( ! function_exists('wp_my_admin_enqueue_scripts') ):
    function wp_my_admin_enqueue_scripts( $hook ) {
    
    	if ( 'edit.php' === $hook &&
    		isset( $_GET['post_type'] ) &&
    		'book' === $_GET['post_type'] ) {
    
    		wp_enqueue_script( 'my_custom_script', plugins_url('scripts/admin_edit.js', __FILE__),
    			false, null, true );
    
    	}
    
    }
    endif;
    add_action( 'admin_enqueue_scripts', 'wp_my_admin_enqueue_scripts' );
    
    
    /* example of how an existing value can be stored in the table */
    add_action( 'manage_book_posts_custom_column' , 'custom_book_column', 10, 2 );
    function custom_book_column( $column, $post_id ) {
        switch ( $column ) {
          case 'inprint':
            // the !! means translate the following item to a boolean value
            if ( !!get_post_meta( $post_id , 'inprint' , true ) ) {
                $checked = 'checked';
            } else {
                $checked = '';
            }
            echo "<input type='checkbox' readonly $checked/>";
            break;
    
          case 'book_author':
            # ...
        }
    }
    
  • scripts/admin_edit.js:
    (function($) {
    
    	// we create a copy of the WP inline edit post function
    	var $wp_inline_edit = inlineEditPost.edit;
    
    	// and then we overwrite the function with our own code
    	inlineEditPost.edit = function( id ) {
    
    		// "call" the original WP edit function
    		// we don't want to leave WordPress hanging
    		$wp_inline_edit.apply( this, arguments );
    
    		// now we take care of our business
    
    		// get the post ID
    		var $post_id = 0;
    		if ( typeof( id ) == 'object' ) {
    			$post_id = parseInt( this.getId( id ) );
    		}
    
    		if ( $post_id > 0 ) {
    			// define the edit row
    			var $edit_row = $( '#edit-' + $post_id );
    			var $post_row = $( '#post-' + $post_id );
    
    			// get the data
    			var $book_author = $( '.column-book_author', $post_row ).text();
    			var $inprint = !! $('.column-inprint>*', $post_row ).prop('checked');
    
    			// populate the data
    			$( ':input[name="book_author"]', $edit_row ).val( $book_author );
    			$( ':input[name="inprint"]', $edit_row ).prop('checked', $inprint );
    		}
    	};
    
    })(jQuery);

Complete Code Samples

Change Log

Source File

Related

Actions

Filters