Adding Custom Field to WordPress Quick Edit UI for Custom Post Type

Adding a custom field to the WordPress Quick Edit screen for a custom post type was a rather tricky task, so I wanted to be sure to share my solution with my readers in case any of you have a difficult time with it as well.

Let's get our hands dirty shall we?

There are six basic high level steps to adding a field to quick edit which are:

  1. Add a new column to the posts screen for the post type - I thought this was not necessary at first, but I assure you that it is 100% required for the new field to work within the quick edit UI. Therefore if this turns you off, you can surely find a way to hide the field from view if you don't want it to show up on the posts admin screen.
  2. Fill the column you added in the previous item with data - While this step isn't actually required for the field to work in the quick edit screen, it is needed if you wish for the column to have relevant data in it. However, if you wish to hide the column as I suggested could be done, then you may surely skip this step. I don't recommend skipping it however.
  3. Add HTML code to the Quick Edit User Interface - this will be accomplished, as you'll soon see below, with WordPress's quick_edit_custom_box action hook and your custom HTML for your custom field.
  4. Save the new custom field's value that you've added to the Quick Edit UI - This can be easily achieved by making use of the WordPress save_post action hook as you will discover below.
  5. Add some JavaScript code in the admin page's footer to update your custom fields value within Quick Edit UI - this is where it gets a little tricky for some. I'll explain as best I can below, but suffice it to say for now that you have to update the input field you created in the quick edit menu with JavaScript that's generated with PHP code using WordPress's admin_footer hook. I have seen some alterations of this in other posts online where people use JQuery, but I tend to find that using JQuery is often more likely to lead to plugin conflicts if you are not very careful, so I prefer to use plain JavaScript whenever possible.
  6. Finally you'll need to link your JavaScript function from the previous step to the Quick Edit link for each post using a JavaScript OnClick event - this is done with the elusive WordPress filter named post_row_actions that allows you to change the context of the Quick Edit link itself with some PHP magic.

Now that the high level steps have been explained in very little detail to give you an idea of what we'll be doing in this tutorial, I will demonstrate each step with a working code example that you can use to paste into your own Plugin or Theme files as needed. If you don't know where to paste the code, then frankly, this tutorial may not be for you, so I won't go into that part in detail since this tutorial is really meant for plugin developers and all of them surely know where to place the code I'll be showing below.

Step 1 - Add a new column to the posts screen for the post type

Step 1 is by far the easiest step with very little code. All we need to accomplish here is to add a column to the Custom Post Type admin screen. Here is the simple PHP code:

<?php

//Add groomer Column to dogs CPT:
add_filter('manage_dogs_posts_columns', 'dogs_groomer_post_column');
 
function dogs_groomer_post_column($columns) {
    $columns['groomer'] = 'groomer';
    return $columns;
}//end dogs_groomer_post_column PHP function

?>

Not a lot you need to do to the above code but change the custom post type name and the field name to your own CPT and Custom Field Name, so search and replace "dogs" with the name of your Custom Post Type. Then search and replace "groomer" with your custom field name. Your now done with step 1! Don't worry, they will get harder!

Step 2 - Fill the column you added in the previous item with data

Now all we have to do in step 2 is fill our column from step 1 with relevant data. In our case, the name of the groomer for each dog in the dogs custom post type. Here's the PHP code:

<?php

//Add content to new groomer Column in wp-admin for dogs cpt:
add_action('manage_posts_custom_column', 'render_groomer_column_for_dogs', 10, 2);
 
function render_groomer_column_for_dogs($column_name, $id) {
    switch($column_name) {
    case 'groomer':
        // show groomer
        $groomer_val = get_post_meta( $id, '_groomer', TRUE);
        if($groomer_val == '')$groomer_val = 'None';
        echo $groomer_val;              
        break;
    }
}//end render_groomer_column_for_dogs PHP Function

?>

