Custom bulk_action

I would like to add a custom bulk action to a custom post type. I came across the filter bulk_actions-screenid, which according to its documentation, would do exactly as I wish. However, after about two hours of debugging I found the following comment // This filter can currently only be used to remove actions. on line 278 of class-wp-list-table.php – great!

I figured I could hack it by using jQuery to inject the action as an option

Read More
/**
 * Hack to add a custom bulk action. 
 */
public function admin_footer() {
    if($_GET['post_type'] != self::POST_TYPE) return;
    ?> 
    <script type="text/javascript">
        jQuery(document).ready(function() {
            jQuery('<option>').val('create_invoice').text('Bill').appendTo("select[name='action']");
        });
    </script>
    <?php
}

This works. The action now appears in the bulk actions menu. I was under the assumption I could then add some logic into admin_init to do the necessary processing – however, it appears that create_invoice is never posted. Is there something I’m doing wrong?

=== UPDATE ===

I updated the code to use the load-* hook. When I apply the bulk action on users.php – I see create_invoice is passed through the request. However, on edit.php create_invoice is never printed.

function a39x2_admin_footer() {
    ?>
    <script type="text/javascript">
        jQuery(document).ready(function() {
            jQuery('<option>').val('create_invoice').text('Bill').appendTo("select[name='action']");
            jQuery('<option>').val('create_invoice').text('Bill').appendTo("select[name='action2']");
        });
    </script>
    <?php
}
add_action('admin_footer', 'a39x2_admin_footer');


function a39x2_load() {
    echo "<pre>" . print_r($_REQUEST, true) . "</pre>";
}
add_action('load-edit.php', 'a39x2_load');
add_action('load-users.php', 'a39x2_load');

Related posts

Leave a Reply

3 comments

  1. I think the latest major release warrants a new answer to this question, considering the popularity of this question.

    Since WordPress 4.7 (released December 2016) it is possible to add custom bulk actions without using JavaScript.

    The filter bulk_actions-{$screen} (e.g. bulk_actions-edit-page for the pages overview) now allows you to add custom bulk actions. Furthermore, a new action called handle_bulk_actions-{$screen} (e.g. handle_bulk_actions-edit-page) allows you to handle execution of the action.

    This is all explained pretty well in this blog post.
    For example, let’s say we want to add a bulk action to email the titles of the selected items on the pages overview. We could do it like this:

    For a small example, where we add an action to the bulk actions dropdown and add a handler function to it.

    Adding the bulk action to the dropdown:

    function wpse29822_page_bulk_actions( $actions ) {
        // Add custom bulk action
        $actions['my-action-handle'] = __( 'My Custom Bulk Action' );
        return $actions;
    }
    add_action( 'bulk_actions-edit-page', 'wpse29822_page_bulk_actions' );
    

    Adding a handler for the bulk action:

    function wpse29822_page_bulk_actions_handle( $redirect_to, $doaction, $post_ids ) {
        // Check whether action that user wants to perform is our custom action
        if ( $doaction == 'my-action-handle' ) {
            // Do stuff
        }
        return $redirect_to;
    }
    add_action( 'handle_bulk_actions-edit-page', 'wpse29822_page_bulk_actions_handle', 10, 3 );
    
  2. The bulk_actions-* filter doesn’t allow you to add custom bulk actions precisely because it’s tricky to then add a handler for a that action. Updated the Codex.

    I would suggest using the load-* action instead of admin_init. Note that you have to do all the security checks like check_ajax_referrer() and current_user_can().

  3. You must use bulk_actions filters when WP_Screen object is defined.
    like this:

    add_action( 'current_screen', 'custom_bulk_actions' );
    function custom_bulk_actions() {
        if( current_user_can( 'administrator' ) {
            add_filter( 'bulk_actions-edit-post'       , 'register_custom_bulk_actions' );
            add_filter( 'handle_bulk_actions-edit-post', 'custom_bulk_action_handler', 10, 3 );
            add_action( 'admin_notices'                , 'custom_bulk_action_admin_notice' );
        }
    }