I am, using the Codeigniter pagination library,
I am wondering how I can grab the number of the first and last items displayed using the pagination class?
So, if I had 12 results, and per_page was set to 5. I would want
Page 1: Displaying 1 to 5 of 12 results
Page 2: Displaying 6 to 10 of 12 results
Page 3: Displaying 11 to 12 of 12 results.
Keeping it simple.
You need 3 variables. Result start, result end (in the page, not the whole) and total result.
You already know the total results (from the pagination). Let's call it $total.
so, now get the current page ($curpage) value from CI instance. Then,
$result_start = ($curpage - 1) * $per_page + 1;
if ($result_start == 0) $result_start= 1; // *it happens only for the first run*
for $result_end, you just need to add the per page value but considering it'll be 1 less,
$result_end = $result_start+$per_page-1;
if ($result_end < $per_page) // happens when records less than per page
$result_end = $per_page;
else if ($result_end > $total) // happens when result end is greater than total records
$result_end = $total;
send all those 3 values to view.
echo "displaying $result_start to $result_end of $total";
itachi's solution works great except you need to handle the case where the last page has less than $per_page elements.
if ($result_end > $total) {
$result_end = $total;
}
In CodeIgniter Controller file
$params['limit'] = 15;
$params['offset'] = ($this->input->get('per_page')) ? $this->input->get('per_page') : 0;
$config = $this->config->item('pagination');
$config['per_page'] = $params['limit'];
$config['base_url'] = site_url('cy_controller/action?');
$config['total_rows'] = $this->abcd_model->get_count($params);
$this->pagination->initialize($config);
$data['merchant'] = $this->abcd_model->get_all($params);
$countMerchant = count($data['merchant']);
if ($params['offset'] == 0) {
$find_total_record = $countMerchant;
} else {
$valuec = $params['offset'] + $params['limit'];
if ($valuec > $config['total_rows'])
$find_total_record = $params['offset'] + $countMerchant;
else
$find_total_record = $params['offset'] + $params['limit'];
}
$per_page_total = $find_total_record;
$initial = $params['offset'] == 0 ? 1 : $params['offset'];
$data['showing'] = "Showing " . $initial . " to " . $per_page_total . " of " . $config['total_rows'] . " results";
$data['_view'] = 'cy_controller/action';
$this->load->view('layouts/main', $data);
And in view file
<div class="pull-left">
<?php echo $showing; ?>
</div>
Related
I am fetching username and Id from the database. I have more than 500 usernames. I have to display pagination number only 1 to 5 and last pagination number.
Example:- pagination number is:- 1 2 3 4 5...20(last number).
Now I am getting all numbers in horizontal. Would you help me in this?
Can anyone help me with NEXT and LAST in pagination?
include('../db/connection.php');
$reclimit = 3;
if(isset($_GET['page'])){
$page = $_GET['page'];
} else {
$page = 1;
}
$start = (($page-1) * $reclimit);
$sql = "SELECT * FROM request";
$records =$conn->query($sql);;
$total = $records->num_rows;
$tpages = ceil($total / $reclimit);
$search_sql="SELECT * FROM request LIMIT ".$start."," .$reclimit;
$search_result = $conn->query($search_sql);
HTML
<body>
<?php
if (isset($search_result->num_rows) > 0) {
?>
<h2 class="result-title">Results matching your need</h2>
<?php
while($search_ok = $search_result->fetch_assoc()) {
$user_id=$search_ok['Id'];
$user_name=$search_ok['Name'];
echo "
<div class='search-section'>
<div class='search-profile'>
<div class='s_user_id'>{$user_id}</div>
<div class='s_user_name'>{$user_name}</div>
</div>
</div>
";
}}
for($i=1;$i<=$tpages;$i++) {
echo "".$i."";
}
?>
</body>
The pagination which you are using is simple and working one. But the pagination which you are searching is smart way and you should achieve this by using some if conditions. Similar answer are there in SO. Go to the following, this may help you
Smart pagination algorithm
PHP pagination
Limit pagination page number
It's a simple idea, but I didn't test it. Edit foreach displaying numbers:
$pgStart = 1;
if (isset($_GET['page'])) { // get first showing number = current page - 2
$pg = $_GET['page'] - 2;
$pgStart = $pg + 5 > $tpages ? $tpages - 4 : $pg; //EDIT fix when reach pages end
$pgStart = $pg < 1 ? 1 : $pg; // This must be after ending correction (previous line)
}
if ($pgStart > 1) { // show 1
echo '1 ... ';
}
for($i = $pgStart; $i <= $tpages && $i < $pgStart + 5; $i++) { // show 5 pages
echo ' '.$i.' ';
}
if ($i < $tpages) { // show last
echo ' ... '.$tpages.'';
}
EDIT
Output of this script with $_GET['page'] = 7 and $tpages = 20 from php sandbox is (without linebreaks):
1 ...
5
6
7
8
9
... 20
This code to generate a paginator isn't working as expected, what could be the problem?
This function obtains the HTML links for a paginator given some data about the results the current page is showing. $ruta is the base URL, $pagina is the current page for which I want to generate pagination links, $limite is the number of result that each page shows, $total is the total of results to be paged.
function generarPaginador($ruta, $pagina, $limite, $total)
{
// Traducciones
$textoPrimera = _('Primera');
$textoUltima = _('Última');
// Variables para la numeración de los enlaces para paginación
$primera = 1;
$ultima = ceil($total / $limite); //I was using floor but thanks to the answer I could verify that ceil gives me the correct pagination links for the given parameters
$anterior = $pagina == 1 ? 1 : $pagina - 1;
$siguiente = ( ( $pagina + 1) > $ultima) ? $ultima : $pagina + 1;
if ($ultima == 1) {
return '';
}
// ENLACES: Primeros
$enlaces = '';
$enlaces .= "<span>$textoPrimera</span>";
$enlaces .= "<span><</span>";
// ENLACES: Previos a la página actual
$i = ( $pagina - 3) > 0 ? $pagina - 3 : 1;
while ($i < $pagina) {
$enlaces .= "<span>$i</span>";
$i++;
}
// ENLACES: Página actual
$enlaces .= "<span class=\"current\">$pagina</span>";
// ENLACES: Siguientes a la página actual
$i = $pagina + 1;
$tamano = $pagina + 3;
while (($i <= $ultima ) && ($i <= $tamano)) {
$enlaces .= "<span>$i</span>";
$i++;
}
// ENLACES: Últimos enlaces
$enlaces .= "<span>></span>";
$enlaces .= "<span>$textoUltima</span>";
return $enlaces;
}
For example I want to generate the links of the paginator for the page 2, there are 37 total results, but the web page just shows 10 results per page. The base url is /busqueda/resultados/
If I pass those parameters to the function it generates 3 links without problem for the 3 first pages with the first 30 results, but it should also generate a 4th link for the last page (because each page contains 10 max, the first three contains 10 each one, 30 in total, but the 4th contains the remaining 7 and there should be a link to it).
This should be as simple as changing floor to ceil.
I have my pagination page links like this.And the pagegrows like:
1 2 3 4 5 6 7 ,8,9,10 and goes on.
But i want to limit this so if there is more than 5 pages it shall only show 5 links like this:
1 2 3 4 5... 97 98 99
where 99 is the last page.
And if you go to next page it will only change the first pages like this:
3 4 5 ... 97 98 99
function pagination($current_page_number, $total_records_found, $query_string = null)
{
$page = 1;
echo "Page: ";
for ($total_pages = ($total_records_found/NUMBER_PER_PAGE); $total_pages > 0; $total_pages--)
{
if ($page != $current_page_number)
echo "<a href=\"?page=$page" . (($query_string) ? "&$query_string" : "") . "\">";
echo "$page ";
require_once('inc/database.php');
define("NUMBER_PER_PAGE", 5); //number of records per page of the search results
$page = ($_GET['page']) ? $_GET['page'] : 1;
$start = ($page-1) * NUMBER_PER_PAGE;
$sql = "SELECT * FROM members WHERE 1=1";
$total_records = mysql_num_rows(mysql_query($sql));
//we limit our query to the number of results we want per page
$sql .= " LIMIT $start, " . NUMBER_PER_PAGE;
// we display our pagination at the top of our search results
pagination($page, $total_records, "id=$id&username=$username&email=$email");
$loop = mysql_query($sql)
or die ('cannot run the query because: ' . mysql_error());
while ($record = mysql_fetch_assoc($loop))
echo "<br/>{$record['id']}) " . stripslashes($record['username']) . " - {$record['email']}";
echo "<center>" . number_format($total_records) . " search results found</center>";
if ($page != $current_page_number)
echo "</a>";
$page++;
Pagination is one of those things that has been done so many times that you're better off figuring out how to use a pre made class like this one http://code.tutsplus.com/tutorials/how-to-paginate-data-with-php--net-2928
The basics of what you need to do are calculate how many links you want to see on either side of the elipses ... and then make loops to create those links. The ceil() function may be new for you, but it returns a fraction always rounded up.
$buffer = 3;
$results_per_page = 5;
$page = ($_GET['page']) ? $_GET['page'] : 1;
$start = ($page-1) * $results_per_page;
$sql = "SELECT * FROM members WHERE 1=1";
$total_records = mysql_num_rows(mysql_query($sql));
$total_pages = ceil(intval($total_records) / $results_per_page);
for ($x = $page - $buffer; $x < $page; $x++){
echo " $x";
}
echo " ... ";
for ($x = $total_pages - $buffer; $x <= $total_pages; $x++){
echo " $x";
}
This quick little bit of code does not take in to consideration result sets small enough to fit all links in to one line. Which is why I suggest using the pagination classes that exist already.
I have a news table in MySQL Database I query the table and show the title of the news in one PHP pages but now the table getting bigger so I want to divide the results into pages I mean to show each 50 news title in one page (pagenation).
I use this query to bring the news :
SELECT news.*, categories.category, users.username
FROM news INNER JOIN
users on news.user_id = users.id INNER JOIN
categories on categories.id = news.category_id
order by news.timestamp DESC
limit $min,$max
and this is part of the PHP page (How I calculate the max and min)
$news_per_page = 50;
if(!empty($_GET['p_n']))
{
$p_n = $_GET['p_n'];
$max = $news_per_page*$p_n;
$min = ($max - $news_per_page);
}
else
{
$p_n = 1;
$max = 50;
$min = 0;
}
$news = all_news($max,$min);
The sql giving me wrong result when i pass the limits I do not know why. Is it wrong to specify the max and min of sql query by this way?? Should I correct something in this code?
The LIMIT clause, as explained in the docs, takes arguments offset and count. So if you want to get, for example, results from 201 to 250, you would use LIMIT 200, 50. Start by renaming your variables $min and $max to $offset and $count, and from there everything will fall into place.
Pseudocode:
offset = (requestedPageNumber - 1) * rowsPerPage;
count = rowsPerPage;
PHP Code:
(assuming page number is 0-based)
$rowsPerPage = 50;
$page = empty($_GET['p_n']) ? 0 : $_GET['p_n'];
$offset = $rowsPerPage * (int) $page;
$news = all_news($offset, $rowsPerPage);
If you've got problems handling pagination properly, I suggest you use some code that is working, for example a pagination class that takes three parameters:
The current page.
The total count.
The number of items per page.
And then that class will generate the LIMIT clause for you. Example:
$pageNumber = 1;
$totalCount = 17;
$perPage = 5;
$pagination = new LimitPagination($pageNumber, $totalCount, $perPage);
echo $pagination, "\n";
This would output
LIMIT 0, 5
because you'er on the first page. Such a class then could also filter out those problems you have here, for example setting to a negative page - just automatically. And also it can provide a lot of extra data, like the next and previous page, the current page, the number of total pages, if it is the first or the last page and what not:
$pagination->setPage(-2);
echo $pagination, "\n";
echo "Current: ", $pagination->getPage(),
"; Total: ", $pagination->getTotalPages(),
"; Previous: ", $pagination->getPreviousPage(),
"; Next: ", $pagination->getNextPage(),
"\n";
Output:
LIMIT 0, 5
Current: 1; Total: 4; Previous: 1; Next: 2
This is then easy to integrate with different code, including yours:
$pagination = new LimitPagination($_GET['p_n'], $totalCount, 50);
$limit = sprintf("%d, %d", $pagination->getOffset(), $pagination->getCount());
This should easily do it. Class is here as Gist: https://gist.github.com/4469154
You need to set start (this you can achieve by using current page and per page property) and the second information is how many results you want (again per page property).
LIMIT . ($p_n - 1) * $news_per_page .', ' . $news_per_page
So, in your script it will be:
if(!empty($_GET['p_n']))
{
// You need to protect your variables for SQL injection. For numbers (int) or integer() function it is enough.
$p_n = (int) $_GET['p_n'];
$max = (int) $news_per_page;
$min = (int) ($p_n - 1) * $news_per_page;
}
else
{
$p_n = 1;
$max = 50;
$min = 0;
}
The correct code is:
$news_per_page = 50;
if(!empty($_GET['p_n']))
{
$p_n = intval($_GET['p_n']);
$min = ($p_n-1) * $news_per_page;
$max = $news_per_page;
}
else
{
$p_n = 1;
$max = 50;
$min = 0;
}
$news = all_news($max,$min);
While $_GET['p_n'] is page_number you dont' need to make any multiplies
Ok so iv got this code which is suppose to bring back all my results from my database and display 5 results per page. At the moment I have 12 results in my database and it is only showing 10, it wont show the 3rd page as there isnt 5 results to display. Here is my code
//$_GET['page'] is to get the current page opened
if (isset($_GET["page"])) { $page = $_GET["page"]; } else { $page=1; };
$results_per_page = "5"; //number of results I want displayed per page
$start_from = ($page-1) * $results_per_page;
$query = "SELECT * FROM items WHERE subcat = '$conditions' LIMIT $start_from, $results_per_page";
$result = mysql_query($query) or die("Unable to verify user because : " . mysql_error());
while ($row_condition=mysql_fetch_array($result)) {
//Display the results here
}
//Count number of results from database and work out how
//many pages I need to display all the results.
$result1 = mysql_query("SELECT * FROM items WHERE subcat = '$conditions'");
$num_rows = mysql_num_rows($result1);
$num_pages = $num_rows / $results_per_page;
if ($num_rows > $results_per_page){
?>
<div id="pagenum">
<?php
//This creates and displays the page numbers for the user to select
foreach( range( 1, $num_pages) as $i) {
if ($thepage == $i){
echo '<b>' . $i . '</b>';
}else{
echo '' . $i . '';
}
//This places a line between each number of pages
if ($i == $num_pages){
}else{
echo " | ";
}
}
?>
</div>
<?php
}else{ echo "Test";}
?>
So can anyone see a problem with this?, so I have 12 entries in my database. However im only getting 2 pages, 5 on each page and im not getting the 3rd page as there are only 2 results left and it seems to want 5 to finish it.
Thanks
You need to use ceil function:
$num_pages = ceil($num_rows / $results_per_page);
I think your biggest problem is that PHP will make give you a float when you divide two numbers that don't result in a whole one.
$one = 12;
$two = 5;
$result = $one / $two; // That will result in 2.4
Now, the issue is you, technically, have three pages, but PHP will NOT treat the .4 pages as a page, so when you loop through it will technically only do it twice. Since your using range and it's 2.4, it seems like PHP is rounding down. I would suggest something like this:
$result1 = mysql_query("SELECT * FROM items WHERE subcat = '$conditions'");
$num_rows = mysql_num_rows($result1);
$num_pages = ceil($num_rows / $results_per_page);
if ($num_rows > $results_per_page){
for($i = 0; $i < $num_pages; $i++) {
ceil() will force that division to round up every time, which will always give you that extra page.
Give it a shot! Let me know if it fixes your issue!