Search code examples
phpcodeigniter

How do I always keep the "next" and "previous" links in this Codeigniter 3 pagination?


I am working on an online newspaper/blogging application with CodeIgniter 3.1.8 (link to GitHub repo) and Twitter Bootstrap 4.

The application has themes. One of the themes uses a pager instead of pagination, so the Codeigniter default pagination is not well suited for it.

The "hack" I found for this problem relies on CSS.

In the Posts controller I have:

class Posts extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
    }
    
    private function _initPagination($path, $totalRows, $query_string_segment = 'page')
    {
        //load and configure pagination 
        $this->load->library('pagination');
        $config['base_url']             = base_url($path);
        $config['query_string_segment'] = $query_string_segment;
        $config['enable_query_strings'] = TRUE;
        $config['reuse_query_string']   = TRUE;
        $config['total_rows']           = $totalRows;
        $config['per_page']             = 12;
        if (!isset($_GET[$config['query_string_segment']]) || $_GET[$config['query_string_segment']] < 1) {
            $_GET[$config['query_string_segment']] = 1;
        }
        $this->pagination->initialize($config);
        
        $limit  = $config['per_page'];
        $offset = ($this->input->get($config['query_string_segment']) - 1) * $limit;
        
        return array(
            'limit' => $limit,
            'offset' => $offset
        );
    }
    
    public function index()
    {
        
        //call initialization method
        $config = $this->_initPagination("/", $this->Posts_model->get_num_rows());
        
        $data                  = $this->Static_model->get_static_data();
        $data['base_url']      = base_url("/");
        $data['pages']         = $this->Pages_model->get_pages();
        $data['categories']    = $this->Categories_model->get_categories();
        $data['search_errors'] = validation_errors();
        
        //use limit and offset returned by _initPaginator method
        $data['posts'] = $this->Posts_model->get_posts($config['limit'], $config['offset']);
        $this->twig->addGlobal('pagination', $this->pagination->create_links());
        
        // featured posts
        if ($data['is_featured']) {
            $data['featured'] = $this->Posts_model->featured_posts();
            $this->twig->addGlobal('featuredPosts', "themes/{$data['theme_directory']}/partials/hero.twig");
        }
        
        $this->twig->display("themes/{$data['theme_directory']}/layout", $data);
    }
    
    public function search()
    {
        // Force validation since the form's method is GET
        $this->form_validation->set_data($this->input->get());
        $this->form_validation->set_rules('search', 'search term', 'required|trim|min_length[3]', array(
            'min_length' => 'The search term must be at least 3 characters long.'
        ));
        $this->form_validation->set_error_delimiters('<p class = "error search-error">', '</p>');
        // If search fails
        if ($this->form_validation->run() === FALSE) {
            $data['search_errors'] = validation_errors();
            return $this->index();
        } else {
            $expression           = $this->input->get('search');
            $posts_count          = $this->Posts_model->search_count($expression);
            $query_string_segment = 'page';
            $config               = $this->_initPagination("/posts/search", $posts_count, $query_string_segment);
            $data                 = $this->Static_model->get_static_data();
            $data['base_url']     = base_url("/");
            $data['pages']        = $this->Pages_model->get_pages();
            $data['categories']   = $this->Categories_model->get_categories();
            //use limit and offset returned by _initPaginator method
            $data['posts']        = $this->Posts_model->search($expression, $config['limit'], $config['offset']);
            $data['expression']   = $expression;
            $data['posts_count']  = $posts_count;
            $this->twig->addGlobal('pagination', $this->pagination->create_links());
            $this->twig->display("themes/{$data['theme_directory']}/layout", $data);
    }
}

I the stylesheet, I hide the page items except the "Previous" and "Next" buttons:

.pagination li:first-child {
  display: inline-block;
  margin-right: auto;
}

.pagination li.active + li {
  display: inline-block;
  margin-left: auto;
}

.pagination li,
.pagination li.active {
  display: none;
  position: relative;
}

.pagination li:first-child a::before,
.pagination li.active + li a::before {
  display: inline-block;
  font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  background-color: #0085a1;
  border: 1px solid #006d83;
  color: #fff;
  font-size: 14px;
  font-weight: 800;
  padding: 15px 25px;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.pagination li:first-child a::before {
  content: 'Newer Posts';
  padding-left: 35px;
}

.pagination li.active + li a::before {
  content: 'Older Posts';
  padding-right: 35px;
}

.pagination li:first-child a::after,
.pagination li.active + li a::after {
  color: #fff;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

.pagination li:first-child a::after {
  content: '\2190';
  left: 7px;
}

.pagination li.active + li a::after {
  content: '\1F812';
  right: 7px;
}

The result is illustrated below:

enter image description here

The problem

When I am on the last page, the "Newer Posts" button is linked to the first page instead of the previous.

I have reached the conclusion that what I miss is a way to always keep the "next" and "previous" links.


Question:

How do I always keep the "next" and "previous" links?


Solution

  • $config[‘first_link’] = False;
    $config[‘last_link’] = False;
    

    Add this in your config then you will not get first and last page link in your pagination

    If you wanted to not list the specific pages (for example, you only want “next” and “previous” links), you can suppress their rendering by adding:

    $config['display_pages'] = FALSE;
    

    https://codeigniter.com/userguide3/libraries/pagination.html#id12