Add screen options to custom admin pages

I want to add screen options to my plugin settings page, like the ones that are available in the Dashboard.

enter image description here

Read More

I tried using the add_option method of the WP_Screen object and found that it supports only two options. per_page and layout_columns.

Does anyone know what screen option to use to get options like the one in Dashboard page?

Edit:

Let me explain what I am trying to a little bit.

I have different sections in my Bulk Delete Plugin and each section let’s people delete posts based on some criteria (like category, tags, custom taxonomy etc). I want to let users choose which sections they want to use and which sections that they want to hide, similar to the Dashboard page, where users can choose which dashboard widgets they want to see and which ones to hide.

Now, to implement this, I want to show a list of checkboxes (one for each section) and let user choose which one to show.

To show the list of checkboxes, I had to call the add_option method of the WP_Screen object. When I was doing that, I figured out that currently add_option function only supports these two types and the others are just ignored.

  • per_page
  • layout_columns

But, only in the dashboard page checkboxes are shown. I want to know how to replicate a similar thing in the screen options section of my custom admin page as well.

Related posts

3 comments

  1. You don’t need to invent a new screen option row. Just use proper metaboxes.

    Currently, you are drawing pseudo-metaboxes:

    <!-- Post status start-->
            <div class = "postbox">
                <div class = "handlediv"> <br> </div>
                <h3 class = "hndle"><span><?php _e("By Post Status", 'bulk-delete'); ?></span></h3>
            <div class = "inside">
            <h4><?php _e("Select the posts which you want to delete", 'bulk-delete'); ?></h4>
    

    You should do this:

    <div id="post-body-content">
        <!-- #post-body-content -->
    </div>
    
    <div id="postbox-container-1" class="postbox-container">
        <?php do_meta_boxes('','side',$object); ?>
    </div>
    
    <div id="postbox-container-2" class="postbox-container">
        <?php do_meta_boxes('','normal',$object); ?>
        <?php do_meta_boxes('','advanced',$object); ?>
    </div>
    

    Then register your own metaboxes with add_meta_box().

    Read Meta Boxes on Custom Pages from Stephen Harris for all the details (demo on GitHub).
    The main point is: You will get the screen options for these boxes for free.

    And when WordPress changes the inner markup for metaboxes one day, your code will probably still work, because you have used the API.

  2. You can do it, by using the proper filter inside the WP_Screen class. Just make sure that you don’t switch it on per default:

    How to show or hide the tab

    The following filter shows how to show or hide the tab. Actually, as there is a better filter, the following way is of more use if you need to force hide the tab when it already exists:

    add_filter( 'screen_options_show_screen', function( $show, WP_Screen $screen )
    {
        // Navigate to the screen of choice and uncomment the following line to find out the 'base' val
        // var_dump( $screen );
        return 'your_screen_id' !== $screen->base
            ? $show
            : true;
    }, 10, 2 );
    

    How to show the tab and add custom content

    The following shows a settings tab containing an input field that holds the value amount that you could use in any way on your page (for e.g. limitting results of $wpdb query).

    /**
     * @param string     $settings
     * @param WP_Screen $screen
     */
    add_filter( 'screen_settings', function( $settings, WP_Screen $screen )
    {
        if ( 'your_screen_id' !== $screen->base )
            return $settings;
    
        $amount = isset( $_GET['paged'] ) 
            ? filter_var(
                absint( $_GET['paged'] ),
                FILTER_SANITIZE_NUMBER_INT,
                FILTER_NULL_ON_FAILURE
            ) 
            : 1;
    
        return sprintf(
            '<label for="amount">Amount:</label> '
            .'<input step="1" min="1" max="999" class="screen-per-page" name="amount" val="%d">',
            .get_submit_button( 'Set', 'secondary', 'submit-amount', false ),
            $amount
        );
    }, 10, 2 );
    
  3. Here is a full, concise example based on the Meta Boxes on Custom Pages by Stephen Harris:

    Same code as a gist

    <?php
    
    /**
     * Plugin Name:     LHF Volunteer Form
     * Description:     Manages a google-sheet full of names and emails
     * Plugin URI:      http://ladehammerfestivalen.no/volunteer
     * Author URI:      http://genja.org
     * Author:          jazzoslav@gmail.com
     * Text Domain:     lhf-volunteer-form
     * Domain Path:     /languages
     * Version:         0.2.0
     * @package         Lhf_Volunteer_Form
     */
    
    require_once  __DIR__ . '/vendor/autoload.php';
    
    use LhfSheetRegistrationsSheet;
    
    frivilligSystemMain();
    
    function frivilligSystemMain() {
        try {
            $regSheet = LhfSheetRegistrationsSheet::createInWordPress();
        } catch (Exception $ex) {
            error_log(sprintf('%s:%d %s', __FILE__, __LINE__, $ex->getMessage()));
        }
        add_action('init', function() use ($regSheet) {
            if (is_admin()) {
                add_action( 'admin_menu', function() use ($regSheet) {
                    $screenId = DashboardView::screen_id;
                    $pageId = add_dashboard_page( 'hammerater', 'Hammerater', 'endre_frivillig_skjema', $screenId,
                        function () use ($regSheet) { DashboardView::renderVolunteerDashboard($regSheet); } );
                    add_action("load-$pageId", function() use ($regSheet, $pageId, $screenId) {
                        wp_enqueue_script('postbox');
                        add_screen_option('layout_columns', array('max' => 2, 'default' => 2) );
                        do_action("add_meta_boxes_$screenId", null); // allow third parties to hook into this.
                        do_action('add_meta_boxes', $screenId, null); // allow third parties to hook into this.
                    });
                    add_action("add_meta_boxes_$screenId", function () use ($regSheet) { DashboardView::registerMetaboxes($regSheet); });
                });
            }
        });
    }
    
    class DashboardView
    {
        const screen_id = 'frivillig-liste';
    
        private static function includeAdminHeader()
        {
            require_once( ABSPATH . 'wp-admin/admin.php');
            require_once( ABSPATH . 'wp-admin/includes/dashboard.php');
            require_once( ABSPATH . 'wp-admin/admin-header.php');
            wp_dashboard_setup();
            wp_enqueue_script( 'dashboard' );
            add_thickbox();
            do_action( 'add_meta_boxes' );
            if ( wp_is_mobile() ) {
                wp_enqueue_script( 'jquery-touch-punch' );
                //wp_dequeue_script('jquery-migrate');
            }
    
            wp_enqueue_script( 'datatables', '//cdn.datatables.net/1.10.16/js/jquery.dataTables.js');
            wp_enqueue_style( 'datatables', '//cdn.datatables.net/1.10.16/css/jquery.dataTables.css');
    
            wp_enqueue_script( 'datatables-responsive', '//cdn.datatables.net/responsive/2.2.1/js/dataTables.responsive.min.js');
            wp_enqueue_style(  'datatables-responsive', '//cdn.datatables.net/responsive/2.2.1/css/responsive.dataTables.min.css');
    
            wp_enqueue_script( 'datatables-row-group', '//cdn.datatables.net/rowgroup/1.0.2/js/dataTables.rowGroup.min.js');
            wp_enqueue_style(  'datatables-row-group', '//cdn.datatables.net/rowgroup/1.0.2/css/rowGroup.dataTables.min.css');
        }
    
        static function renderVolunteerDashboard(RegistrationsSheet $regSheet) {
            static::includeAdminHeader();
            wp_enqueue_script('lhf-sheets');
            $workTypes = get_option( 'lhfsheets_form_work_types' );
            ?>
            <div class="wrap">
                <form>
    <?php
            wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
            wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
    ?>
                <h1>Frivillige Hammerater</h1>
                <h2 class="nav-tab-wrapper">
                    <a href="<?= admin_url( 'index.php?page=frivillig-liste&tab=liste' ) ?>" >Liste</a>
                    <a href="<?= admin_url( 'index.php?page=frivillig-liste&tab=preferanser' ) ?>">Arbeidsposter</a>
                    <a href="<?= admin_url( 'index.php?page=frivillig-liste&tab=info' ) ?>">Frivilliginfo</a>
                </h2>
                <?php
                $screen      = get_current_screen();
                $columns     = absint( $screen->get_columns() );
                $columns_css = '';
                if ( $columns ) {
                    $columns_css = " columns-$columns";
                }
                ?>
    
                <?php if ( $_GET['tab'] == 'liste' || ! $_GET['tab'] ) { ?>
                    <div id="dashboard-widgets" class="metabox-holder<?php echo $columns_css; ?>">
                        <div id="postbox-container-1" class="postbox-container">
                            <?php do_meta_boxes( $screen->id, 'main_list', '' ); ?>
                        </div>
                    </div>
                <?php } ?>
    
                <?php if ( $_GET['tab'] == 'preferanser' || ! $_GET['tab'] ) { ?>
                    <div id="dashboard-widgets" class="metabox-holder<?php echo $columns_css; ?>">
                        <div id="preferences-sortables" class="postbox-container">
                            <?php do_meta_boxes( $screen->id, 'preferences', ''); ?>
                        </div>
                        <div id="preferences_left-sortables" class="postbox-container">
                            <?php do_meta_boxes( $screen->id, 'preferences_right', ''); ?>
                        </div>
                    </div>
                <?php } ?>
                <?php if ( $_GET['tab'] == 'info' ) { ?>
                            <h3>Annen info</h3>
                <?php } ?>
                </form>
            </div>
            <?php
        }
    
        static function renderMainList($records, $status = 'registered/served/contacted') {
            /** @var Frivillig $e */
            ?>
            <div class="main">
              <table id="frivillige-hammerater-<?= $status ?>" style="display:none" data-status="<?= $status ?>">
                <?php foreach ($records as $e) { ?>
                  <tr> ...  </tr>
                <?php } ?>
                </tbody>
              </table>
            </div>
            <?php
        }
    
        public static function registerMetaboxes( RegistrationsSheet $regSheet ) {
            if ($_GET['tab'] == 'info') { return; }
            $all = $regSheet->getVolunteerRecords();
            if ($_GET['tab'] == 'liste' || $_GET['tab'] === null) {
                foreach (Frivillig::states() as $state) {
                    add_meta_box(
                        "volunteers-search-all",
                        __('Verktøy') ,
                        function () use ($state) { DashboardView::renderGlobalSearchMetaBox(); },
                        'dashboard_page_frivillig-liste',
                        'main_list'
                    );
    
                    $peopleWithState = [];
                    foreach ($all as $f) { if ($f->status === $state) { $peopleWithState[] = $f; } }
    
                    add_meta_box(
                        "volunteers-$state",
                        DashboardView::$stateName[$state],
                        function () use ($peopleWithState, $state) { DashboardView::renderMainList($peopleWithState, $state); },
                        'dashboard_page_frivillig-liste',
                        'main_list'
                    );
                }
            }
    
            if ($_GET['tab'] == 'preferanser') {
                $workTypes = get_option('lhfsheets_form_work_types');
                foreach ($workTypes as $workType) {
                    $workers = [];
                    foreach ($all as $frivillig) {
                        $interests = preg_split('/,s+/', $frivillig->interests);
                        if (in_array($workType['slug'], $interests)) {
                            $workers[] = $frivillig;
                        }
                    }
                    add_meta_box(
                        "volunteer-prefers-{$workType['slug']}",
                        $workType['description'],
                        function () use ($workers, $workType) { DashboardView::renderPreferences($workers, $workType); },
                        'dashboard_page_frivillig-liste',
                        'preferences'
                    );
                }
            }
        }
    
        public static function renderPreferences($workers, $workType) { ?>
            <ul>
                <?php foreach ($workers as $e) { ?>
                <li data-id="<?= $e->id ?>"> ...  </li>
                <?php } ?>
            </ul>
            <?php
        }
    
        private static function renderGlobalSearchMetaBox() {
            ?> Søk: <input type="text" onkeydown="window.populateSearchFields(event)" placeholder="<?= __('i alle tabellene') ?>  "> <?php
        }
    }
    

    references

    https://codex.wordpress.org/Dashboard_Widgets_API

Comments are closed.