Ajax ListTable

Creating native admin tables is pretty difficult. I decided to normalize this step, by extending base WP_List_Table class and wrapping it with well-documented framework.

What you need

  • ShellPress’s namespace autoloading.
  • Knowledge about filters and actions.

Why you should use my “List Table” framework

  • It’s made with ajax. It means yoour implementation will not collide with table’s requests.
  • You can have many tables in one admin page!
  • It just works.
  • It has filters for everything, which is perfect for creating extensible plugins.

 

Start using it

  • You have to enqueue script placed in ShellPress/assets/js/AjaxListTable.js
  • Create new class which extends shellpress\vX_X_X\src\Shared\AjaxListTable
  • Declare all filters and settings in method protected function setUp(){ ... }
  • Create your new object and pass it’s slug into constructor like this:
    $listTable = new ListTable_SubscribersAjax( 'my_fancy_table );
  • Echo display root where you want it to appear.
    echo $listTable->getDisplayRoot();

     

Methods

getDisplayRoot()

Gets whole string of HTML and javascript hookup. You should echo it in place you want your table to display.

Returns:

  • string $html

generateRowCheckbox( $data )

Gets HTML of checkbox. This is perfect for content of cell cb. Data passed in parameter is then returned in ajax request, when row is selected.

Parameters:

  • mixed $data

Returns:

  • string $html

generateRowActions( $actions, $alwaysVisible = false )

Gets HTML of clickable links, called row actions.

Parameters:

  • array $actions
  • bool $alwaysVisible

Returns:

  • string $html

$actions is an array of arrays with key names.

Name of argument Type Description
title string Title of link
url string We will need that if this link is redirecting.
ajax boolean Catch it and use as action?
data mixed Anything that will be passed with action.
temp boolean Clear action after call?

Filters

All filter tags are built with table’s slug ( defined in class constructor ). If you declare your filters inside class, you can easly get it with method getSlug().


headers_<slug>

$headers is an array of arrays with key names. Column header arguments:

Name of argument Type Description
isSortable boolean Enable sorting of column?
realColumnName string You can use it in further query.
title string Title of column.
isHidden boolean Hide column?

Example of filter method:

/**
 * Define columns headers.
 *
 * @param array $headers
 *
 * @return array
 */
public function defineHeaders( $headers ) {

    $headers = array(
        'cb'                =>  array(

        ),
        'email'             =>  array(
            'isSortable'        =>  true,
            'realColumnName'    =>  'title',
            'title'             =>  "E-mail"
        ),
        'id'                =>  array(
            'isHidden'          =>  true,
            'isSortable'        =>  true,
            'realColumnName'    =>  'term_id'
        ),
        'lists'             =>  array(
            'title'             =>  __( "Lists", 'mailboo' )
        ),
        'status'            =>  array(
            'title'             =>  __( "Status", 'mailboo' )
        ),
        'createdOn'         =>  array(
            'isSortable'        =>  true,
            'realColumnName'    =>  'date',
            'title'             =>  __( "Created on", 'mailboo' ),
        ),
        'lastOpen'          =>  array(
            'title'             =>  __( "Last open", 'mailboo' )
        ),
        'statistics'        =>  array(
            'title'             =>  __( "Statistics", 'mailboo' )
        )
    );

    return $headers;

}

views_<slug>

$views is an array of keyed strings which represent clickable labels.

Example of filter method:

/**
 * Define list of views.
 *
 * @param array $views
 *
 * @return array
 */
public function defineViews( $views ) {

    //  Counting shit

    $countObj = wp_count_posts( 'subscriber' );

    $countAll = (int) array_sum( array(
        $countObj->publish,
        $countObj->future,
        $countObj->draft,
        $countObj->private,
        $countObj->pending,
        $countObj->trash,
    ) );

    $countSubscribed    = (int) $countObj->publish;
    $countUnsubscribed  = (int) $countObj->private;
    $countTrash         = (int) $countObj->trash;

    // Defining views

    $views['default']       = sprintf( '%1$s <span class="count">(%2$s)</span>', __( 'All' ), $countAll );
    $views['subscribed']    = sprintf( '%1$s <span class="count">(%2$s)</span>', __( 'Subscribed' ), $countSubscribed );
    $views['unsubscribed']  = sprintf( '%1$s <span class="count">(%2$s)</span>', __( 'Unsubscribed' ), $countUnsubscribed );
    $views['trash']         = sprintf( '%1$s <span class="count">(%2$s)</span>', __( 'Trash' ), $countTrash );

    return $views;

}

bar_actions_<slug>

These are arguments passed in filter rmethod.

  • array $barActions
  • string $currentView

It should return:

  • array $barActions

$barActions is an array of keyed arrays which are action groups. Each group then contain array of keyed components.

Remember: Each key must be unique.

Component arguments:

Name of argument Type Description
type string select or submit
temp boolean Define if action should be passed once.
select array See below ->
data mixed Only used if type is set to submit
attributes array Array of attribute values keyed with attribute tag.
title string Title of button.

Select option arguments:

Name of argument Type Description
data mixed Sent when this option is choosen.
title string Title of option.
attributes array Array of attribute values keyed with attribute tag.

Example of filter method:

/**
 * Define list of bar actions.
 *
 * @param array $barActions
 *
 * @return array
 *
 */
public function _f_defineBarActions( $barActions ) {

    $barActions = array(
        'mainBulkActions'       =>  array(
            'selectAction'          =>  array(
                'type'                  =>  'select',
                'default'               =>  '-1',
                'temp'                  =>  true,
                'select'                =>  array(
                    '-1'                    =>  array(
                        'title'                 =>  __( "Bulk actions", 'mailboo' ),
                        'data'                  =>  ''
                    ),
                    'delete'                =>  array(
                        'title'                 =>  __( "Delete", 'mailboo' ),
                        'data'                  =>  'hi'
                    ),
                    'trash'                 =>  array(
                        'title'                 =>  __( "Move to trash", 'mailboo' ),
                    )
                )
            ),
            'submit'                =>  array(
                'type'                  =>  'submit',
                'attributes'            =>  array(
                    'class'                 =>  'button'
                ),
                'title'                 =>  __( "Apply", 'mailboo' )
            )
        ),
        'bulkMoveTo'            =>  array(
            'moveToList2'           =>  array(
                'type'                  =>  'select',
                'select'                =>  array(
                    'wpUsers'               =>  array(
                        'title'                 =>  __( "From", 'mailboo' ),
                        'data'                  =>  array(
                            'listId'                =>  '14'
                        )
                    )
                )
            ),
            'moveToList'        =>  array(
                'type'              =>  'select',
                'select'            =>  array(
                    'wpUsers'           =>  array(
                        'title'             =>  __( "To", 'mailboo' ),
                        'data'              =>  array(
                            'listId'            =>  '14'
                        )
                    )
                )
            ),
            'submitMoveToList'  =>  array(
                'type'              =>  'submit',
                'attributes'        =>  array(
                    'class'             =>  'button'
                ),
                'title'             =>  __( "Move", 'mailboo' )
            )
        ),
        'singleButtonGroup'     =>  array(
            'singleButton'          =>  array(
                'type'                  =>  'submit',
                'attributes'            =>  array(
                    'class'                 =>  'button'
                ),
                'data'                  =>  'lol',
                'title'                 =>  __( "Clear cache", 'mailboo' )
            )
        ),
    );

    return $barActions;

}

 

items_<slug>

This filter defines items returned at certain conditions in table.

These are arguments passed in filter rmethod.

  • array $items
  • int $itemsPerPage
  • int $paged
  • string $search
  • string $order
  • string $orderBy
  • string $view
  • array $actions

It should return:

  • array $items

Example of filter method:

/**
 * Load items and sets total num.
 *
 * @param WP_Post[] $items
 * @param int $itemsPerPage
 * @param int $paged
 * @param string $search
 * @param string $order
 * @param string $orderBy
 * @param string $view
 * @param array $actions
 *
 * @return array
 */
public function loadItems( $items, $itemsPerPage, $paged, $search, $order, $orderBy, $view, $actions ) {

    //  Defining post status by $view

    switch( $view ){

        case 'subscribed':
            $postStatus = 'publish';
            break;

        case 'unsubscribed':
            $postStatus = 'private';
            break;

        case 'trash':
            $postStatus = 'trash';
            break;

        default:
            $postStatus = array( 'any', 'trash' );
            break;

    }

    //  Query

    $queryArgs = array(
        'post_type'         =>  'subscriber',
        'post_status'       =>  $postStatus,
        's'                 =>  $search,
        'posts_per_page'    =>  $itemsPerPage,
        'paged'             =>  $paged,
        'order'             =>  $order,
        'orderby'           =>  $orderBy
    );

    $query = new WP_Query( $queryArgs );

    $this->setTotalItems( $query->found_posts );

    $items = $query->posts;

    return $items;

}

 

cell_<slug>_<cell_id>

Controls display of specific cells.

These are arguments passed in filter rmethod.

  • string $html
  • mixed $item

It should return:

  • string $html

Example of cell which displays row checkbox.:

/**
 * Sets output of cell `cb`.
 *
 * @param string $html
 * @param WP_Post $item
 *
 * @return string
 */
public function cellCb( $html, $item ) {

    $html = $this->generateRowCheckbox( $item->ID );

    return $html;

}

Actions

All action tags are built with table’s slug ( defined in class constructor ). If you declare your actions inside class, you can easly get it with method getSlug().


actions_<slug>

This action is called once and passes whole array of actions data. It’s called before table display, so you can use them to manipulate your data, etc.

You have to find out which action you want to process.

These are arguments passed in action rmethod.

  • array $currentActions
  • array $selectedItems
/**
 * @param array $currentActions
 * @param array $selectedItems
 */
public function moveToList( $currentActions, $selectedItems ) {

    if( isset( $currentActions['funkyShit'] ) ){
    
        //  DO SOMETHING HERE
            
        //  ...
    
    }

    $this->addNotice( "Got it!", 'notice-success' );

}