How to update the delete user confirmation form?

On the Users (wp-admin/users.php) page, WordPress uses wp_dropdown_users() to generate the users drop-down menu you’re referring to, so I’d suggest using the wp_dropdown_users_args hook to filter the users query, e.g. to show only 1 result (or 10, but surely not 55k!) and then use JavaScript to add/load the other results.

So in this answer, I’m going to show you how you can do that, where we use Select2 to add the “type and search” functionality. Note that I’m using a custom REST API endpoint which returns the results in the format expected by Select2 and that way, the JavaScript part/code would also be simpler for us (i.e. the code is shorter).

Step #1: Filter the users query for the reassign_user drop-down menu.

function my_filter_reassign_user_query( $query_args, $parsed_args ) {
    // Make sure we're on the users.php page on the admin side.
    if ( is_admin() && 'users' === get_current_screen()->id          &&
        // .. and the action is deleting a user
        ( isset( $_GET['action'] ) && 'delete' === $_GET['action'] ) &&
        // .. and the <select>'s name is set to reassign_user.
        'reassign_user' === $parsed_args['name']
    ) {
        // You can also use 10, etc., but the point is, we don't want 55k (or
        // LOTS OF) <option> tags!
        $query_args['number'] = 1;
    }

    return $query_args;
}
add_filter( 'wp_dropdown_users_args', 'my_filter_reassign_user_query', 10, 2 );

Step #2: Enqueue the Select2 scripts and styles, and our AJAX script.

function my_enqueue_select2_scripts() {
    // Make sure we're on the users.php page on the admin side.
    if ( is_admin() && 'users' === get_current_screen()->id ) {
        wp_enqueue_style( 'select2', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/css/select2.min.css', [], null );
        wp_enqueue_script( 'select2', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/js/select2.full.min.js', [], null );

        wp_enqueue_script( 'users-ajax', '/path/to/users-ajax.js', [ 'select2', 'jquery' ], '1.0' );
        wp_localize_script( 'users-ajax', 'users_ajax', [
            'root'  => esc_url_raw( get_rest_url() ),
            'nonce' => wp_create_nonce( 'wp_rest' ),
        ] );
    }
}
add_action( 'admin_enqueue_scripts', 'my_enqueue_select2_scripts' );

Step #3: Register the custom REST API endpoint.

I’m just giving you the code, so check out the official handbook if you haven’t. You’d also want to check WP_User_Query::prepare_query() for the parameters you can use.

function my_select2_users( $request ) {
    $search   = $request->get_param( 'term' );     // the search keyword
    $per_page = $request->get_param( 'per_page' ); // results per page
    $page     = $request->get_param( 'page' );     // current page number

    $per_page = $per_page ? $per_page : 10;
    $page     = $page     ? $page     : 1;
    $args     = [
        'number'         => $per_page,
        'paged'          => $page,
        'search_columns' => [ 'user_login', 'display_name' ],
        'fields'         => [ 'ID', 'display_name', 'user_login' ],
        'who'            => 'authors',
    ];

    if ( $search ) {
        $args['search'] = '*' . sanitize_text_field( $search ) . '*';
    }

    $query = new WP_User_Query( $args );

    $items = [];
    foreach ( $query->get_results() as $user ) {
        $items[] = [
            'id'   => $user->ID,
            'text' => $user->display_name . ' (' . $user->user_login . ')',
        ];
    }

    return [
        'results'    => $items,
        'pagination' => [ 'more' => $page * $per_page < $query->get_total() ],
        'total'      => $query->get_total(),
    ];
}

add_action( 'rest_api_init', function () {
    // You should rename the my-plugin to a meaningful one..
    register_rest_route( 'my-plugin/v1', '/select2_users', [
        'methods'             => 'GET',
        'callback'            => 'my_select2_users',
        'permission_callback' => function () {
            return current_user_can( 'delete_users' );
        }
    ] );
} );

Step #4: The JavaScript/AJAX script (placed in users-ajax.js).

Check here for the Select2‘s parameters (like the ajax) you can use.

jQuery( function ( $ ) {
    $( 'select[name="reassign_user"]' ).on( 'select2:open', function () {
        $( '#delete_option1' ).prop( 'checked', true );
    } ).on( 'select2:select', function( e ) {
        $( '#submit' ).removeProp( 'disabled' );
    } ).on( 'select2:unselect', function( e ) {
        $( '#submit' ).prop( 'disabled', true );
    } ).select2( {
        ajax: {
            url: users_ajax.root + 'my-plugin/v1/select2_users',
            dataType: 'json',
            headers: { 'X-WP-NONCE': users_ajax.nonce }
        },
        minimumInputLength: 2
    } );
} );

When all code put together, you’d get something like so:

enter image description here

Leave a Comment