Again, all you have to do to make this code your own is replace "dogs" with the name of your custom post type and replace "groomer" with the name of your custom field and be sure to get the ones with the underscore in front of them too! I like to put underscores in front of field names when saving them to the database. That's all for step 2! Another easy one! Okay on to step 3.

Step 3 - Add HTML code to the Quick Edit User Interface

In step 3 we have to add a PHP function using the quick_edit_custom_box WordPress hook that adds HTML content to the Quick Edit User Interface. Here's the PHP code:

<?php

//add groomer to quick edit screen:
add_action('quick_edit_custom_box',  'CCRM_add_groomer_to_quick_edit', 10, 2);
 
function CCRM_add_groomer_to_quick_edit($column_name, $post_type) {
    if($column_name != 'groomer') return;
    ?>
    <fieldset class="inline-edit-col-left">
    <div class="inline-edit-col">
        <input type="hidden" name="groomer_noncename" id="groomer_noncename" value="" />
<label for="groomer_status"><?php _e('groomer: ', 'dogs'); ?><select name="groomer_status" id="groomer_status">
    <option>-Pick one-</option>
    <option>Ted Dogly</option>
    <option>Teresa Lassie</option>
    <option>Megan Dame</option>
    <option>Star Wolfe</option>
    <option>Joan Smith</option>
    <option>Dober Mann</option>
    </select></label>
    </div>
    </fieldset>
    <?php
}//end CCRM_add_groomer_to_quick_edit PHP function

?>

Again to make the above code your own, you'll want to replace all occurrences of dogs and groomer with your own names as in the previous two steps. Another option you may wish to change in the above code will be the input type. Here we have decided to use a select input to create a drop-down of possible groomer names to assign to each dog. You may prefer to use a text field, checkbox or even a textarea here, you can use any form element you want to collect your custom field's data. Simply change the above code to fit your individual needs and your done with step 3!

Step 4 - Save the new custom field's value that you've added to the Quick Edit UI

In step 4, we save the new custom field value to the WordPress database when it is edited from the Quick Edit dialog. As with all the previous steps, change the names of dog and groomer according to your own post type and field name respectively. In the below code we use the common "save_post" WordPress hook to detect when a new field value is submitted and save it with the following PHP code:

<?php

//save groomer for quick edit screen:
add_action('save_post', 'save_groomer_quick_edit_data');
 
function save_groomer_quick_edit_data($post_id) {
    $post = get_post($post_id);
    //verify if this is an auto save routine. If it is our form has not been submitted, so we dont want to do anything:
    if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
        return $post_id;    
    //Check permissions
    if('dogs' == $post->post_type){
        if(!current_user_can('edit_page', $post_id ))
            return $post_id;
    }   
    //OK, we're authenticated: we need to find and save the data
    
    if(isset($_POST['groomer_status']) && ($post->post_type != 'revision')) {
        $groomer = esc_attr($_POST['groomer_status']);
        if ($groomer)
            update_post_meta($post_id, '_groomer', $groomer);     
        else
            delete_post_meta($post_id, '_groomer');     
    }       
    if(!isset($groomer))$groomer='';
    return $groomer;  
}//End save_groomer_quick_edit_data PHP function

?>

The above code is fairly straight forward, so simply change dogs and groomer text as with previous steps and move on to step 5 below.

step 5 - Add some JavaScript code in the admin page's footer to update your custom fields value within Quick Edit UI

Here is where it gets a little tricky! There's no simple PHP code to update the Quick Edit UI with the latest updated field value, so we have to generate some JavaScript with the following PHP code. We'll use the admin_footer WordPress hook to inject JS code into the footer of the admin page like so:

<?php

//add JS to footer that updates quick edit dropdown:
add_action('admin_footer', 'groomer_quick_edit_JS');
 
