title: Pagination issue with WP_List_table in WordPress
body: <p>I'm developing a plugin for WordPress. I use WP_List_Table which output rows from database nicely.
  The issue I have is the pagination. If I have let's say 200 rows in the database and I set it to only display 50 rows per page, this works and I do get 1 of 4 pages.</p>
  
  <p>On page 1 It displays ID 1 to ID 50. But when I click on page 2 it displays ID 2 to ID 51. So it only jumps 1 row and not 50. Where's the issue?</p>
  
  <p>This will handle the data:</p>
  
  <pre><code>    function prepare_items() {
          global $wpdb;
  
          /* Select project for user */
          $table_name2 = $wpdb-&gt;prefix . 'project_name';
  
          $current_user = wp_get_current_user();
  
          $sql2 = "SELECT * FROM " . $wpdb-&gt;prefix . "project_name WHERE alloweduser = " . $current_user-&gt;ID;
  
          $results2 = $wpdb-&gt;get_results($sql2) or die(mysql_error());
  
              foreach( $results2 as $result2 ) {
  
                  $table_name = $wpdb-&gt;prefix . "project_name_" . $result2-&gt;projectname;
  
          /* Define how many rows to show per page */
          $per_page = 50;
  
          $columns = $this-&gt;get_columns();
          $hidden = array();
          $sortable = $this-&gt;get_sortable_columns();
  
          // here we configure table headers, defined in our methods
          $this-&gt;_column_headers = array($columns, $hidden, $sortable);
  
          // [OPTIONAL] process bulk action if any
          $this-&gt;process_bulk_action();
  
          // will be used in pagination settings
          $total_items = $wpdb-&gt;get_var("SELECT COUNT(cid) FROM $table_name");
  
  
          // prepare query params, as usual current page, order by and order direction
          $paged = isset($_REQUEST['paged']) ? max(0, intval($_REQUEST['paged']) - 0) : 0;
          $orderby = (isset($_REQUEST['orderby']) &amp;&amp; in_array($_REQUEST['orderby'], array_keys($this-&gt;get_sortable_columns()))) ? $_REQUEST['orderby'] : 'cid';
          $order = (isset($_REQUEST['order']) &amp;&amp; in_array($_REQUEST['order'], array('ASC', 'DESC'))) ? $_REQUEST['order'] : 'ASC';
  
          // Define $items array
          // notice that last argument is ARRAY_A, so we will retrieve array
          $this-&gt;items = $wpdb-&gt;get_results($wpdb-&gt;prepare("SELECT * FROM $table_name ORDER BY $orderby $order LIMIT %d OFFSET %d", $per_page, $paged), ARRAY_A);
  
          // configure pagination
          $this-&gt;set_pagination_args(array(
              'total_items' =&gt; $total_items, // total items defined above
              'per_page' =&gt; $per_page, // per page constant defined at top of method
              'total_pages' =&gt; ceil($total_items / $per_page) // calculate pages count
          ));
  
          }
  
      }
  }
  </code></pre>
  
  <p>This will output the data:</p>
  
  <pre><code>function custom_table_example_submissions_page_handler() {
      global $wpdb;
  
      $table = new Custom_Table_Example_List_Table();
      $table-&gt;prepare_items();
  
      $message = '';
      if ('delete' === $table-&gt;current_action()) {
          $message = '&lt;div class="updated below-h2" id="message"&gt;&lt;p&gt;' . sprintf(__('Deleted %d submission(s).', 'custom_table_example'), count($_REQUEST['id'])) . '&lt;/p&gt;&lt;/div&gt;';
      }
      ?&gt;
      &lt;div class="wrap"&gt;
  
          &lt;div class="icon32 icon32-posts-post" id="icon-edit"&gt;
              &lt;br&gt;&lt;/div&gt;
              &lt;h2&gt;&lt;?php _e('Submissions', 'custom_table_example')?&gt; 
              &lt;/h2&gt;
              &lt;?php echo $message; ?&gt;
  
              &lt;form id="submissions-table" method="GET"&gt;
                  &lt;input type="hidden" name="page" value="&lt;?php echo $_REQUEST['page']; ?&gt;"/&gt;
                  &lt;?php //$table-&gt;display(array('contributorname', 'email')); ?&gt;
                  &lt;?php $table-&gt;display(); ?&gt;
              &lt;/form&gt;
  
      &lt;/div&gt;
  &lt;?php
  }
  </code></pre>
  
  <p>Update:</p>
  
  <p>get_columns:</p>
  
  <pre><code>function get_columns() {
      $columns = array(
          'cb' =&gt; '&lt;input type="checkbox" /&gt;', //Render a checkbox instead of text
          'name' =&gt; __('Name', 'custom_table_example'),
          'upload' =&gt; __('Upload', 'custom_table_example'),
          'upload2' =&gt; __('Upload', 'custom_table_example'),
          'upload3' =&gt; __('Upload', 'custom_table_example'),
          'upload4' =&gt; __('Upload', 'custom_table_example'),
          'rate' =&gt; __('Rate', 'custom_table_example'),
      );
      return $columns;
  }
  </code></pre>
  
  <p>$this->items is retrieved from:
  <a href="https://core.trac.wordpress.org/browser/tags/4.0.1/src//wp-admin/includes/class-wp-list-table.php#L0" rel="nofollow">https://core.trac.wordpress.org/browser/tags/4.0.1/src//wp-admin/includes/class-wp-list-table.php#L0</a></p>
  
  <p>It's called with:</p>
  
  <pre><code>if (!class_exists('WP_List_Table')) {
      require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
  }
  </code></pre>