WP List Table Tutorial – Add Action Links To List

We create wordpress admin tables using WP_List_Table class to show data. In this tutorial we will see how to add action links to WordPress admin table.

Action links are links for edit / delete etc which provide you the option to perform any action to your list. This is also a bit logical implementation you need to focus on.

Here is an example image. Probably while working with wordpress admin tables of Post, Pages, Users, etc you may or may not seen this action links.

We can see here the links for Edit, Delete with each row of Username. When we click on any link then associated operation will be performed. WP_List_Table provides a method to add these action links to any specific column of list table.

Add Action Links To List

Here is the code to add a action links to list table.

// Adding action buttons to column
function column_user_login($item)
{
    $actions = array(
            'edit'      => sprintf('<a href="?page=%s&action=%s&employee=%s">Edit</a>', $_REQUEST['page'], 'edit', $item['ID']),
            'delete'    => sprintf('<a href="?page=%s&action=%s&employee=%s">Delete</a>', $_REQUEST['page'], 'delete', $item['ID']),
    );

    return sprintf('%1$s %2$s', $item['user_login'], $this->row_actions($actions));
}

Function name should be in this format like column_{column_identifier}. Inside this function we have $actions array of links. Links for edit and delete. sprintf() is a PHP function.

$item[‘ID’] and $item[‘user_login’], ID and user_login are key identifiers for table columns.

After adding above code, inside user_login key it will add action links for Edit and Delete. Functionality for Edit and Delete, you need to do code for it. It adds only the links to your column.

Initially the links will be visible when you hover on column row value. To remove the hide and show visible from links, simply add this CSS code into your table.

<style>#the-list .row-actions{left:0;}</style>

#the-list is the ID of your table.

Method to handle action link operations

We need to add these operational lines prepare_items() method. Also we can define these handler lines into separate method and call it inside prepare_items() method.

// edit
if (isset($_GET['action']) && $_GET['page'] == "employees_list_table" && $_GET['action'] == "edit") {
        $empID = intval($_GET['employee']);

        //... do operation
}

// delete
if (isset($_GET['action']) && $_GET['page'] == "employees_list_table" && $_GET['action'] == "delete") {
        $empID = intval($_GET['employee']);

        //... do operation
}

Plugin Setup

Here, is the complete code of plugin.

<?php
/*
Plugin Name:  Simple Employees Table
Description: It displays a table with employee data
Author: Online Web Tutor
Author URI: https://onlinewebtutorblog.com/
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: basic-wp-list-table
Version: 1.0
*/

// Loading table class
if (!class_exists('WP_List_Table')) {
      require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
}

// Extending class
class Employees_List_Table extends WP_List_Table
{
      private $users_data;

      private function get_users_data($search = "")
      {
            global $wpdb;

            if (!empty($search)) {
                  return $wpdb->get_results(
                        "SELECT ID,user_login,user_email,display_name from {$wpdb->prefix}users WHERE ID Like '%{$search}%' OR user_login Like '%{$search}%' OR user_email Like '%{$search}%' OR display_name Like '%{$search}%'",
                        ARRAY_A
                  );
            } else {
                  return $wpdb->get_results(
                        "SELECT ID,user_login,user_email,display_name from {$wpdb->prefix}users",
                        ARRAY_A
                  );
            }
      }

      // Define table columns
      function get_columns()
      {
            $columns = array(
                  'cb'            => '<input type="checkbox" />',
                  'ID' => 'ID',
                  'user_login' => 'Username',
                  'display_name'    => 'Name',
                  'user_email'      => 'Email'
            );
            return $columns;
      }

      // Bind table with columns, data and all
      function prepare_items()
      {
            if (isset($_POST['page']) && isset($_POST['s'])) {
                  $this->users_data = $this->get_users_data($_POST['s']);
            } else {
                  $this->users_data = $this->get_users_data();
            }

            $columns = $this->get_columns();
            $hidden = array();
            $sortable = $this->get_sortable_columns();
            $this->_column_headers = array($columns, $hidden, $sortable);

            /* pagination */
            $per_page = $this->get_items_per_page('employees_per_page', 2);
            $current_page = $this->get_pagenum();
            $total_items = count($this->users_data);
            
            // edit
            if (isset($_GET['action']) && $_GET['page'] == "employees_list_table" && $_GET['action'] == "edit") {
                  $empID = intval($_GET['employee']);

                  //... do operation
            }

            // delete
            if (isset($_GET['action']) && $_GET['page'] == "employees_list_table" && $_GET['action'] == "delete") {
                  $empID = intval($_GET['employee']);

                  //... do operation
            }

            $this->users_data = array_slice($this->users_data, (($current_page - 1) * $per_page), $per_page);

            $this->set_pagination_args(array(
                  'total_items' => $total_items, // total number of items
                  'per_page'    => $per_page // items to show on a page
            ));

            usort($this->users_data, array(&$this, 'usort_reorder'));

            $this->items = $this->users_data;
      }

