I want to paginate query results in CodeIgniter to look like this:
Problem 1 :
The Pagination class always outputs numeric links. I just want to show next and back links.
Problem 2 :
$data['links'] = $this->pagination->create_links(); returns all of the links as a string. How can I separate the next and back links and put next to the right and back to the left ?
suppose url is: http://localhost/controller/method/
do following in your controller function
...
function method($page_num)
{
...
$data['next_link'] = $page_num + 1;
$data['prev_link'] = $page_num;
...
$this->load->view('<veiw_name>', $data);
}
do this in your view
...
Prev
Next
....
Related
So here is what I had before. If I'd go to ciblog/categories/posts/5/, it would take me to a page showing all posts with a category with the id of 5.
And here is what I want to do. I want to go to ciblog/categories/posts/5 and it would show be 5 posts lets say. Then when I go to ciblog/categories/posts/5/3 it would offset by 3 so now I have the next 3 posts.
Currently I have 4 posts, just for testing. If I directly through my url go to ciblog/categories/posts/5 it shows 3 posts, and if I go to ciblog/categories/posts/5/3 it shows my one other post, so the amount of posts I am getting is correct based on the url.
BUT at the bottom it always shows that I am on page 2. When I use F12 and look at the elements both my pagination links show ciblog/categories/posts/5
So its not adding on the number at the end
Here is what I have for the pagination for this page. I used print_r and everything in $config is correct.
public function posts($id, $offset=0){
$category = $this->category_model->get_category($id);
if(empty($category))
{
show_404();
}
$config['base_url'] = base_url().'categories/posts/'.$id;
$config['total_rows'] = $this->post_model->get_posts_by_category_count($id);
$config['per_page'] = 3;
$config['uri_segment'] = 3;
$config['attributes'] = array('class' => 'pagination-link');
$this->pagination->initialize($config);
$data['title'] = $category->name;
$data['posts'] = $this->post_model->get_posts_by_category($id,$config['per_page'],$offset);
$this->load->view('templates/header');
$this->load->view('posts/index', $data);
$this->load->view('templates/footer');
}
Routes:
$route['categories/posts/(:num)/(:num)'] = 'categories/posts/$1/$2';
Reference:
I have been following a tutorial here: https://www.youtube.com/watch?v=WoQTjJepDWM&index=8&list=PLillGF-RfqbaP_71rOyChhjeK1swokUIS
Code for this tutorial is here: https://github.com/bradtraversy/ciblog
I am now adding on to this. The only changes I have made are shown above
$config['base_url'] = base_url().'categories/posts/'. $id . '/' . $offset;
$config['uri_segment'] = 4;
Because your pagination depends on offset, not id of category, then you should let it find for the offset with uri_segment 4, and your base_url must send an offset variable to find the offset.
I allow the user to delete items from paginated content. After deleting the item the user requests i redirect them back. I however have noticed this is buggy because if the page contains only one item and the user deletes it they are redirected to the same page which now has no records.I have 11 items on each page and use the default Laravel pagination. How can i enforce a mechanism that redirects user to the previous page if the current page is blank after deletion of the last or only item?
You can try to do simple check in controller and redirect users manually. The code just shows the idea:
$result = Model::paginate(10);
if (count($result) === 0) {
$lastPage = $result->lastPage(); // Get last page with results.
$url = route('my-route').'?page='.$lastPage; // Manually build URL.
return redirect($url);
}
return redirect()->back();
You can check the no. of results, if its less than 1 then you can redirect to the previousPageUrl as:
if ($results->count()) {
if (! is_null($results->previousPageUrl())) {
return redirect()->to($results->previousPageUrl());
}
}
I solved it by doing a Redirect::back() on the delete function. This led to the paginator function where l did the following:
//if an item was deleted by the user and it was the only on that page the number of
//items will be zero due the page argument on the url. To solve this we need to
//redirect to the previous page. This is an internal redirect so we just get the
//current arguments and reduce the page number by 1. If the page argument is not
//available it means that we are on the first page. This way we either land on the
//first page or a previous page that has items
$input = Input::all();
if( (count($pages) == 0) && ( array_key_exists('page', $input) ) ){
if($input['page'] < 2){
//we are headed for the first page
unset($input['page']);
return redirect()->action('MyController#showItems', $input);
}
else{
//we are headed for the previous page -- recursive
$input['page'] -= 1;
return redirect()->action('MyController#showItems', $input);
}
}
To implement such a logic in the controller method, destroy(), we need to know the current page number, and the items count (before we delete this item).
Pass these two pieces of information through the DELETE link, and retrieve them using the Request input method.
In your view:
<form action="{{'/items/'.$item->id.'?current_page='.$items->currentPage().'&items_count='.$items->count()}}" method="POST">
#method('DELETE')
#csrf
<button>Delete</button>
</form>
In your controller:
public function destroy(Item $item, Request $request)
{
$item->delete();
$itemsCount = $request->input('items_count');
$currentPage = $request->input('current_page');
$url = $itemsCount > 1 ? '/items/?page='.$currentPage : '/items/?page='.($currentPage - 1);
return redirect($url);
}
If it's the last page (1), then the page number becomes 0, which will still return the correct response (empty items list).
For the routes, implement a route with the two parameters, with the controller's destroy method as the callback.
If you have a resource controller, then this route has to be before the latter's route.
web.php
Route::DELETE('/items/{item_id}?current_page={number}&items_count={count}', 'ItemController#destroy');
Route::resource('/items', 'ItemController');
$category_id=$_GET['category_id'];
$data['adsd']=$this->mymodel->select_ads_by_category($category_id);
$config["base_url"]=site_url('main/category_ads_display?category_id='.$category_id.'');
$config["total_rows"]=count($data['adsd']);
$limit=$config["per_page"]=1;
$config["uri_segment"]=3;
$config["use_page_numbers"]=TRUE;
$this->pagination->initialize($config);
if($this->uri->segment(3))
$page=($this->uri->segment(3)-1)*$limit;
else
$page=0;
Hello friends i have pasted my code above,,everything is working fine,but when i click on links of pagination the url is like this =localhost/blabla/main/category_ads_display?category_id=5/2(not working)
but i need the url to be as = localhost/blabla/main/category_ads_display/2?category_id=5(working)
please help me on this
Try this way
$category_id=$this->uri->segment(3);
$data['adsd']=$this->mymodel->select_ads_by_category($category_id);
config["base_url"]=site_url('main/category_ads_display/'.$category_id);
$config["total_rows"]=count($data['adsd']);
$limit=$config["per_page"]=1;
$config["uri_segment"]=4;
$config["use_page_numbers"]=TRUE;
$this->pagination->initialize($config);
if($this->uri->segment(4))
$page=($this->uri->segment(3)-1)*$limit;
else
$page=0;
Now your new link will be like this localhost/blabla/main/category_ads_display/5/2 for page 2 and 5 will be your category id
If requesting for a page say page number 3 in paginated items of a table in cakephp,
which is having only 2 pages, how do we show the last page ie page number 2?
I found out the solution here:-
cakephp paginator helper shows error when delete the last record from the last page
public function index() {
try {
$paginatedData = $this->Paginator->paginate();
} catch (NotFoundException $e) {
//get current page
$page = $this->request->params['named']['page'];
if( $page > 1 ){
//redirect to previous page
$this->redirect( array( "page" => $page-1 ) );
}else{
$paginatedData = array(); //no data to paginate so use empty array()
//you will have to check for this in the view and no longer display the pagination links, since they will NOT be defined
}
}
}
Ok, I followed the instructions in the example perfectly. Ultimately, pagination works, kind of.
I get all of the pages listed: 1 | 2 | > | Last. Etc.
The first one is active, like it should be. I did the querying correctly as well, because each link will result in the correct query.
However, when I click on number 2, it will show me the next set of products correctly, but it will display the pagination from the first page.
Whatever pagination button I click on, will return the main pagination set: 1 (selected) | 2 | > | Last. It never changes! I'm loosing my patience, can someone help?
I think I might know whats going on. You need to tell the pagination library which segment of the URL holds the offset.
For example, if your URL is /products/browse/all/20, you need to tell CodeIgniter that the 4th segment holds the offset
$config['uri_segment'] = 4;
The default for the library is URL segment #3. If the offset in your URL is not in position 3 and you forget to tell the pagination library this, it will interpret the wrong segment as being the offset. This can lead to the kind of behaviour you describe above where the pagination does not appear to change.
I also came across same error and finally was able to fix it. Just thought to share the code script, may be someone will be able to use it.
=====> Controller
// Default function
function index()
{
// Display listing
$this->listing();
}
function listing($argDataArr = array())
{
// Initialize pagination
$pageArr['base_url'] = $this->config->item('categoryBeAction')."/listing";
$pageArr['total_rows'] = 15; //assume
$pageArr['per_page'] = 5; //assume
//You need to tell the pagination library which segment of the URL holds the offset.
$pageArr['uri_segment'] = 4; //URL eg: http://localhost/myproject/index.php/backend/category/listing/5
$this->pagination->initialize($pageArr);
// Get list of categories
// Create data array and pass data to get function
$dataArr['limitRows'] = $pageArr['per_page'];
$dataArr['limitOffset'] = $this->uri->segment(4); //the dynamic value from this segment will be used as offSet
$viewArr['listArr'] = $this->category_model->get($dataArr);
//rest of the code...
}
======> Model
function get($argDataArr = array())
{
//Select the fields required
$this->db->select('id, name, parent_id, status');
$this->db->from($this->config->item('tbl_category','dbtables'));
$this->db->where('parent_id', $parentId);
$this->db->limit($argDataArr['limitRows'], $argDataArr['limitOffset']);
$this->db->order_by("name", "asc");
$query_result = $this->db->get();
return $query_result;
}
======> View page
<!-- Pagination -->
<tr>
<td align="right">
<?php echo $this->pagination->create_links(); ?>
</td>
</tr>
Which example?
echo $this->pagination->create_links();
^^Is this in your view?