Handle search in WordPress from WP_List_Table code

I need to add support for searching or filter items using WP_List_Table I read and didn’t know how to get this done. I’ve already added the box trough this code:

function ft_list()
{
    echo '</pre><div class="wrap"><h2>' . __('Frequent Traveler List') . '</h2>';
    $ftList = new FT_WP_Table();
    $ftList->search_box('search', 'search_id');
    echo '</div>';
}

And this is how my prepare_items() functions looks:

Read More
public function prepare_items()
{
    $searchcol = array(
        'firstname',
        'lastname',
        'foid',
        'no_frequent',
        'create_time'
    );

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

    // SQL results
    $posts = $this->get_sql_results();
    empty($posts) AND $posts = array();

    # >>>> Pagination
    $per_page = $this->posts_per_page;
    $current_page = $this->get_pagenum();
    $total_items = count($posts);
    $this->set_pagination_args(array(
        'total_items' => $total_items,
        'per_page' => $per_page,
        'total_pages' => ceil($total_items / $per_page)
    ));
    $last_post = $current_page * $per_page;
    $first_post = $last_post - $per_page + 1;
    $last_post > $total_items AND $last_post = $total_items;

    // Setup the range of keys/indizes that contain 
    // the posts on the currently displayed page(d).
    // Flip keys with values as the range outputs the range in the values.
    $range = array_flip(range($first_post - 1, $last_post - 1, 1));

    // Filter out the posts we're not displaying on the current page.
    $posts_array = array_intersect_key($posts, $range);
    # <<<< Pagination
    // Prepare the data
    $permalink = __('Edit:');

    foreach ($posts_array as $key => $post) {
        $link = get_edit_post_link($post->id);
        $no_title = __('No title set');
        $title = !$post->firstname ? "<em>{$no_title}</em>" : $post->firstname;
        $posts[$key]->firstname = "<a title='{$permalink} {$title}' href='{$link}'>{$title}</a>";
    }
    $this->items = $posts_array;
}

Where I should add the code to filter items based on search parameter?

Related posts

Leave a Reply

1 comment

  1. Looking at other classes that extend WP_List_Table I see they use something like

    $search = ( isset( $_REQUEST['s'] ) ) ? $_REQUEST['s'] : false;
    

    and pass that to the prepare_items() method.

    In my test plugin I made this (see Percent in wpdb->prepare):

    $search = ( isset( $_REQUEST['s'] ) ) ? $_REQUEST['s'] : false;
    $do_search = ( $search ) ? $wpdb->prepare(" AND post_content LIKE '%%%s%%' ", $search ) : ''; 
    $sql_results = $wpdb->get_results("
            SELECT $sql_select
                FROM $wpdb->posts
            WHERE post_status = 'publish'
            $do_search
            ORDER BY $this->orderby $this->order "
    );
    

    And in display_tablenav() method I added:

    <form action="" method="GET">
        <?php 
        $this->search_box( __( 'Search' ), 'search-box-id' ); 
        ?>
        <input type="hidden" name="page" value="<?= esc_attr($_REQUEST['page']) ?>"/>
    </form>
    

    I haven’t created any search_box() method, letting the parent class render it.