      // bind data with column
      function column_default($item, $column_name)
      {
            switch ($column_name) {
                  case 'ID':
                  case 'user_login':
                  case 'user_email':
                        return $item[$column_name];
                  case 'display_name':
                        return ucwords($item[$column_name]);
                  default:
                        return print_r($item, true); //Show the whole array for troubleshooting purposes
            }
      }

      // To show checkbox with each row
      function column_cb($item)
      {
            return sprintf(
                  '<input type="checkbox" name="user[]" value="%s" />',
                  $item['ID']
            );
      }

      // Add sorting to columns
      protected function get_sortable_columns()
      {
            $sortable_columns = array(
                  'user_login'  => array('user_login', false),
                  'display_name' => array('display_name', false),
                  'user_email'   => array('user_email', true)
            );
            return $sortable_columns;
      }

      // Sorting function
      function usort_reorder($a, $b)
      {
            // If no sort, default to user_login
            $orderby = (!empty($_GET['orderby'])) ? $_GET['orderby'] : 'user_login';
            // If no order, default to asc
            $order = (!empty($_GET['order'])) ? $_GET['order'] : 'asc';
            // Determine sort order
            $result = strcmp($a[$orderby], $b[$orderby]);
            // Send final sort direction to usort
            return ($order === 'asc') ? $result : -$result;
      }

      // Adding action buttons to column
      function column_user_login($item)
      {
            $actions = array(
                  'edit'      => sprintf('<a href="?page=%s&action=%s&employee=%s">Edit</a>', $_REQUEST['page'], 'edit', $item['ID']),
                  'delete'    => sprintf('<a href="?page=%s&action=%s&employee=%s">Delete</a>', $_REQUEST['page'], 'delete', $item['ID']),
            );

            return sprintf('%1$s %2$s', $item['user_login'], $this->row_actions($actions));
      }
}

// Adding menu
function my_add_menu_items()
{
      $hook = add_menu_page('Employees List Table', 'Employees List Table', 'activate_plugins', 'employees_list_table', 'employees_list_init');

      // screen option
      add_action("load-$hook", 'my_tbl_add_options');

      function my_tbl_add_options()
      {
            $option = 'per_page';

            $args = array(
                  'label' => 'Employees',
                  'default' => 2,
                  'option' => 'employees_per_page'
            );
            add_screen_option($option, $args);

            $empTable = new Employees_List_Table();
      }
}
add_action('admin_menu', 'my_add_menu_items');

// get saved screen meta value
add_filter('set-screen-option', 'my_table_set_option', 10, 3);

function my_table_set_option($status, $option, $value)
{
      return $value;
}

// Plugin menu callback function
function employees_list_init()
{
      // Creating an instance
      $empTable = new Employees_List_Table();

      echo '<style>#the-list .row-actions{left:0;}</style><div class="wrap"><h2>Employees List Table</h2>';
      // Prepare table
      $empTable->prepare_items();
?>
      <form method="post">
            <input type="hidden" name="page" value="employees_list_table" />
            <?php $empTable->search_box('search', 'search_id'); ?>
      </form>
<?php
      // Display table
      $empTable->display();
      echo '</div>';
}

Plugin

Go to Plugins >> Installed Plugins

Click on Activate

It will create a admin menu. When we click on it.

Now, successfully we have implemented the action links to columns to wordpress admin table.

Sanjay KumarHello friends, I am Sanjay Kumar a Web Developer by profession. Additionally I'm also a Blogger, Youtuber by Passion. I founded Online Web Tutor and Skillshike platforms. By using these platforms I am sharing the valuable knowledge of Programming, Tips and Tricks, Programming Standards and more what I have with you all. Read more