I was looking for a simple pagination script and found one here, this seems to be working just fine.
However, when i click on "2", as in page 2, it just shows the records of page 2 underneath those that are already there. So basically if I would click on page 214 it still shows all of the records on one page.
I am not very experienced with PHP so i couldn't figure out what was wrong with the paginator.class.php, hopefully someone here can.
This is the code on the page where it should do the pagination:
else {
$query = "SELECT COUNT(*) FROM products";
$result = mysql_query($query) or die(mysql_error());
$num_rows = mysql_fetch_row($result);
$pages = new Paginator;
$pages->items_total = $num_rows[0];
$pages->mid_range = 9;
$pages->paginate();
$query1 = "SELECT serial, name, description, price, picture FROM products WHERE serial != '' ORDER BY serial ASC $pages->limit";
$result = mysql_query($query1) or die(mysql_error());
while ($row = mysql_fetch_array($result))
{
echo '<div style="margin-bottom:10px;display:inline-block;background-color:#E3E3E3;width:190px;height:200px;"><img style="padding-top:10px;padding-left:25px;width:150px;height:150px;" src="'.htmlspecialchars($row['picture']).'"><br><div align="center"><b>'.htmlspecialchars($row['name']).'</b><br><h6>€'.htmlspecialchars($row['price']).'</h6></div></div> ';
};
echo ' ';
echo '<br><br><div style="margin-left:330px;">';
echo $pages->display_pages();
echo '</div>';
}
The paginator.class.php can be found on the website I just mentioned.
The issue lies in your query:
"SELECT serial, name, description, price, picture FROM products WHERE serial != '' ORDER BY serial ASC $pages->limit"
You need to determine what the value of $pages->limit is. It seems to me that instead of calculating how many records should be displayed on each page (let's say 10 for argument's sake) and then determining what page you're on and setting the LIMIT condition.
What it should be set to is something like this:
LIMIT 30, 10
That's for page 4 - it displays records 30-40, rather than what I suspect it's doing, which is
LIMIT 40
That line will simply show up to 40 records and not close the lower bound of the window.
FYI take a look at the MySQL SELECT syntax in the manual.
Related
I am a beginner when it comes to PHP and it is not my specialty, I am rather in the front end and I have a big problem.
I need to edit one of the tables after a guy who doesn't work with our company anymore and it seemed simple to me at first, but I can't find a solution.
I have a table with 4 columns: Date, Full Name, Login, and Points. Records of added points are saved in the database, but each action adding points creates a new record in the database, let's say:
Date
Full Name
Login
Points
04/10/2021
John Kovalsky
koval
10
04/11/2021
John Kovalsky
koval
20
04/12/2021
John Kovalsky
koval
15
The script below works, and I can almost understand the syntax, there is a display limit set here and a table pagination added. The script displays all records in the database.
The problem is that I need exactly the same, but with the sum of the user's points, so that a given user is displayed only once, and in the "Points" column, the sum of all his points is displayed.
I tried with the array_sum () function, but it enumerates all the records in the database for me. The script looks like this:
<?php
$login = $_GET['login'];
$_SESSION["login"] = $login;
include('Pagination.php');
include('config.php');
$limit = 200;
$queryNum = $db->query("SELECT COUNT(*) as ID FROM db_main");
$resultNum = $queryNum->fetch_assoc();
$rowCount = $resultNum['ID'];
$pagConfig = array(
'totalRows' => $rowCount,
'perPage' => $limit,
'link_func' => 'searchFilter'
);
$pagination = new Pagination($pagConfig);
$query = $db->query("SELECT * FROM db_main LIMIT $limit");
echo "<center>";
echo "<table id=\"tabela\" cellpadding=\"2\" border=1>";
echo "<tr>";
echo "<th>".'Date'."</th>";
echo "<th>".'Full Name'."</th>";
echo "<th>".'Login'."</th>";
echo "<th>".'Points'."</th>";
echo "</tr>";
echo "</tr>";
if($query->num_rows > 0){
?>
<?php
while($r = $query->fetch_assoc()){
echo "<tr>";
echo "<td>".$r['Date']."</td>";
echo "<td>".$r['Full_name']."</td>";
echo "<td>".$r['Login']."</td>";
echo "<td>".$r['Points']."</td>";
echo "</tr> </center>";
}
echo $pagination->createLinks();
}
?>
Please help, I have no idea how to do it. I will be very grateful for your help and hints.
You could do it by using a different query.
First, get all unique users.
$db->query("SELECT COUNT(DISTINCT(Full_name)) as ID FROM db_main");
Now get the collected data for each user.
$db->query("SELECT MAX(Date) AS Date, Full_name, Login, SUM(Points) AS Points FROM db_main GROUP BY Full_name LIMIT $limit");
Using the GROUP option will make sure you get one row per user.
The SUM will give you the amount of all the user's points.
The MAX(Day) will return user's the last day field.
There are two assumptions here, that the login is always the same for the user, and that the Points field is numeric and not a string.
I know there are libraries etc that I could use to get this sorted but Im almost there with my code.
A little about the code and what it's trying to do. I have a mysql table where there are various news articles and grouped in categories of news.
I have managed to get a forward button working. So it looks for the next news article that is in the same category. This works and the code is below.
//Gets the next story from the same story type in line.
$query= "SELECT * FROM news WHERE storytype2 = '$storytype2' AND id > '$currentid'";
$result = mysql_query($query) or die ("Error in query: $query " . mysql_error());
$row = mysql_fetch_array($result);
$num_results = mysql_num_rows($result);
if ($num_results > 0){
echo "<td width=\"20%\"align=\"right\"><img title=\"Next News\" src=\"webImg/forwardarrow.png\"/></td></tr>";
}else{
echo "<td width=\"20%\"align=\"right\"></td></tr>";
}
//End of the next button
However, when I try do the same for the previous button. All I ever seem to get back is the first id of that category regardless of where my iteration is. For example, if I am on news article 10 and try to go to previous one which say has an id of 7 it will automatically show the first news article within that category, say id 4.
Below is the code.
//Gets the next story from the same story type in line.
$query= "SELECT * FROM news WHERE storytype2 = '$storytype2' AND id < '$currentid'";
$result = mysql_query($query) or die ("Error in query: $query " . mysql_error());
$row = mysql_fetch_array($result);
$num_results = mysql_num_rows($result);
if ($num_results > 0){
echo "<td width=\"20%\"align=\"left\"><img title=\"Previous News\" src=\"webImg/backarrow.png\"/></td>";
}else{
echo "<td width=\"20%\"align=\"left\"></td>";
}
//End of the next button
What have I done wrong?
Thanks
Neither of your queries is correct. Your "Next" code selects any row whose ID is higher than the current, not necessarily the next one; if you get the next one, it's just by accident.
You should use ORDER BY and LIMIT to control which row is selected:
Next:
SELECT *
FROM news
WHERE storytype2 = '$storytype2' AND id > '$currentid'
ORDER BY id
LIMIT 1
Previous:
SELECT *
FROM news
WHERE storytype2 = '$storytype2' AND id < '$currentid'
ORDER BY id DESC
LIMIT 1
Without any further information, I don't think you can assume that the first row of your queries will be the ID you're looking for. Ordering by ID first will probably solve your problem; you can also limit your query to one row, since it's the only one you're looking at. Something like the following would probably solve your problem (where x is $storytype2 and y is $currentid:
SELECT * FROM news
WHERE storytype2 = x
AND id < y
ORDER BY id DESC /* <-- THIS */
LIMIT 1
Use ORDER BY id ASC for the other case.
Note that the MySQL family of PHP is deprecated and support thereof will disappear, if it hasn't yet. Please look into PDO or MySQLi.
Note also that you are inserting a variable into SQL code directly, which is never a good idea. I hope you have some good input checks on your variables.
Let's look at the PDO way to get the previous article ID:
$dbh = new PDO(..);
// Use ? where dynamic input will come
$sql = $dbh->prepare('SELECT * FROM news
WHERE storytype2 = ?
AND id < ?
ORDER BY id DESC
LIMIT 1');
// Fill the ? safely with PDO's execute function
$sql->execute(array($storytype2, $currentid));
$result = $sql->fetch(PDO::FETCH_ASSOC);
if($result && isset($result['id'])) {
// Process previous ID
}
I am getting 10 rows with the highest ID from a table ...
$result = pg_query($dbconn, "SELECT w_news_id, name, w_newsnachricht, w_newsdatum FROM adempiere.w_news ORDER BY w_news_id DESC LIMIT 10");
... then I build 10 divs in a while loop:
while ($row = pg_fetch_row($result)) {
// building divs here
}
BUT I want to also include the name that belongs to the next w_news_id in that same div (as a "teaser" for the "next"-arrow). So I was thinking I have to run a second query with the ID that would be next in the loop.
How is the SQL syntax for that? Or is there maybe a better way to do this?
You can use the lead window function:
SELECT w_news_id, name, w_newsnachricht, w_newsdatum,
LEAD (name) OVER (ORDER BY w_news_id) AS next_name
FROM adempiere.w_news
ORDER BY w_news_id DESC
LIMIT 10
You can select one more record - LIMIT 11, instead of 10, and process it differently in PHP.
$result = pg_query($dbconn, "SELECT w_news_id, name, w_newsnachricht, w_newsdatum FROM adempiere.w_news ORDER BY w_news_id DESC LIMIT 11");
$i = 0;
while ($row = pg_fetch_row($result) and $i < 10) {
$i++;
// building divs here
}
// then process the arrow and teaser separately (if present)
if ($row = pg_fetch_row($result)) {
// show teaser div
}
UPDATE
The window function solution provided by Mureinik is better.
I have a page named 'job.php', currently this page is showing all posted job. But now I want to show only 5 latest posts. And if anyone want to check the previous posts, they can click next button thus more 5 posts will be seen. There should be a previous button too.
Following is my code:
$result1 = mysql_query("SELECT * FROM job ORDER BY ID DESC");
$num_row = mysql_num_rows($result1);
while($row1 = mysql_fetch_array($result1)){
$cat=$row1['Category'];
$title=$row1['Title'];
echo "Job field: $cat<br/> Title: $title<br/>";
}
N:B: It's not pagination. I don't want to show page numbers, just want to show next & previous button.
There are 100s of articles available on the Internet
Create Awesome PHP/MYSQL Pagination
PHP / MySQL select data and split on pages
If you want to do on your own:
Use LIMIT keywords in your query.
Pass the page and the multiplier to the LIMIT.
Some code
<?php
$limit = 5;
$start = (int)(($page - 1 ) * $limit);
$page = mysql_real_escape_string($_GET["page"]);
$query = "SELECT * FROM `table` LIMIT $start, {(int)$page + $limit}"
?>
There are two ways to achieve this.
1) In the query itself by using LIMIT
$result1 = mysql_query("SELECT * FROM job ORDER BY ID DESC LIMIT 1, 5");
2 ) By using loop
$i = 0;
while($row1 = mysql_fetch_array($result1)){
if($i < 5) {
$cat=$row1['Category'];
$title=$row1['Title'];
echo "Job field: $cat<br/> Title: $title<br/>";
$i++;
}
}
You can pass the current value to URL and get it back by using $_GET..
You can use this query:
Select * from table_name ORDER BY ID DESC LIMIT 5;
I feel its better to use pagination. If you want dont want to show page nos, better hide it or just modify the code. If you planning to do it manually its a bit messy
You can use LIMIT in you mysql query:
$result1 = mysql_query("SELECT * FROM job ORDER BY ID DESC LIMIT 0, 5");
I am not realy a php programmer myself, so any help would be appreciated.
I run a website on cms e107.
Now I have installed a menu plugin called "Recent news menu"
This will display the latest news articles in the selected menu area on the site.
Now my problem is that it also displays news that is set to "Not display" (see picture)
Can anyone help how to get this not displayed?
Here is all the code:
<?php
global $sql2, $tp;
$caption = "Recent news";
$no_news = "No news items";
$eol_separator = "</td></tr>";
$sol_separator = "<tr><td style='width:0%;text-align:left;'>";
$qry = "SELECT news_id, news_title FROM #news WHERE news_render_type = 0 ORDER BY news_id DESC LIMIT 0,5";
if($sql2->db_Select_gen($qry))
{
$n_text = "<table style='width:100%;'>";
while ($row = $sql2->db_Fetch())
{
$title = $tp->toHTML($row['news_title']);
$n_text .=$sol_separator ."<a href='".e_HTTP."news.php?item.".$row['news_id']."'>".$title."</a>".$eol_separator;
}
$n_text .= "</table>";
}
else
{
$n_text = $no_news;
}
$ns->tablerender($caption, $n_text);
Since the code of this plugin doesn't look very good in general, I guess you might not want to use this plugin and look for a better one... but in case you want to use this plugin you could adjust the db query so that the items, which are not ment to be displayed are not selected. Something like this:
$qry = "SELECT news_id, news_title
FROM #news
WHERE news_render_type = 0
AND display = 1
ORDER BY news_id DESC
LIMIT 0,5";
Depending on how the display information is stored, you might need to make it AND display > 0.