I am building a product catalog, that I want to be determined depending on users device. ie., if windows device show particular products. I have my products listing absolutely fine, however when implementing pagination, I am stuck.
I want only 6 items to be listed per page, I have more results. However more results are showing on the first page. When I select to go next, the ID number changes, to show it is showing me the next result, but it continues to show the same page, so obviously I am missing/got confused somewhere with my code. I'd appreciate any advice:
$current_url = $_SERVER['REQUEST_URI'];
$current_url = substr($current_url, 1);
$results = mysqli_query($conn, "SELECT * FROM apps A INNER JOIN device D ON D.DeviceID = A.DeviceID WHERE D.DeviceName = '$os'");
$foundnum = mysqli_num_rows($results);
if ($foundnum==0){
echo "Sorry, there are currently no applications that are compatible with your device. Please try another option.";
} else {
echo "$foundnum applications are avaliable for '$os' devices:<p>";
$per_page = 6;
$start = $_GET['start'];
$max_pages = ceil($foundnum / $per_page);
if(!$start)
$start=0;
while($obj = $results->fetch_object()){
$applicationid=$obj->ApplicationID;
$start=0;
echo "<div class=\"col-4 col-sm-4 col-lg-4\">";
echo '<form method="post" action="cart_update.php">';
echo "<div id='product'><a href='appproduct.php?id=$applicationid'><img src='images/app_images/$applicationid.jpg' alt='Product picture'/></div>";
echo '<h2>'.$obj->ApplicationName.'</h2>';
echo '<p>'.$obj->ApplicationDescription.'</p>';
if($obj->App_cost=="0.00"){
echo '<p>Free</p>';
}else{
echo '<p>£'.$obj->App_cost.'</p>';
}
echo '<button class="add_to_cart">Add To Cart</button>';
echo '<input type="hidden" name="product_code" value="'.$obj->ApplicationID.'" />';
echo '<input type="hidden" name="type" value="add" />';
echo '<input type="hidden" name="return_url" value="'.$current_url.'" />';
echo '</form><br /><br /></div>';
}
//Pagination Starts
echo "<center>";
$prev = $start - $per_page;
$next = $start + $per_page;
$last = $max_pages - 1;
if($max_pages > 1){
//previous button
if (!($start<=0))
echo "<a href='index.php?os=$os=Search+source+code&start=$prev'>Prev |</a> ";
//pages
$i = 0;
for ($counter = 1; $counter <= $max_pages; $counter++){
if($i == $start){
echo " <a href='index.php?os=$os=Search+source+code&start=$i'><b> $counter |</b></a> ";
}
else {
echo " <a href='index.php?os=$os=Search+source+code&start=$i'> $counter |</a> ";
}
$i = $i + $per_page;
}
}
//next button
if (!($start >=$foundnum-$per_page))
echo " <a href='index.php?os=$os=Search+source+code&start=$next'> Next</a> ";
}
echo "</center>"
?>
You should try to do the pagination via database, instead of loading all the results eagerly. If you had 100000 records and wanted to show only first 6 of them, you'd need to fetch 99994 records you might not use. Try to use limit of sql.
As for your problem with "bolding" current page number, you have logic error here:
$i = 0;
for ($counter = 1; $counter <= $max_pages; $counter++) {
if($i == $start){
echo " <a href='index.php?os=$os=Search+source+code&start=$i'><b> $counter |</b></a> ";
} else {
echo " <a href='index.php?os=$os=Search+source+code&start=$i'> $counter |</a> ";
}
$i = $i + $per_page;
According to this snippet you are comparing $i to $start, where $i is always equal to 0, so it will bold anything only on first page.
You need to use LIMIT in your MySQL query to only get a page of results at a time. It will look something like LIMIT 0, 6.
change this line it will work
$results = mysqli_query($conn, "SELECT * FROM apps A INNER JOIN device D ON D.DeviceID = A.DeviceID WHERE D.DeviceName = '$os' LIMIT $_GET['start'], 6;");
but it's not the best way to do pagination or putting a variable straight from global variables. I would advise you to use at leat mysql escape string function in php
Related
I have a form that uses the method post. The form contains a submit button and on clicking it, my database records get displayed in an html table. I would like to limit the number of rows (5) displayed to each page, but I'm not looking to use GET. Is there any way I can do that with my post method?
// My form using post method
<form action = "" name = "dealer_call_log.php" id = "dealer_call_log.php" method = "post">
//Data displayed in the table below from post
$record_per_page = 5;
$page = '';
if(isset($_GET['page'])){
$page = $_GET['page'];
}
else{
$page = 1;
}
$start_from = ($page - 1) * $record_per_page;
if(isset($_POST['submit'])){
echo '<center>';
echo '<br>';
$sql = "SELECT SFID, Comment, Time FROM tbl_call_log_detail
WHERE
(dealer_id = '$call_id' AND '$endDate'='1970-01-01' AND '$startDate' ='1970-01-01')
OR ( Time <= '$endDate' AND Time >= '$startDate'
AND (dealer_id = '$call_id' OR'$call_id'='' ))
OR ('$endDate'='1970-01-01' AND '$startDate' ='1970-01-01' AND '$call_id'='')
ORDER BY Time DESC LIMIT $start_from, $record_per_page" ;
$result = mysqli_query($conn, $sql);
$rows = mysqli_num_rows($result);
$all_property = array();
echo "<table class = 'data-table' border = '1' cellpadding = '9' bgcolor = '#CCCCCC'>
<tr class = 'data-heading'>";
while($property = mysqli_fetch_field($result)){
echo '<td><b> '. $property ->name. ' </b></td>';
array_push($all_property, $property ->name);
}
echo '</tr>';
}
while ($row = mysqli_fetch_array($result)){
echo '<tr>';
foreach($all_property as $item){
echo '<td> '. $row[$item] . ' </td>';
}
echo '</tr>';
echo '</center>';
}
}
$page_query = "SELECT * FROM tbl_call_log_detail ";
$page_result = mysqli_query($conn, $page_query);
$total_records = mysqli_num_rows($page_result);
$total_pages = ceil($total_records/$record_per_page);
$start_loop = $page;
$difference = $total_pages - $page;
if($difference <= $total_pages){
$start_loop = $total_pages - $difference;
}
$end_loop = $start_loop + 2;
if($difference > $total_pages){
$end_loop = $total_pages;
}
if($page > 1){
echo "<a href= 'dealer_call_log.php?page=1'>First</a>";
echo "<a href= 'dealer_call_log.php?page=".($page - 1)."'><<</a>";
}
for ($i = $start_loop; $i <= $end_loop; $i++){
echo "<a href= 'dealer_call_log.php?page=".$i."'>".$i."</a>";
}
if($page <= $end_loop){
echo "<a href= 'dealer_call_log.php?page=".($page + 1)."'>>></a>";
echo "<a href= 'dealer_call_log.php?page=".$total_pages."'>Last</a>";
}
if($page < 1){
$page = 1;
}
echo '</table>';
Any help would be appreciated. Thanks!
You can use LIMIT 20 OFFSET 0 to get the first 20 results. Then for the next page you can use LIMIT 20 OFFSET 20 the get the second set of 20 results. See W3Schools for more information on this
You can also keep track of your pagenumber with post but you'll have to post it in an input field. You can use an input type hidden like so: <input type="hidden" name="pageNumber" value="0"> and change the value everytime you switch page.
Then you could do something like this:
$limit = 20;
if(isset($_POST['pageNumber']) {
$page = $_POST['pageNumber'];
} else {
$page = 0;
}
$sql = "SELECT sfid, comment, time_stamp, time_of_submission FROM tbl_call_log_detail
WHERE
(dealer_id = '$call_id' AND '$endDate'='1970-01-01' AND '$startDate' ='1970-01-01')
OR ( time_stamp <= '$endDate' AND time_stamp >= '$startDate'
AND (dealer_id = '$call_id' OR'$call_id'='' ))
OR ('$endDate'='1970-01-01' AND '$startDate' ='1970-01-01' AND '$call_id'='')
ORDER BY time_stamp DESC
LIMIT " . $limit . " OFFSET " . $page * $limit;
echo '<input type="hidden" name="pageNumber" value="' . $page + 1 . '">'
Here is how the index will show the links for pagination:
total record = 40
per_page = 2
and now for the link generating:
<?php
if ($pagination->total_pages() > 1) {
if ($pagination->has_previous_page()) {
echo "<a href='index.php?page=";
echo $pagination->previous_page();
echo "&refone=" . $refone ."'>« PREVEOUS</a> ";
}
for ($i = 1; $i <= $pagination->total_pages(); $i++) {
if ($i == $page) {
echo " <span class=\"selected\">{$i}</span> ";
} else {
echo " <a href='index.php?page=" . $i . "&refone=" . $refone ."'>" . $i . "</a> ";
}
}
if ($pagination->has_next_page()) {
echo " <a href='index.php?page=";
echo $pagination->next_page();
echo "&refone=" . $refone."'>NEXT »</a> ";
}
}
?>
metion code will generate the links for pagination but the problem is it is showing many links
for example:
we have 40 record in each page we need to show 2 records so it will generate 20 links( for ($i = 1; $i <= $pagination->total_pages(); $i++) {) here is the code which will calculate for the links but I want to echo only 8 links the rest should be hid like
1-2-3-4-5-6-7-8-Next
prev-2-3-4-5-6-7-8-9-next
but its showing all
I found my answer::
here I need to change the code for the for statement:
for ($i = $page - $per_page; $i <= $page + $per_page; $i++){
this will work for me.
My question is rather lengthy, so I'll get right to it. I have a search engine set up that sends data (GET method) to a php script which queries a MySQL database and then displays the results. You can view the project, to get a better understanding, here: http://www.quinterest.org/testcategory/
The form consist of a search box as well as a multiple select option that narrow the search.
Everything thing works wonderfully, but there is one thing I would like to change and I don't know how. If someone could explain, in detail, what I need to do to be able to show the results (I figure it will be in a div written in the HTML?) from the query on the same page as the original form without the need to refresh the page?
If you would like an example, here is one: http://quizbowldb.com/search
The search stays on the same page.
P.S. I know the mysql_ functions are outdated. Please don't harass me. I'm all very new to this still and the mysql_ functions are simple, easy and good enough for what I need. When I get further programming experience (I'm still in middle school), I may convert it to PDO or MySQLi.
HTML Form:
<form action='search.php' method='GET' class="form-search">
<input type='text' placeholder="What would you like to learn about?" class="input-xxlarge search-query" id="inputInfo" name='search'><br></br>
<input type='submit' class="btn btn-large btn-primary" name='submit' value='Search'></br>
<select multiple="multiple" name='category[]'>
<option value="%">All</option>
<option>Literature</option>
<option>History</option>
<option>Science</option>
<option>Fine Arts</option>
<option>Trash</option>
<option>Mythology</option>
<option>Phylosophy</option>
<option>Social Science</option>
<option>Religion</option>
<option>Geography</option>
</select>
</center>
</form>
search.php
<?php
$button = $_GET ['submit'];
$search = $_GET ['search'];
print $search;
//validating search term length and connecting to db
if(strlen($search)<=1)
echo "Search term too short";
else{
echo "You searched for <b><em>$search</em></b> and ";
mysql_connect("fake","fake","fake");
mysql_select_db("quinterestdb");}
//validating search term for protection; if statement to avoid errors being displayed
if (strlen($search)>1){
mysql_real_escape_string($search);}
//exploding search with multiple words
$search_exploded = explode (" ", $search); //creates array of all terms in search
foreach($search_exploded as $search_each) //loops through array
{
$x++;
if($x==1)
$construct .="Answer LIKE '%$search_each%'"; //if only one value in array
else
$construct .="AND Answer LIKE '%$search_each%'"; //for each multiple value in array
}
$cat = $_GET ['category']; //preparing array (multiple choices)
if (is_array($cat))
{
foreach($cat as $val) //
{
if($val=="%") //if no category is selected
continue;
else //split array choices (separated by ' and ,)
$comma_separated = implode("','", $cat);
$newvar = "AND Category IN('$comma_separated')"; //if category is chosen
}
} //ignore for now
$constructs ="SELECT * FROM tossupsdb WHERE $construct $newvar"; //completed search query
//quering the database; if statement to avoid errors being displayed
if (strlen($search)>1){
$run = mysql_query($constructs);}
print "$constructs"; //ignore for now
//number of results found; if statement to avoid errors being displayed
if (strlen($search)>1){
$foundnum = mysql_num_rows($run);}
if ($foundnum==0)
echo "Sorry, there are no matching result for <b>$search</b>.</br></br>1.
Try more general words. for example: If you want to search 'how to create a website'
then use general keyword like 'create' 'website'</br>2. Try different words with similar
meaning</br>3. Please check your spelling";
else
{
echo " <span class='badge badge-info'> $foundnum </span> results were found:<hr size='5'>";
$per_page = 25; //preparing for pagination; results that appear per page
$start = $_POST['start']; //where to start results on page
$max_pages = ceil($foundnum / $per_page); //number of pages there will be
if(!$start) //starting at 0
$start=0;
$getquery = mysql_query("SELECT * FROM tossupsdb WHERE $construct $newvar LIMIT $start, $per_page");
while($runrows = mysql_fetch_array($getquery)) //fetching results
{
$answer = $runrows ['Answer']; //obtaining individual data from database
$category = $runrows ['Category']; //obtaining individual data from database
$num = $runrows ['Question #']; //obtaining individual data from database
$difficulty = $runrows ['Difficulty']; //obtaining individual data from database
$question = $runrows ['Question']; //obtaining individual data from database
$round = $runrows ['Round']; //obtaining individual data from database
$tournament = $runrows ['Tournament']; //obtaining individual data from database
$year = $runrows ['Year']; //obtaining individual data from database
//what will be displayed on the results page
echo "<div class='alert alert-info' style='border-radius: 20px'><div style='padding: 10px'>
<span class='label label-info' font-size='30px'><em>Tournament | Year | Round | Question # | Category</em></span></div>
<b>$tournament |</b> <b>$year |</b> <b>$round |</b> <b>$num |</b> <b>$category</b>
<p><em>Question:</em> $question</p>
<div class='alert alert-info'><em><strong>ANSWER:</strong></em> $answer</div></div><hr>
";
}
//Pagination Starts
echo "<center>";
$prev = $start - $per_page;
$next = $start + $per_page;
$adjacents = 3;
$last = $max_pages - 1;
if($max_pages > 1)
{
//previous button
if (!($start<=0))
echo " <a class='btn btn-primary btn-large' href='search.php?search=$search&submit=Search+source+code&start=$prev'>Prev</a> ";
//pages
if ($max_pages < 7 + ($adjacents * 2)) //not enough pages to bother breaking it up
{
$i = 0;
for ($counter = 1; $counter <= $max_pages; $counter++)
{
if ($i == $start){
echo " <a class='btn' href='search.php?search=$search&submit=Search+source+code&start=$i'><b>$counter</b></a> ";
}
else {
echo " <a class='btn' href='search.php?search=$search&submit=Search+source+code&start=$i'>$counter</a> ";
}
$i = $i + $per_page;
}
}
elseif($max_pages > 5 + ($adjacents * 2)) //enough pages to hide some
{
//close to beginning; only hide later pages
if(($start/$per_page) < 1 + ($adjacents * 2))
{
$i = 0;
for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++)
{
if ($i == $start){
echo " <a class='btn' href='search.php?search=$search&submit=Search+source+code&start=$i'><b>$counter</b></a> ";
}
else {
echo " <a class='btn' href='search.php?search=$search&submit=Search+source+code&start=$i'>$counter</a> ";
}
$i = $i + $per_page;
}
}
//in middle; hide some front and some back
elseif($max_pages - ($adjacents * 2) > ($start / $per_page) && ($start / $per_page) > ($adjacents * 2))
{
echo " <a class='btn' href='search.php?search=$search&submit=Search+source+code&start=0'>1</a> ";
echo " <a class='btn' href='search.php?search=$search&submit=Search+source+code&start=$per_page'>2</a> .... ";
$i = $start;
for ($counter = ($start/$per_page)+1; $counter < ($start / $per_page) + $adjacents + 2; $counter++)
{
if ($i == $start){
echo " <a class='btn' href='search.php?search=$search&submit=Search+source+code&start=$i'><b>$counter</b></a> ";
}
else {
echo " <a class='btn' href='search.php?search=$search&submit=Search+source+code&start=$i'>$counter</a> ";
}
$i = $i + $per_page;
}
}
//close to end; only hide early pages
else
{
echo " <a class='btn' href='search.php?search=$search&submit=Search+source+code&start=0'>1</a> ";
echo " <a class='btn' href='search.php?search=$search&submit=Search+source+code&start=$per_page'>2</a> .... ";
$i = $start;
for ($counter = ($start / $per_page) + 1; $counter <= $max_pages; $counter++)
{
if ($i == $start){
echo " <a class='btn' href='search.php?search=$search&submit=Search+source+code&start=$i'><b>$counter</b></a> ";
}
else {
echo " <a class='btn' href='search.php?search=$search&submit=Search+source+code&start=$i'>$counter</a> ";
}
$i = $i + $per_page;
}
}
}
//next button
if (!($start >=$foundnum-$per_page))
echo " <a class='btn btn-primary btn-large' href='search.php?search=$search&submit=Search+source+code&start=$next'>Next</a> ";
}
echo "</center>";
}
?>
You need to use AJAX to do that. Using AJAX, you send asynchronous requests (requests without loading the page) to the server.
This is how Google and other major search engines work. Learn about it here : Ajax tutorial
Ajax - Asynchronous JavaScript And XML
From Wikipedia definition of Ajax:
With Ajax, web applications can send data to, and retrieve data from, a server asynchronously (in the background) without interfering with the display and behavior of the existing page.
Data can be retrieved using the XMLHttpRequest object.
Despite the name, the use of XML is not required (JSON is often used instead), and the requests do not need to be asynchronous.
The simplest way to accomplish this is probably via jQuery, a JavaScript framework; by "simple", I mean the least work on your end:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script>
// This is the equivalent of the older $(document).ready() event
$(function(){
$('#search-form').on('submit', function(event){
event.preventDefault(); // prevents form submission
var data = $('#search-form').serialize(); // get all of the input variables in a neat little package
var action = $('#search-form').attr('action'); // get the page to get/post to
$.get(action, data, function(response, status, jqxhr){
$('#target').html(response);
});
});
});
</script>
Here, I add an id to your form so that I can directly target it. I also assume that there is a HTML element with an id of target that I can inject with the response HTML (which I also assume is only a fragment).
I have the following queries: the first as a count for pagination, the second to fill the resulting table with data. They both worked very well, but I want to add Ordering functionality to the table also, and have made some ham-fisted efforts in that direction.
Essentially, I have broken up the MySQL query into portions stored in variables, which may or may not be assigned based on the wishes of the user as expressed by the submitting and GETting of forms. I'm only at a beginner level, and this is what made logical sense to me. It is probably not the correct method!
The data is ordered by default as it is entered in the database. The table is filled 15 rows at a time. Ideally, the user could then choose to order the animal's data in another way - by age, or colour, for example. The choice is made via submitting a form to the page itself, the query is re-submitted, and the result is outputted in 15-row pages again.
So far, here is my code:
PAGINATION:
$genderid = $_GET['groupid'];
$sortby = $_GET['sortby'];
##################
if (isset($_GET['pageno'])) { $pageno = $_GET['pageno']; }
else { $pageno = 1; }
$initialcount = "SELECT count(*)
FROM profiles
WHERE ProfileName != 'Unknown'";
if ($genderid > 0) {
$genderquery = " AND ProfileGenderID = $genderid";
}
if ($sortby == 'age') {
$orderby = " ORDER BY ProfileYearOfBirth ASC";
}
elseif ($sortby == 'colour') {
$orderby = " ORDER BY ProfileAdultColourID ASC";
}
$finalcount = ($initialcount . ' ' . $genderquery . ' ' . $orderby);
$result = mysql_query($finalcount) or trigger_error();
$query_data = mysql_fetch_row($result);
$numrows = $query_data[0];
$rows_per_page = 15;
$lastpage = ceil($numrows/$rows_per_page);
$pageno = (int)$pageno;
if ($pageno > $lastpage) {
$pageno = $lastpage;
}
if ($pageno < 1) {
$pageno = 1;
}
$limit = 'LIMIT ' .($pageno - 1) * $rows_per_page .',' .$rows_per_page;
if ($pageno == 1)
{
echo '<p class="pagination">';
echo '<span class="first"><< First</span><span class="previous">< Previous</span>';
}
else
{
echo '<p class="pagination">';
echo "<span class='first'><a href='{$_SERVER['PHP_SELF']}?pageno=1'><< First</a></span>";
$prevpage = $pageno-1;
echo "<span id='class'><a href='{$_SERVER['PHP_SELF']}?pageno=$prevpage'>< Previous</a></span>";
}
echo '<span class="pagination-nav">' . "Page $pageno of $lastpage" . '</span>';
if ($pageno == $lastpage)
{
echo '<span class="next">Next ></span><span class="last">Last >></span>';
echo '</p>';
}
else
{
$nextpage = $pageno+1;
echo "<span class='next'><a href='{$_SERVER['PHP_SELF']}?pageno=$nextpage'>Next ></a></span>";
echo "<span class='last'><a href='{$_SERVER['PHP_SELF']}?pageno=$lastpage'>Last >></a></span>";
echo '</p>';
}
OUTPUT:
<table class="admin-display">
<thead>
<tr>
<th>Name:</th>
<th>Age:
<form class="sorting-form" method="GET" action="">
<input type="hidden" name="sortby" value="age" />
<input type="hidden" name="groupid" value="<?php echo $genderid; ?>" />
<input type="submit" value="⇑" class="sort-submit" />
</form>
</th>
<th>Colour:
<form class="sorting-form" method="GET" action="">
<input type="hidden" name="sortby" value="colour" />
<input type="hidden" name="groupid" value="<?php echo $genderid; ?>" />
<input type="submit" value="⇑" class="sort-submit" />
</form>
</th>
<th>Gender:</th>
<th>Owner:</th>
<th>Breeder:</th>
</tr>
</thead>
<?php
$initialquery = "SELECT ProfileID, ProfileOwnerID, ProfileBreederID,
ProfileGenderID, ProfileAdultColourID, ProfileColourModifierID, ProfileYearOfBirth,
ProfileYearOfDeath, ProfileLocalRegNumber, ProfileName,
owner.ContactFirstName AS owner_fname, owner.ContactLastName AS owner_lname,
breeder.ContactFirstName AS breeder_fname, breeder.ContactLastName AS breeder_lname,
BreedGender, BreedColour, BreedColourModifier
FROM profiles
LEFT JOIN contacts AS owner
ON ProfileOwnerID = owner.ContactID
LEFT JOIN contacts AS breeder
ON ProfileBreederID = breeder.ContactID
LEFT JOIN prm_breedgender
ON ProfileGenderID = prm_breedgender.BreedGenderID
LEFT JOIN prm_breedcolour
ON ProfileAdultColourID = prm_breedcolour.BreedColourID
LEFT JOIN prm_breedcolourmodifier
ON ProfileColourModifierID = prm_breedcolourmodifier.BreedColourModifierID
WHERE ProfileName != 'Unknown'";
$finalquery = ($initialquery . ' ' . $genderquery . ' ' . $orderby . ' ' . $limit);
$result = mysql_query($finalquery) or trigger_error("SQL", E_USER_ERROR);
//process results
The data still outputs correctly (initially), and the user can re-submit the query successfully also. The problem arises when - after ordering by anything other than default - I click to go forward a page. Once the page changes, the ordering returns to default. I don't know how to maintain that ORDER BY clause beyond the initial re-submission.
This is as far as I've gotten before I start breaking the code and things begin to get hairy. I need someone to point out the glaring error! Much thanks in advance :)
This sounds like it should be handled in an AJAX call. Theoretically, you can persist your initial and incremented state throughout the session (using the session variable, a hidden form field, or even a cookie) but I think you'll be happier with asynchronously grabbing X records at a time and keeping the arguments on the client side until you want to get the next page.
Per poster's inquiry, storing the necessary values in the session would look something like this:
session_start();
$startat = intval($_REQUEST["startat"]);
$numrows= intval($_REQUEST["numrows"]);
if (isset($_SESSION['base_query'])){
$query = $_SESSION['base_query'];
} else {
$query = <query construction minus limit clause>;
$_SESSION['base_query'] = $query;
}
$query .= " LIMIT $startat, $numrows";
<query db/ send results>
Does that give you the idea?
maybe you can get around this problem by using http://www.datatables.net/ ? it's a client side ajax solution that orders results for you. And you avoid reloading the whole page each time.
Ok, I worked on what I had for another few hours, and came up with a solution. It doesn't use AJAX, or SESSIONS, and is undoubtably horrible to behold, but it suits the skill level I'm at.
First off, I changed the pagination script to give a distinct value to the offset parameter:
$title = intval($_GET['groupid']);
$genderid = intval($_GET['groupid']);
$sortby = $_GET['sortby'];
##################################
$initialcount = "SELECT count(*) FROM profiles WHERE ProfileName != 'Unknown'";
if($genderid > 0) {
$where = "AND ProfileGenderID = $genderid";
$finalcount = ($initialcount . ' ' . $where);
}
else { $finalcount = $initialcount; }
$result = mysql_query($finalcount) or trigger_error("SQL", E_USER_ERROR);
$r = mysql_fetch_row($result);
$numrows = $r[0];
$rowsperpage = 15;
$totalpages = ceil($numrows / $rowsperpage);
if (isset($_GET['currentpage']) && is_numeric($_GET['currentpage'])) {
$currentpage = (int) $_GET['currentpage'];
}
else { $currentpage = 1; }
if ($currentpage > $totalpages) {
$currentpage = $totalpages;
}
if ($currentpage < 1)
{ $currentpage = 1; }
$offset = ($currentpage - 1) * $rowsperpage;
I also changed the pagination links to a) hold the value of the current gender (overall) sort, and the subsequent sort (age, colour); and b) to display numbered page links á la Google:
// range of num links to show
$range = 3;
##############
$range = 3;
echo '<p class="pagination">';
if ($currentpage == 1)
{
echo '<span class="first"><< First</span><span class="previous">< Previous</span>';
}
if ($currentpage > 1) {
echo "<span class='first'><a href='{$_SERVER['PHP_SELF']}?sortby=$sortby&groupid=$genderid¤tpage=1'><< First</a></span>";
$prevpage = $currentpage - 1;
echo "<span class='previous'><a href='{$_SERVER['PHP_SELF']}?sortby=$sortby&groupid=$genderid¤tpage=$prevpage'>< Previous</a></span>";
}
echo '<span class="pagination-nav">';
for ($x = ($currentpage - $range); $x < (($currentpage + $range) + 1); $x++) {
if (($x > 0) && ($x <= $totalpages)) {
if ($x == $currentpage) {
echo " [<b>$x</b>] ";
}
else {
echo " <a href='{$_SERVER['PHP_SELF']}?sortby=$sortby&groupid=$genderid¤tpage=$x'>$x</a> ";
}
}
}
echo '</span>';
if ($currentpage != $totalpages) {
$nextpage = $currentpage + 1;
echo "<span class='next'><a href='{$_SERVER['PHP_SELF']}?sortby=$sortby&groupid=$genderid¤tpage=$nextpage'>Next ></a></span>";
echo "<span class='last'><a href='{$_SERVER['PHP_SELF']}?sortby=$sortby&groupid=$genderid¤tpage=$totalpages'>Last >></a></span>";
}
if ($currentpage == $totalpages)
{
echo '<span class="next">Next ></span><span class="last">Last >></span>';
}
echo '</p>';
And finally constructed the query:
$baseQuery = "SELECT ProfileID, ProfileOwnerID, ProfileBreederID,
ProfileGenderID, ProfileAdultColourID, ProfileColourModifierID, ProfileYearOfBirth,
ProfileYearOfDeath, ProfileLocalRegNumber, ProfileName,
owner.ContactFirstName AS owner_fname, owner.ContactLastName AS owner_lname,
breeder.ContactFirstName AS breeder_fname, breeder.ContactLastName AS breeder_lname,
BreedGender, BreedColour, BreedColourModifier
FROM profiles
LEFT JOIN contacts AS owner
ON ProfileOwnerID = owner.ContactID
LEFT JOIN contacts AS breeder
ON ProfileBreederID = breeder.ContactID
LEFT JOIN prm_breedgender
ON ProfileGenderID = prm_breedgender.BreedGenderID
LEFT JOIN prm_breedcolour
ON ProfileAdultColourID = prm_breedcolour.BreedColourID
LEFT JOIN prm_breedcolourmodifier
ON ProfileColourModifierID = prm_breedcolourmodifier.BreedColourModifierID
WHERE ProfileName != 'Unknown'";
if($sortby == 'age') {
$orderby = "ORDER BY ProfileYearOfBirth ASC";
}
elseif ($sortby == 'colour') {
$orderby = "ORDER BY ProfileAdultColourID ASC";
}
$limitClause = "LIMIT $offset, $rowsperpage";
$finalQuery = ($baseQuery . ' ' . $where . ' ' . $orderby . ' ' . $limitClause);
$result = mysql_query($finalQuery) or trigger_error("SQL", E_USER_ERROR);
Effective as a hammer hitting a cheesecake :)
Much thanks to the contributors above, particularly for introducing me to INTVAL (and by progression, CASTING).
I have a small problem with my PHP pagination, I have 6 records and I display 2 at a time, when I click on next and it displays from 2 to 4 records, that works fine, But to display from 4 to 6 records, that does not work. I am not sure what im doing wrong. Anyone have any ideas ? the problem is to do with the calculation for the Next records to be displayed
<?php
$per_page = 2;
$start = $_GET['start'];
$query = mysql_query("SELECT * FROM Directory");
$record_count = mysql_num_rows($query);
$record_count = round($record_count / $per_page);
if(!$start) {
$start = 0;
}
$query = mysql_query("SELECT * FROM Directory LIMIT $start,$per_page") or die(mysql_error());
$row = mysql_num_rows($query);
// Output Records here
// Setup next and previous button variables
$prev = $start - $per_page;
$next = $start + $per_page;
echo '<p> <h4>';
if($prev < 0) {
echo 'Previous';
} else {
echo '<a href="directory.php?start='.$prev.'>Previous</a>';
}
echo ' ' . $start . ' of ' . $record_count;
if($next < $record_count) {
echo ' <a href="directory.php?start='.$next.'>Next</a>';
} else {
echo ' Next';
}
echo '</h4> </p>';
?>
It looks like it's a formatting issue. When I look at your source for the URL http://gebsbo.limewebs.com/directory/directory.php?start=1 I see:
<br /><p> <h4>Previous 1 of 4 <a href="directory.php?start=3>Next</a></h4> </p> </body>
It looks like you're missing a quote on the href attribute.
In your code, you want:
echo 'Previous';
and
echo ' Next';
use this code for calculating :
$num = 10; // number of items on page
$p = $_GET['page']; // the var that comes from url (for ex: htttp://..../xxx.php?page=3)
$r = mysql_query(" select * from your_table ");
$posts=mysql_num_rows($r); // total posts
$total=(($posts-1)/$num)+1; // toatal pages
$total=intval($total);
$p=intval($p);
if(empty($p) or $p<0 or !isset($p)) $p=1;
if($p>$total) $p=$total;
$start=$p*$num-$num;
// here print the html for pagination (for ex: htttp://...../xxx.php?page=1 .. 2 ...3 .... and so on ...) you can make a for() here
$r = mysql_query(" select * from your_table limit ".$start.", ".$num);
while (....) {
.....
}