Search function on PHP/HTML page using AJAX - php

Description: Trying to do a title search for videos within a PHP page with AJAX pagination.
Problem: "Search" button does not do anything when pressed. Instead, if I write something in "keywords" field and switch from page 1 to page 2 the date gets updated and shows videos with matching title. If I delete what I wrote in "keywords" field, and switch again between pages, the data gets updated. As mentioned, "Search" button does not work.
Fix: I would like to write in the text field and press "Search" button. The page should then update and show only the videos with the matching title.
search.php:
<!-- Testing the search -->
<p><b> Search all videos in database below: </b></p>
<ul>
<li>
<label for="keywords">Keywords</label>
<input type="text" id="keywords" name="keywords" size="50" maxlength="64" />
</li>
<li>
<input type="button" value="Search" onclick="loadData()" />
</li>
</ul>
search_videos.js:
* 'page' variable is used for pagination
...
function loadData(page){
$.ajax
({
type: "POST",
url: "search_videos.php",
data: { 'page': page, 'keywords': $('#keywords').val() },
success: function(msg)
{
loading_hide();
$("#container").html(msg);
}
});
}
...
Update: Below is what I get, after I press 2nd page and then 1st page again.
POST results:
Raw results (sorry for bad formatting):
005<div class='data' style='margin-bottom:10px'><ul><img src="images/link_pic.png" alt="error" width="164" height="128"><li>Title: <b>Video 1</b></br> Uploaded by: user1</br>Date added: 13/07/2013</li></br></br><img src="images/link_pic.png" alt="error" width="164" height="128"><li>Title: <b>ghg</b></br> Uploaded by: cacamaca</br>Date added: 21 Jul 2013 16:03</li></br></br><img src="images/link_pic.png" alt="error" width="164" height="128"><li>Title: <b>s</b></br> Uploaded by: cacamaca</br>Date added: 21 Jul 2013 16:23</li></br></br><img src="images/link_pic.png" alt="error" width="164" height="128"><li>Title: <b>s</b></br> Uploaded by: cacamaca</br>Date added: 21 Jul 2013 16:24</li></br></br><img src="images/link_pic.png" alt="error" width="164" height="128"><li>Title: <b>dg</b></br> Uploaded by: gdfgdf</br>Date added: data azi</li></br></br></ul></div><div class='pagination'><ul><li class='inactive'>Previous</li><li p='1' style='color:#fff;background-color:#006699;' class='active'>1</li><li p='2' class='active'>2</li><li p='2' class='active'>Next</li>
This is what I get when I press search button now:
This is a bit long, the first part of the code should be relevant to the problem. Here is the code for:
search_videos.php :
<?php
if($_POST['page'])
{
$page = $_POST['page'];
$cur_page = $page;
$page -= 1;
$per_page = 5;
$previous_btn = true;
$next_btn = true;
$start = $page * $per_page;
include"core/database/connect.php";
// Get the input of the selected video
$input = $_POST['input'];
//$input = 'video';
echo $input;
echo $page;
echo $start;
echo $per_page;
// protect against sql injection and ignore multiple spaces in the input
$keywords = preg_split('#\s+#', mysql_real_escape_string($input));
// query the database by user input title
$by_title = "LOWER(`V_TITLE`) LIKE '%" . implode("%' OR `V_TITLE` Like '%", $keywords) . "%'";
$query_pag_data = "SELECT * from upload WHERE $by_title LIMIT $start, $per_page";
$result_pag_data = mysql_query($query_pag_data) or die('MySql Error' . mysql_error());
$msg = "";
while ($row = mysql_fetch_array($result_pag_data)) {
$msg .= '<img src="images/link_pic.png" alt="error" width="164" height="128">' . '<li>Title: <b>' . $row['V_TITLE'] . '</b></br> Uploaded by: ' . $row['V_USERNAME'] . '</br>Date added: ' . $row['V_DATE'] . '</li></br></br>';
}
$msg = "<div class='data' style='margin-bottom:10px'><ul>" . $msg . "</ul></div>"; // Content for Data
/* --------------------------------------------- */
$query_pag_num = "SELECT COUNT(*) AS count FROM upload";
$result_pag_num = mysql_query($query_pag_num);
$row = mysql_fetch_array($result_pag_num);
$count = $row['count'];
$no_of_paginations = ceil($count / $per_page);
/* ---------------Calculating the starting and endign values for the loop----------------------------------- */
if ($cur_page >= 7) {
$start_loop = $cur_page - 3;
if ($no_of_paginations > $cur_page + 3)
$end_loop = $cur_page + 3;
else if ($cur_page <= $no_of_paginations && $cur_page > $no_of_paginations - 6) {
$start_loop = $no_of_paginations - 6;
$end_loop = $no_of_paginations;
} else {
$end_loop = $no_of_paginations;
}
} else {
$start_loop = 1;
if ($no_of_paginations > 7)
$end_loop = 7;
else
$end_loop = $no_of_paginations;
}
/* ----------------------------------------------------------------------------------------------------------- */
$msg .= "<div class='pagination'><ul>";
// FOR ENABLING THE PREVIOUS BUTTON
if ($previous_btn && $cur_page > 1) {
$pre = $cur_page - 1;
$msg .= "<li p='$pre' class='active'>Previous</li>";
} else if ($previous_btn) {
$msg .= "<li class='inactive'>Previous</li>";
}
for ($i = $start_loop; $i <= $end_loop; $i++) {
if ($cur_page == $i)
$msg .= "<li p='$i' style='color:#fff;background-color:#006699;' class='active'>{$i}</li>";
else
$msg .= "<li p='$i' class='active'>{$i}</li>";
}
// TO ENABLE THE NEXT BUTTON
if ($next_btn && $cur_page < $no_of_paginations) {
$nex = $cur_page + 1;
$msg .= "<li p='$nex' class='active'>Next</li>";
} else if ($next_btn) {
$msg .= "<li class='inactive'>Next</li>";
}
echo $msg;
// de-allocate memory that was used to store the query results returned by mysql_query(), improve performance
mysql_free_result($query_pag_data);
}

