Can someone help me please? I am sure it is easy for you guys. I am battling to find a solution on how to hide the next link when there are no pages to display my code is as follows:
if (!isset($_GET['page']) or !is_numeric($_GET['page'])) {
$page = 0;
} else {
$page = (int)$_GET['page'];
}
$pages_query=mysql_query ("SELECT COUNT * FROM hardware");
$result = mysql_query("SELECT * FROM hardware LIMIT $page, 3");
echo 'Next<p>';
$prev = $page - 3;
//only print a "Previous" link if a "Next" was clicked
if ($prev >= 0) {
echo 'Previous';
}
You can use mysql_num_rows($result) to get the number of records in hardware:
$result = mysql_query("SELECT * FROM hardware LIMIT $page, 3");
$record_count = mysql_num_rows($result);
if ($record_count > 1)
echo 'Next';
in your if statement check if the $page is greater than 0 then according to the outcome of the value of $page write your code. you can use another if statement in the first if statement and make it detect the situation and decide what to do. The other thing is if the user clicked next then the user is on the second page so your previous should appear if $prev is higher than 1 it should make it
something along the lines of:
$itemsPerPage = 3;
$sql = "SELECT * FROM hardware";
$result = mysql_query($sql);
$count = mysql_num_rows($result);
$pageCount = $count/$itemsPerPage;
if($pageCount > $page) { //Are there more pages worth of items stored, than we're currently looking at?
echo 'next';
}
You want to be using OFFSET in your SQL syntax, as well as LIMIT.
LIMIT limits the number of rows returned.
OFFSET tells it to start a number of rows into the result set.
You need to limit to the number of items you want on a page. and offset by that number*page.
Hopes this helps.
Related
I didn't know exactly how to word this question but by do something I mean that I would like to hide or not show my "next" button that is shown below. I have a script that pulls all the images from MySQL and prints them to my page by 30 images per page and the next 30 will create a new page that is activated by my back/next buttons. My "back" button has a if statement if $startrow isn't >= 0 than it won't show but I would like the same concept with my next button when the last row in my database is shown and it hides my next button.
I was thinking if you can detect the first empty row or the last row of the database and if so hide the next button. Otherwise it keeps adding 30 to $startrow when nothing is shown on screen.
I found a script helping me with this here but it didn't tell me how to hide the next button.
<?php
$startrow = $_GET['startrow'];
if (!isset($_GET['startrow']) or !is_numeric($_GET['startrow'])) {
$startrow = 0;
} else {
$startrow = (int)$_GET['startrow'];
}
?>
<?php
$db = mysqli_connect("localhost", "root", "", "media");
$uploaded = mysqli_query($db, "SELECT * FROM images LIMIT $startrow, 30");
while ($row = mysqli_fetch_array($uploaded)) {
echo "<div class='img_container'>";
echo "<li><img class='img_box' src='uploads/images/".$row['image_title']."' ></li>";
echo "</div>";
}
$prev = $startrow - 30;
if ($prev >= 0) {
echo '<div class="prevRow">Back</div>';
}
echo '<div class="nextRow">Next</div>';
?>
You could try something like
$num_rows = 30; // rows on a page
$db = mysqli_connect("localhost", "root", "", "media");
// get total possible rows
$res = mysqli_query($db, "SELECT count(id) FROM images");
$row = $res->fetch_row();
$total_rows = $row[0];
$res->close();
$uploaded = mysqli_query($db, "SELECT * FROM images LIMIT $startrow, $num_rows");
while ($row = mysqli_fetch_array($uploaded)) {
. . .
}
$prev = $startrow - $num_rows;
if ($prev >= 0) {
echo '<div class="prevRow">Back</div>';
}
if ( $startrow+$num_rows < $total_rows ) {
echo '<div class="nextRow">Next</div>';
}
Potentially a little faster than the answer from #RiggsFolly, you can modify your existing query to count the rows.
SELECT SQL_CALC_FOUND ROWS * FROM images LIMIT $startrow, 30
Then, after the query returns, you run a second query to get the answer:
SELECT FOUND_ROWS()
The FOUND_ROWS() function returns the number of rows the previous query would have returned, without LIMIT (or an offset).
This is probably not as fast as your original query would be in isolation, but should be slightly faster than SELECT COUNT(...) ... followed by your original query. With small data sets, though, any differences will likely be below measurable limits.
See also https://dev.mysql.com/doc/refman/5.7/en/information-functions.html
You can also combine these things into a stored procedure that accepts items per page and page number, and returns all of the records along with metadata items such as the total number of pages.
I'm learning PHP at the moment.
I want to make my HTML page pagination.
Here is the code I have:
I'm trying to make 6 videos only per page. And to do that I'm going to search how many ID's I have it means I have that same value of videos so I can make X pages.
At the moment, I'm having this error:
Notice: Object of class mysqli_result could not be converted to int in C:\xampp\htdocs\Site\index.php on line 20
$stmt3 = $db->prepare ("SELECT COUNT(ID_Video) as total FROM Videos");
$stmt3->execute();
$result2 = $stmt3->get_result();
$result2->fetch_assoc();
// Remember to round it up always!
$VideosPerPage = 6;
$totalPages = ceil($result2 / $VideosPerPage);
// Check that the page number is set.
if(!isset($_GET['page'])){
$_GET['page'] = 0;
}else{
// Convert the page number to an integer
$_GET['page'] = (int)$_GET['page'];
}
// If the page number is less than 1, make it 1.
if($_GET['page'] < 1){
$_GET['page'] = 1;
// Check that the page is below the last page
}else if($_GET['page'] > $totalPages){
$_GET['page'] = $totalPages;
}
You are seeing this error because $result2 is PDO result- not an integer. You need to assign the fetched value from the result in a variable. You can use fetchColumn() as you are getting one column. Your first few lines could look like following:
$result2 = $stmt3->get_result();
$totalVideos = $result2->fetchColumn(); // will get the number from single column
// Remember to round it up always!
$VideosPerPage = 6;
$totalPages = ceil($totalVideos / $VideosPerPage);
In input field user enters condition - what data to get from mysql. For example, user wants to get mysql rows where month is October (or 10).
Here I get user input $date_month = $_POST['date_month'];
Then mysql statement and code for pagination
try {
$sql = $db->prepare("SELECT * FROM 2_1_journal WHERE RecordMonth = ? ");
$sql->execute(array($date_month));
foreach ($sql as $i => $row) {
}
$number_of_fetched_rows = $i;
$number_of_results_per_page = 100;
$total_pages = ceil($number_of_fetched_rows / $number_of_results_per_page);
if (isset($_GET['page']) && is_numeric($_GET['page'])) {
$show_page = $_GET['page'];
if ($show_page > 0 && $show_page <= $total_pages) {
$start = ($show_page -1) * $number_of_results_per_page;
$end = $start + $number_of_results_per_page;
}
else {
$start = 0;
$end = $number_of_results_per_page;
}
}
else {
$start = 0;
$end = $number_of_results_per_page;
}
for ($page_i = 1; $page_i <= $total_pages; $page_i++) {
echo "<a href='__filter_mysql_data.php?page=$page_i'>| $page_i |</a> ";
}
}
So, user enters month (10), script displays all rows where month is 10; displays page No 1. But if user click on other page number, script displays all data from mysql (all months, not only 10)
What I see - when click on other page number, page reloads, that means that values of php variables "dissapears". As understand after page reload $date_month value is not set (has lost/"dissapears") ? How to keep the value? Or may be some better solution for pagination?
Update.
Behavior is following:
1) in input field set month 10 (October);
2) click on button and get displayed data from mysql where month is 10 (October); so far is ok
3) click on page number 2 and get displayed all data from mysql (all months, not only 10 (October))
Tried to use LIMIT however it does not help.
Possibly problem is related with this code
for ($page_i = 1; $page_i <= $total_pages; $page_i++) {
echo "<a href='__filter_mysql_data.php?page=$page_i'>| $page_i |</a> ";
}
When click on $page_i for not understandable (for me) reasons get displayed all (not filtered) data from mysql. If I use LIMIT also get displayed not filtered results from mysql....
Use LIMIT in your query, have a look at the following example , you can try something like :
SELECT
*
FROM
2_1_journal
WHERE
RecordMonth = ?
LIMIT [start_row],[number_of_rows_per_page]
So for example lets say you have 2 pages with 10 rows per page then the LIMIT for the 2 queries (one per page) will be:
1) LIMIT 0,10
2) LIMIT 10,10
You should change your query like this:
SELECT * FROM 2_1_journal WHERE RecordMonth = ? LIMIT = $number_of_results_per_page OFFSET ($page_number*$number_of_results_per_page);
Here you need to calculate the page number also and you should use the limit and offset concept of mysql.
Is it possible to create pagination without getting all elements of table?
But with pages in GET like /1 /666…
It usually involves issuing two queries: one to get your "slice" of the result set, and one to get the total number of records. From there, you can work out how many pages you have and build pagination accordingly.
A simply example:
<?php
$where = ""; // your WHERE clause would go in here
$batch = 10; // how many results to show at any one time
$page = (intval($_GET['page']) > 0) ? intval($_GET['page']) : 1;
$start = $page-1/$batch;
$pages = ceil($total/$batch);
$sql = "SELECT COUNT(*) AS total FROM tbl $where";
$res = mysql_query($sql);
$row = mysql_fetch_assoc($res);
$total = $row['total'];
// start pagination
$paging = '<p class="paging">Pages:';
for ($i=1; $i <= $pages; $i++) {
if ($i==$page) {
$paging.= sprintf(' <span class="current">%d</a>', $i);
} else {
$paging.= sprintf(' %1$d', $i);
}
}
$paging.= sprintf' (%d total; showing %d to %d)', $total, $start+1, min($total, $start+$batch));
And then to see your pagination links:
...
// loop over result set here
// render pagination links
echo $paging;
I hope this helps.
Yes, using mySQL's LIMIT clause. Most pagination tutorials make good examples of how to use it.
See these questions for further links and information:
How do you implement pagination in PHP?
Searching for advanced php/mysql pagination script
more results
You can use LIMIT to paginate over your result set.
SELECT * FROM comments WHERE post_id = 1 LIMIT 5, 10
where LIMIT 5 means 5 comments and 10 is the offset. You can also use the longer syntax:
... LIMIT 5 OFFSET 10
I've already created a query to mysql that will give 20 results from mysql table etc. "cat"
heres the calling:
if(isset($_GET['cat']))
{
$query = "SELECT game_title,game_desc,....
FROM games WHERE cat_id='".validate_input($_GET['cat'])."' LIMIT 20";
}
...
by this I manage to get the results I wanted. What I am asking here is how can I create a "button" that will load the next "20" records from table "cat" (something like Buttons).
<?
$cn=mysql_connect("localhost","root","root") or die(mysql_error());
mysql_select_db("db56") or die(mysql_error());
$sql="select count(*) from emp";
$result=mysql_query($sql);
$r=mysql_fetch_row($result);
$record=$r[0];
$pagesize=20;
$totalpages=$record/$pagesize;
$currpage=$_GET["pg"];
if(!isset($currpage))
$start=0;
else {
$currpage--;
$start= $currpage * $pagesize;
}
$end=$start+$pagesize;
$sql="select * from emp limit $start,$pagesize";
$result=mysql_query($sql);
if($result){
print "<table border='1'>";
print "<tr><th>No</th><th>Name</th><th>Date</th></tr>";
while($r=mysql_fetch_row($result))
{
print "<tr><td>$r[0]</td><td>$r[1]</td><td>$r[2]</td></tr>";
}
print "</table>";
}
for($i=1;$i<=$totalpages;$i++){
print "<a href='listemp.php?pg=$i'> $i </a>";
}
?>
If you keep track of what page you're on, in the URL or a hidden field or session variable, you can use that to work out the limit. For example, page 2 should show limit 20 from row 20 (20 times the page offset).
You can pass two SQL parameters to LIMIT (put a comma between them) If you do, the first tells SQL how many records to skip (ie the offset of the first record) and the 2nd parameter is the one you're already using (how many records to return).
So just put a variable in your "next" link that says what page to display. You can pass the offset in this link, but it's pretty common to pass the "page number" instead, and multiply by the number of records per page before sticking it in the sql.
next page
With a bit more work, you can make a "previous page" link, and make the correct links non-clickable when you're at the first/last page.
Pass along a parameter that tells the script that you want another chunk of the results and not just the first batch.
So for the link it could be like this:
example.com/results.php?cat=1&page=2
Where page= will tell the script what page you want to return.
Then you want to turn that LIMIT number you have so that you can work out some simple maths
$results_cnt = 20; //--rows you want per page of results
Now in your script you'll check to see if the page variable has been set. If not, default the start row to return from the first. But as you want to return different pages/sets of results, a little math is needed in order to start at the proper row.
if(isset($_GET["page"]) //--see if the variable is even there
{
$page_num = (int)$_GET["page"]; //--forcing it to always be an integer
$start_row = $results_cnt * ($page_num - 1);
/* --
what happens:
($results_cnt currently at 20)
on page one (page=1), start at row 0
math: 20 * (1 - 1) = 0
on page two (page=2), start at row 20
math: 20 * (2 - 1) = 20
on page three (page=3), start at row 40
math: 20 * (3 - 1) = 40
etc.
*/
}
else
$start_row = 0;
Now, having set the correct starting row, adjust the SQL query to use the variables like so:
if(isset($_GET['cat']))
{
$query = "SELECT game_title,game_desc,....
FROM games
WHERE cat_id='".validate_input($_GET['cat'])."'
LIMIT $start_row, $results_cnt";
}
OK I got it fixed I guess...
in index.php:
<?php
$games = array();
$count = 1;
$total = 0;
if(isset($_GET['cat']))
{
$query = "SELECT game_title,game_desc,.... FROM games WHERE cat_id='".validate_input($_GET['cat'])."' LIMIT 20";
$total = mysql_num_rows(mysql_query("SELECT 1 FROM games WHERE cat_id='".validate_input($_GET['cat'])."'"));
}
$query_result = #mysql_query ($query) OR error(mysql_error(), __LINE__, __FILE__, 0, '', '');
while ($info = #mysql_fetch_array($query_result))
{
/* -- here goes the infos.. */
$games[$info['game_title']]['game_title'] = $info['game_title'];
etc..
if(isset($_GET['cat']))
{
/* -- for template engine */
$page->SetLoop ('PAGES', pagenav($total,$_GET['page'],20,$config['site_url'].'?cat='.$_GET['cat'],1,$lang));
}
--end php
and in funct.php
--start php
function pagenav($total,$page,$perpage,$url,$posts=0)
{
$page_arr = array();
$arr_count = 0;
if($posts)
{
$symb='&';
}
else
{
$symb='?';
}
$total_pages = ceil($total/$perpage);
$llimit = 1;
$rlimit = $total_pages;
$window = 5;
$html = '';
if ($page<1 || !$page)
{
$page=1;
}
if(($page - floor($window/5)) <= 0)
{
$llimit = 1;
if($window > $total_pages)
{
$rlimit = $total_pages;
}
else
{
$rlimit = $window;
}
}
else
{
if(($page + floor($window/2)) > $total_pages)
{
if ($total_pages - $window < 0)
{
$llimit = 1;
}
else
{
$llimit = $total_pages - $window + 1;
}
$rlimit = $total_pages;
}
else
{
$llimit = $page - floor($window/2);
$rlimit = $page + floor($window/2);
}
}
if ($page>1)
{
$page_arr[$arr_count]['title'] = 'Prev';
$page_arr[$arr_count]['link'] = $url.$symb.'page='.($page-1);
$page_arr[$arr_count]['current'] = 0;
$arr_count++;
}
for ($x=$llimit;$x <= $rlimit;$x++)
{
if ($x <> $page)
{
$page_arr[$arr_count]['title'] = $x;
$page_arr[$arr_count]['link'] = $url.$symb.'page='.($x);
$page_arr[$arr_count]['current'] = 0;
}
else
{
$page_arr[$arr_count]['title'] = $x;
$page_arr[$arr_count]['link'] = $url.$symb.'page='.($x);
$page_arr[$arr_count]['current'] = 1;
}
$arr_count++;
}
if($page < $total_pages)
{
$page_arr[$arr_count]['title'] = 'Next';
$page_arr[$arr_count]['link'] = $url.$symb.'page='.($page+1);
$page_arr[$arr_count]['current'] = 0;
$arr_count++;
}
return $page_arr;
}
?>
and call it by
{LOOP: PAGES}{PAGES.title} {/LOOP: PAGES}
in an .html file..
it works perfectly but when I press the number 2 or next to get the next 20 records it jumps back to the first 20...
on the browser it reads http://siteurl/?cat=1&page=2
I can't figure out why.