function groomer_quick_edit_JS() {
    global $current_screen;
    if(($current_screen->id != 'edit-dogs') || ($current_screen->post_type != 'dogs')) return;
     
    ?>
    <script type="text/javascript">
    <!--
    function replace_quick_edit_link(widgetSet, nonce) {
        //alert('set_inline....');
        //revert Quick Edit menu so that it refreshes properly
        inlineEditPost.revert();
        var widgetInput = document.getElementById('groomer_status');
        var nonceInput = document.getElementById('groomer_noncename');
        nonceInput.value = nonce;
        //check option selected
        for(i = 0; i < widgetInput.options.length; i++) {
            if(widgetInput.options[i].value == widgetSet) {
                widgetInput.options[i].setAttribute("selected", "selected");
            }else{widgetInput.options[i].removeAttribute("selected");}
        }
    }//End replace_quick_edit_link JavaScript Function
    //-->
    </script>
    <?php
}//End groomer_quick_edit_JS PHP function

?>

Now the above code maybe a little complicated for some, especially those of you who want to use a different type of form field rather than use the drop-down select like in our code. Where you see the section of code that has the comment "//check option selected" before it is where you'll need to make significant code changes if you use anything other than a select field in your own code. Also be sure to also change all occurrences of dog and groomer as in each of the previous steps.

Step 6 - Link your JavaScript function from step 5 to the Quick Edit link for each post using a JavaScript OnClick event

Next due to the fact that it's impossible to update the option updated in the quick edit UI, we use the following PHP and JS magic to make it happen with the help of the WordPress post_row_actions filter hook:

<?php

//code to modify quick edit link with on-click event:
add_filter('post_row_actions', 'groomer_expand_quick_edit_link', 10, 2);
 
function groomer_expand_quick_edit_link($actions, $post) {
    global $current_screen;
    if (($current_screen->id != 'edit-dogs') || ($current_screen->post_type != 'dogs')) return $actions;
 
    $nonce = wp_create_nonce('groomer'.$post->ID);
    $groomer_val = get_post_meta($post->ID, '_groomer', TRUE);
    $actions['inline hide-if-no-js'] = '<a href="#" class="editinline" title="';
    $actions['inline hide-if-no-js'] .= esc_attr(__( 'Edit this item inline' ) ) . '" ';
    $actions['inline hide-if-no-js'] .= " onclick=\"replace_quick_edit_link('{$groomer_val}', '{$nonce}')\">";
    $actions['inline hide-if-no-js'] .= __( 'Quick&nbsp;Edit' );
    $actions['inline hide-if-no-js'] .= '</a>';
    return $actions;    
}//end groomer_expand_quick_edit_link PHP function

?>

Changing each occurrence of dogs and groomer in the above code should be sufficient in most cases to make it your own. Good luck!

Going a Step Further with Bulk Edit Ability Too!

Okay, this technically makes it seven steps instead of six, but I added this as an afterthought because it is so easy to add the bulk edit feature to the above code. All you have to do in order to make the same custom field from the above code show up in the bulk edit screen or UI, is add one line of code! Therefore I thought it wise to add it here.  Here is how:

If you look above at step 3, the first line of PHP code is the quick edit hook which looks like this:

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

All you have to do to also make the same field show up in the bulk edit screen too is add the following code that contains the bulk_edit_custom_box hook in place of the quick_edit_custom_box hook in the above line of code like this:

add_action('bulk_edit_custom_box',  'CCRM_add_groomer_to_quick_edit', 10, 2);

That's it! you can add the above l line directly before or after the quick_edit_custom_box hook as in step 3 above. Now if you select all posts from the custom post type screen and then in the "bulk actions" dropdown, select "edit" and you can edit the new custom field value for all of your posts at one time! Yes, we saved the simple step for last! Enjoy your new bulk and quick editor plugin!

Summary

In conclusion, you'll want to incorporate the above code examples into your own plugin for best results. I have created such a plugin for anyone who needs it. Please feel free to contact me by email at linnian11@yahoo.com if you would like the plugin.

Leave a Reply

Your email address will not be published. Required fields are marked *