The problem was with the javascript. The pagination is given by the ajax response and it seems that in some cases (or all; I didn't study the issue that deep) javascript events can't be fired after the elements to which they were bound are dynamically added to the page. The very easy to use live() method is deprecated since jQuery 1.7. What worked now was:
$('#container').on('click','.pagination li.active', function(){//... the ajax request here}
The difference between live() and on() is that the element to which you would normally bind the event is the second argument of the on() method and the on() method is called on the parent of the element.

Related

Pagination in search php

I have a search form and i want to put a pagination, but when i press the next button or second page on the search using pagination , all the results get messed up, and there is no data being fetched from the query. I don't know where the exact problem could be, but this is my search code:
include ('paginate.php'); //include of paginat page
$per_page = 5;
$find = $_POST['find'];
$find = strtoupper($find);
$find = strip_tags($find);
$find = trim ($find); // number of results to show per page
$result = mysql_query("SELECT * FROM projects WHERE p_name LIKE '%$find%'");
$total_results = mysql_num_rows($result);
$total_pages = ceil($total_results / $per_page);//total pages we going to have
//------------if page is setcheck-----------------//
if (isset($_GET['page'])) {
$show_page = $_GET['page']; //it will telles the current page
if ($show_page > 0 && $show_page <= $total_pages) {
$start = ($show_page - 1) * $per_page;
$end = $start + $per_page;
} else {
// error - show first set of results
$start = 1;
$end = $per_page;
}
} else {
// if page isn't set, show first set of results
$start = 0;
$end = $per_page;
$show_page=1;
}
// display pagination
if(isset($_GET['page'])){
$page = intval($_GET['page']);
}else{
$page =1;
}
$tpages=$total_pages;
if ($page <= 0)
$page = 1;
?>
<?php
$reload = $_SERVER['PHP_SELF'] . "?tpages=" . $tpages;
echo '<div class="pagination"><ul>';
if ($total_pages > 1) {
echo paginate($reload, $show_page, $total_pages);
}
echo "</ul></div>";
// display data in table
echo "<table class='table table-bordered'>";
echo "<thead><tr><th>Project</th> <th>Country</th> <th>Active</th>
</tr></thead>";
for ($i = $start; $i < $end; $i++) {
// make sure that PHP doesn't try to show results that don't exist
if ($i == $total_results) {
break;
}
?><form name="frmactive" method="POST" action="">
<input type="hidden" name="id" value="<?php echo mysql_result($result, $i, 'p_id');?>" />
<?php
// echo out the contents of each row into a table
echo '<tr><td>' . mysql_result($result, $i, 'p_name') . '</td>';
echo '<td>' . mysql_result($result, $i, 'p_country') . '</td>';
if (mysql_result($result, $i, 'p_isActive')=='1'){
echo '<td>Active</td>';
echo '<td align="center">Edit</td>';
}
else{
echo'<td>Inactive</td> ';
echo '<td align="center">Edit</td>';
echo "</tr>";
}
// close table>
}
echo "</table>";
// pagination
?>
and this is the paginate.php
function paginate($reload, $page, $tpages) {
$adjacents = 2;
$prevlabel = "‹ Prev";
$nextlabel = "Next ›";
$out = "";
// previous
if ($page == 1) {
$out.= "<span>" . $prevlabel . "</span>\n";
} elseif ($page == 2) {
$out.= "<li>" . $prevlabel . "\n</li>";
} else {
$out.= "<li>" . $prevlabel . "\n</li>";
}
$pmin = ($page > $adjacents) ? ($page - $adjacents) : 1;
$pmax = ($page < ($tpages - $adjacents)) ? ($page + $adjacents) : $tpages;
for ($i = $pmin; $i <= $pmax; $i++) {
if ($i == $page) {
$out.= "<li class=\"active\"><a href=''>" . $i . "</a></li>\n";
} elseif ($i == 1) {
$out.= "<li>" . $i . "\n</li>";
} else {
$out.= "<li>" . $i . "\n</li>";
}
}
if ($page < ($tpages - $adjacents)) {
$out.= "<a style='font-size:11px' href=\"" . $reload . "&page=" . $tpages . "\">" . $tpages . "</a>\n";
}
// next
if ($page < $tpages) {
$out.= "<li>" . $nextlabel . "\n</li>";
} else {
$out.= "<span style='font-size:11px'>" . $nextlabel . "</span>\n";
}
$out.= "";
return $out;
}
Could you please point out where the bug is taking place ? Thank you for your time
Try this (pay attention to the comments please) :
<?php
/*
Assuming that your search form has a POST method set to it,
be sure to do a redirect to this page and send the find parameter gotten
from the posted form urlencoded
ie path_to_my_file?find='.urlencode(trim($_POST['find']))
*/
include ('paginate.php'); //include of paginat page
$per_page = 5;
$find = strip_tags(strtoupper(trim(urldecode($_GET['find']))));
$page = intval($_GET['page']);
$result_total = mysql_query("SELECT COUNT(*) AS total FROM projects WHERE p_name LIKE '%".$find."%'");
$tmp_total = mysql_fetch_assoc($results_total);
$totalpages = ceil($tmp_total['total'] / $per_page);
if ($totalpages != 0 && $page > $totalpages) {
$page = $totalpages;
} else if ($page < 1) {
$page = 1;
}
$offset = ($page - 1) * $per_page;
$result = mysql_query("SELECT * FROM projects WHERE p_name LIKE '%".$find."%' LIMIT ".$offset.", ".$per_page);
$show_page = 1;
//You need to pass the phrase you are searching for in every link in order for the pagination to work (or user Sessions to save the keyword somewhere if you don't want it in the link)
$reload = $reload = 'http://localhost/Personal/Stackoverflow/2/index.php?find='.urlencode($find);
echo ' <div class="pagination">
<ul>';
if ($totalpages > 1) {
echo paginate($reload, $show_page, $totalpages);
}
echo ' </ul>
</div>';
// display data in table
if(mysql_num_rows($result) > 0) {
echo ' <table class="table table-bordered">
<thead>
<tr>
<th>Project</th>
<th>Country</th>
<th>Active</th>
</tr>
</thead>';
while($row = mysql_fetch_assoc($result)) {
echo ' <tr>
<td>'.$row['p_name'].'</td>
<td>'.$row['p_country'].'</td>
<td>'.((intval($row['p_isActive']) == 1) ? 'Active' : 'Inactive').'</td>
<td align="center">
Edit
</td>
</tr>';
}
echo ' </table>';
}
?>

MySQL/PHP Search Engine - Without Refresh? Examples and documents provided

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).

php jquery pagination expanding without moving to the next page

Im working on a codeigniter project which takes results and adds it to the page with pagination.
The problem that im having is,
the page shows all the page numbers but the first page always seems empty. When i move to the second page it shows the first page results along with the second page results. Even if i move to the first page again its empty.
when i move further, all the results seems to be stacked rather than paginating.
so first page 0 results. the second page shows 30, 3rd page shows 45 results.
below is my script
<script type="text/javascript">
$(document).ready(function(){
function loading_show(){
$('#loading').html("<img src='<?php echo $url?>images/loading.gif'/>").fadeIn('fast');
}
function loading_hide(){
$('#loading').fadeOut('fast');
}
function loadData(page){
loading_show();
$.ajax
({
type: "POST",
url: "<?php echo base_url()?>index.php/controls/ajaxload",
data: "page="+page,
success: function(msg)
{
$("#container").ajaxComplete(function(event, request, settings)
{
loading_hide();
$("#container").html(msg);
});
}
});
}
loadData(1);
$('#container .pagination li.active').live('click',function(){
var page = $(this).attr('p');
loadData(page);
});
$('#go_btn').live('click',function(){
var page = parseInt($('.goto').val());
var no_of_pages = parseInt($('.total').attr('a'));
if(page != 0 && page <= no_of_pages){
loadData(page);
}else{
alert('Enter Number '+no_of_pages);
$('.goto').val("").focus();
return false;
}
});
});
</script>
php code
function ajaxload()
{
if($_POST['page'])
{
$page = $_POST['page'];
$cur_page = $page;
$page -= 1;
$per_page = 15;
$previous_btn = true;
$next_btn = true;
$first_btn = true;
$last_btn = true;
$start = $page * $per_page;
$city ='London';
$this->load->model('control_model');
$query_pag_datas = $this->control_model->data_for_pagination($start, $per_page,$city);
$msg = "";
foreach ($query_pag_datas as $single):
$htmlmsg = htmlentities($single['Description']);
$msg .= "<li><b>" . $single['offID'] . "</b> " . $htmlmsg . "</li>";
endforeach;
$msg = "<div class='data'><ul>" . $msg . "</ul></div>";
$count = $this->control_model->count_pages($city);
$no_of_paginations = ceil($count / $per_page);
if ($cur_page >= 7) {
$start_loop = $cur_page - 3;
if ($no_of_paginations > $cur_page + 3)
$end_loop = $cur_page + 3;
else if ($cur_page <= $no_of_paginations && $cur_page > $no_of_paginations - 6) {
$start_loop = $no_of_paginations - 6;
$end_loop = $no_of_paginations;
} else {
$end_loop = $no_of_paginations;
}
} else {
$start_loop = 1;
if ($no_of_paginations > 7)
$end_loop = 7;
else
$end_loop = $no_of_paginations;
}
$msg .= "<div class='pagination'><ul>";
if ($first_btn && $cur_page > 1) {
$msg .= "<li p='1' class='active'>First</li>";
} else if ($first_btn) {
$msg .= "<li p='1' class='inactive'>First</li>";
}
if ($previous_btn && $cur_page > 1) {
$pre = $cur_page - 1;
$msg .= "<li p='$pre' class='active'>Previous</li>";
} else if ($previous_btn) {
$msg .= "<li class='inactive'>Previous</li>";
}
for ($i = $start_loop; $i <= $end_loop; $i++) {
if ($cur_page == $i)
$msg .= "<li p='$i' style='color:#fff;background-color:#006699;' class='active'>{$i}</li>";
else
$msg .= "<li p='$i' class='active'>{$i}</li>";
}
if ($next_btn && $cur_page < $no_of_paginations) {
$nex = $cur_page + 1;
$msg .= "<li p='$nex' class='active'>Next</li>";
} else if ($next_btn) {
$msg .= "<li class='inactive'>Next</li>";
}
if ($last_btn && $cur_page < $no_of_paginations) {
$msg .= "<li p='$no_of_paginations' class='active'>Last</li>";
} else if ($last_btn) {
$msg .= "<li p='$no_of_paginations' class='inactive'>Last</li>";
}
$goto = "<input type='text' class='goto' size='1' style='margin-top:-1px;margin-left:60px;'/><input type='button' id='go_btn' class='go_button' value='Go'/>";
$total_string = "<span class='total' a='$no_of_paginations'>Page <b>" . $cur_page . "</b> of <b>$no_of_paginations</b></span>";
$msg = $msg . "</ul>" . $goto . $total_string . "</div>";
echo $msg;
}
}
any help will be appreciated.
So if the page you are posting is 1, this is what you get:
Page 1:
$page = $_POST['page'];//let's say we're posting page 1, so $page === 1
...
$page -= 1;//so now, page === 0
...
$start = $page * $per_page;//which, since math, will be 0
...
$query_pag_datas = $this->control_model->data_for_pagination($start, $per_page,$city);
// you just called data_for_pagination(0, 15, 'London')
Since we can't see the data_for_pagination method, I'm going to assume that this first parameter is the number of results you are requesting. This makes sense because as the page number increases, the number of results will increase:
Page 2:
$page = $_POST['page'];//let's say we're posting page 2, so $page === 2
...
$page -= 1;//so now, page === 1
...
$start = $page * $per_page;//which, since math, will be 15
...
$query_pag_datas = $this->control_model->data_for_pagination($start, $per_page,$city);
// you just called data_for_pagination(15, 15, 'London')
Page 3:
$page = $_POST['page'];//let's say we're posting page 3, so $page === 3
...
$page -= 1;//so now, page === 2
...
$start = $page * $per_page;//which, since math, will be 30
...
$query_pag_datas = $this->control_model->data_for_pagination($start, $per_page,$city);
// you just called data_for_pagination(30, 15, 'London')
Hope that helps.
change
$page -= 1;
to
$page = ($page > 0 ) ? $page -1 : 0 ;
in the first click page is 0
so
0-1 => -1
-1 * 15 => -15 ;
your first offset is -15 !

PHP/MySQL - Pagination with variety of ORDER BY clauses

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&currentpage=1'><< First</a></span>";
$prevpage = $currentpage - 1;
echo "<span class='previous'><a href='{$_SERVER['PHP_SELF']}?sortby=$sortby&groupid=$genderid&currentpage=$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&currentpage=$x'>$x</a> ";
}
}
}
echo '</span>';
if ($currentpage != $totalpages) {
$nextpage = $currentpage + 1;
echo "<span class='next'><a href='{$_SERVER['PHP_SELF']}?sortby=$sortby&groupid=$genderid&currentpage=$nextpage'>Next ></a></span>";
echo "<span class='last'><a href='{$_SERVER['PHP_SELF']}?sortby=$sortby&groupid=$genderid&currentpage=$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).

Having some trouble in my pagation code(PHP)

My table is posting and in that table, it shows all the posting people put in.
I am trying to make page navigation links at the bottom of the posts.
the function generateenter code here_page_links does all the work.
The code seem to be only showing the "<-" and "->" and not the link numbers. I think the function is only reading the $_GET['posting'] ==1.
(this code is from the Oreilly PHP/MySQL book. I am using it as practice)
function generate_page_links($cur_page, $num_pages) {
$page_links = '';
// If this page is not the first page, generate the "previous" link
if ($cur_page > 1) { //cur_page is just a number that is gotten from the url.
$page_links .= '<-- ';
}
else {
$page_links .= '<- ';
}
// Loop through the pages generating the page number links
for ($i = 1; $i <= $num_pages; $i++) {
if ($cur_page == $i) {
$page_links .= ' ' . $i;
}
else {
$page_links .= ' ' . $i . '';
}
}
// If this page is not the last page, generate the "next" link
if ($cur_page < $num_pages) {
$page_links .= ' ->';
}
if ($cur_page == $num_pages){ //the last page
$page_links .= ' ->';
}
return $page_links; //need to return this variable in the function
}
// Calculate pagination information
$cur_page = isset($_GET['page']) ? $_GET['page'] : 1;
$results_per_page = 3; // number of results per page
$skip = (($cur_page - 1) * $results_per_page);
$query = "SELECT * FROM posting ORDER BY date_added DESC";
$data = mysqli_query($dbc, $query);
$total = mysqli_num_rows($data);
$num_pages = ceil($total / $results_per_page);
//Query again to get just the subset of results
$query = $query . " LIMIT $skip, $results_per_page";
$result = mysqli_query($dbc, $query);
echo '<table>';
echo '<tr><td><b>Title</b></td><td><b>Date Posted</b></td></tr>';
while ($row = mysqli_fetch_array($result)) {
echo '<tr><td><a href="ad.php?
posting_id='.$row['posting_id'].'
">'.$row['title'].'</a></td>';
echo '<td>'.$row['date_added'].'</td>';
//echo '<td>'.$row['name'].'</td></tr>';
}
echo '</table>';
// Generate navigational page links if we have more than one page
if ($num_pages > 1) {
echo generate_page_links($user_search, $sort, $cur_page, $num_pages);
}
Well you have some problems here to start with:
You call the function with 4 variables
echo generate_page_links($user_search, $sort, $cur_page, $num_pages);
But the function only accepts two
function generate_page_links($cur_page, $num_pages)
If that's the code you're using, then it's probably going to crash because those variables are undefined.
Try deleting "$user_search, $sort," and see if that fixes it?

Categories