I'm following this tutorial here: http://brenelz.com/blog/implementing-paging-using-php-and-jquery/
Here is what I have: http://eataustineat.com/testingfolder/
I've encountered a strange problem when the page initially loads. All that shows is the Next and previous link when the first set of results and the next link should be present. Once you click next or previous, then the the results show. But after that, the next and previous links no longer work. The numbered links will work, however.
I've included the jquery below because i believe it to be the source of the problem:
function pager(dir) {
var page = parseInt($("#offset").val());
var max = parseInt($("#maxpage").val());
var no = isNaN(parseInt(dir));
if (!no) {
page = parseInt(dir);
}
if (dir == "next") page = page + 1;
else if (dir == "first") page = 0;
else page = page - 1;
if (page == 0) {
$("#prev").remove();
} else $("#prev").add();
if (page == max - 1) {
$("#next").remove();
} else $("#next").add();
$.post("page.php", {
val: page
}, function (result) {
$("#table-div").html(result);
});
}
Thanks for reading.
The problem is the var page = parseInt($("#offset").val()); line in your pager function. There is no element with an id attribute of offset. The result of parseInt is NaN and when you try to add a number to it, it doesn't add since NaN isn't a number.
You most likely forgot to add the element that contains the offset in your form somewhere. It looks like that's covered in Step 9 of your tutorial.
Is there createTable($link,$sql_offset,$limit); in your php code, Step 8
Related
After User Clicks Sumbit Button Data passes through one half of the path to images and then the code below links it to the second half. I want to know how I can display all this without Page Reload? I know it might be done with AJAX but I have no idea on how to do so. So please can someone help?
<?php
$albumnamepath = $_POST['field'];
echo $albumnamepath;
$display = "SELECT * FROM paths WHERE user_id = '$session_user_id' AND album_name = '$albumnamepath'";
$result = mysql_query($display);
echo "<table>";
$i = 0;
while ( $row = mysql_fetch_array($result) ) {
if ($i % 4 == 0) { //3 == 0.
echo '<tr>';
}
echo "<td>".'
<ul class="img-list">
<li><div class="picbox"><img src="'.$albumnamepath.$row['thumbnail'].'"><span class="text-content"><span>'.$row['caption'].'</span></span>'."</li>
</ul>
</td>";
//echo '<a href="'.$albumnamepath.$row['location'].'" class="swipebox" title="'.$row['caption'].'"><img src="'.$albumnamepath.$row['thumbnail'].'">';
if ($i % 4 == 3) { //3 == 2.
echo '</tr>';
}
$i++;
}
//Here is a check in case there is not a multiple of 3 images in a row.
if ($i % 4 != 0) { //4 != 0.
echo '</tr>';
}
echo "</table>";
?>
Thank you.
I don't think Ajax would help you very much, since you'll be using ajax to get, essentially, the entire page. Ajax is usually used if you want to change a part of the page, and the data either has to come from the server real-time (i.e. after the page is loaded), or is expensive to calculate or deliver in full (e.g. a very long, or infinite list, and if most users only use a small amount). Otherwise, it's more efficient to send all the data in one go, and then manipulate it in the browser.
I would suggest the following approach: divide the table rows into groups of table rows; e.g. 5 rows (chosen arbitrarily). Change the block of code where you echo '' to:
if ($i % 4 == 0) { //3 == 0.
$block=ceil($i/(4*5));
echo '<tr class="block_$block">';
}
This means each block of 5 rows (by 4 across) will be a different class - "block_1", "block_2" and so forth.
Then, you can hide and display blocks using Javascript. To hide a block, use the following javascript code:
var trToHide = document.getElementsByClassName("block_1");
for(var i = 0; i < trToHide.length; i++) {
trToHide[i].style.display="none";
}
To unhide a block:
var trToHide = document.getElementsByClassName("block_3");
for(var i = 0; i < trToHide.length; i++) {
trToHide[i].style.display="block";
}
Obviously, you will want to use variables to keep track of which block is displayed; then you can have a "Next" and "Back" button, which hides the current block, adds/subtracts one, then displays the (new) current block. You will also want to have all blocks except the first one hidden at the start. Left as an exercise to the reader.
Answer:
You have to use ajax request.
You use form to set filters? Then you can use .ajaxSumbit (but you need jQuery Form Plugin for it).
Also, you can add form submit handler, where you will prevent form default submit action and send ajax request instead of it. Look this example:
File getImages.php:
// in this file you will do same actions as you do now to output table with images
Note, that getImages.php must contain only table with results or message, that there are no results.
File with form, where you set filters:
// some html with forms etc
<form id='myForm'>
// some inputs etc
</form>
<div id='results'></div>
And javascript:
$("#myForm").submit(function(e) { // use e parameter for preventDefault();
$.ajax({
type: "POST",
url: "path/to/getImages.php",
data: $("#myForm").serialize(), // serializes the form's elements.
success: function(data)
{
$("#results").html(data);
}
});
return false; // <-- deny sumitting from and reloading page
//e.preventDefault(); // <-- this do same as `return false;` <-- deny sumitting from and reloading page
});
Explanation:
Browser load page with form, where you can set filters. User sets filters and pressing button submit. Browser will send ajax request to file getImages.php with some parameters (filters, user set filter before sending the form). This script generates some output with table, with img tags etc and return it. Browser receives this output and puts it to element with id #results:
<div id='results'></div>
^
------------------^
Data, generated by script getImages.php will be inserted here.
So, filtered images will be received and shown without page reload :)
Is it what you need?
Hope this will help you.
I know this question has been answered multiple times but I haven't been able to find one specifically to solve my problem.
I'm making a website where a user can sell their eBay items, using the eBay API (which is a bit of a pain!). My problem is at the results' pagination: I need a way of updating a $_SESSION page number variable so that the page reloads and displays a different page of results. I'm doing this with AJAX, and it's my first time using it.
The process is the following:
1)User clicks on one of the pagination links on the bottom of the page (like what's at the bottom of your Google results), which I made into a form with a hidden field storing the next page number that updates accordingly when the user clicks.
2)Use AJAX to update said $_SESSION variable on an external page (without refreshing!)
3)Reload the page and display the appropriate page of results.
The problem seems to be between steps #2 and 3. The bits of code I use:
Set $_SESSION variable
<?php
session_start();
if(!isset($_SESSION['pageNumber']))
{
$_SESSION['pageNumber'] = "1";
echo("Session value NOT set, pageNumber = " . $_SESSION['pageNumber']);
}
else
{
echo("Session value SET, pageNumber = " . $_SESSION['pageNumber']);
}
?>
Pagination
<form action="">
<div id="pagination" style="text-align:center; <?php if($totalPages == 1) echo('display:none;');?>">
<?php
global $totalPages;
if(intval($_SESSION['pageNumber']) != 1)
{
print("Previous Page");
}
for($i = 1; $i <= $totalPages; $i++)
{
print("$i");
print(" ");
}
if(intval($_SESSION['pageNumber']) != $totalPages)
{
print("Next Page");
}
?>
</div>
<input type="hidden" name="nextPageNumber" id="nextPageNumber" value="<?php echo($_SESSION['pageNumber']);?>">
</form>
Update Hidden Field and $_SESSION Value
function updatePageNumber(newNumber)
{
//Update hidden field
if(newNumber == -1)
{
var num = document.getElementById('nextPageNumber').value;
num--;
document.getElementById('nextPageNumber').value = num;
}
else if(newNumber == 0)
{
var num = document.getElementById('nextPageNumber').value;
num++;
document.getElementById('nextPageNumber').value = num;
}
else
{
document.getElementById('nextPageNumber').value = newNumber;
}
//Update $_SESSION value with AJAX
var dataString = 'nextPageNumber='+ document.getElementById('nextPageNumber').value;
$.ajax(
{
url: "scripts/updatePageNumber.php",
type: "POST",
data: dataString,
dataType: "text",
success: function(text)
{
alert("Done! Response: " + text);
}
});
And the PHP file
<?php
if (isset($_POST['nextPageNumber']))
{
session_start();
die("Made it this far!");
$nextPageNumber = $_POST['nextPageNumber'];
$_SESSION['pageNumber'] = $nextPageNumber;
echo $nextPageNumber;
}
?>
Note: I don't get to the PHP file's die() method, nor the alert with the AJAX's success (by the way, is that how to properly get the response text?)
I'd greatly appreciate any help at all, I've been stuck at this for quite a long time now!
Your ajax call doesnt have nextPageNumber in its data, so it isn't seen by your PHP script (not in $_POST array) your test for it fails.
(As a general comment, your question involves too many working parts that makes it not a good fit for a site like this, devoted to helping others with similar problems. Next time please isolate the very part of the code that is causing the problem. This is likely why you have no other answers yet - people are sick of getting downvoted when trying to help solve something so comprehensive.)
I recently came upon a site that has done exactly what I want as far as pagination goes. I have the same basic setup as the site I just found.
I would like to have prev and next links to navigate through my portfolio. Each project would be in a separate file (1.php, 2.php, 3.php, etc.) For example, if I am on the 1.php page and I click "next project" it will take me to 2.php.
The site I am referencing to accomplishes this with javascript. I don't think it's jQuery:
function nextPg(step) {
var str = window.location.href;
if(pNum = str.match(/(\d+)\.php/i)){
pNum = pNum[1] * 1 + step+'';
if ((pNum<1) || (pNum > 20)) { pNum = 1; }
pNum = "".substr(0, 4-pNum.length)+pNum;
window.location = str.replace(/\d+\.php/i, pNum+'.php');
}
}
And then the HTML:
Next Project
I can't really decipher the code above, but I assume the script detects what page you are on and the injects a number into the next page link that is one higher than the current page.
I suppose I could copy this code but it seems like it's not the best solution. Is there a way to do this with php(for people with javascript turned off)? And if not, can this script be converted for use with jQuery?
Also, if it can be done with php, can it be done without dirty URLs?
For example, http://www.example.com/index.php?next=31
I would like to retain link-ability.
I have searched on stackoverflow on this topic. There are many questions about pagination within a page, but none about navigating to another page that I could find.
From your question you know how many pages there are going to be. From this I mean that the content for the pages themselves are hardcoded, and not dynamically loaded from a database.
If this is the approach you're going to take you can take the same course in your javascript: set an array up with the filenames that you will be requesting, and then attach event handlers to your prev/next buttons to cycle through the array. You will also need to keep track of the 'current' page, and check that incrementing/decrementing the current page will not take you out of the bounds of your page array.
My solution below does the loading of the next page via AJAX, and does not change the actual location of the browser. This seems like a better approach to me, but your situation may be different. If so, you can just replace the related AJAX calls with window.location = pages[curPage] statements.
jQuery: (untested)
$(function() {
var pages = [
'1.php',
'2.php',
'3.php'
];
var curPage = 0;
$('.next').bind('click', function() {
curPage++;
if(curPage > pages.length)
curPage = 0;
$.ajax({
url: pages[curPage],
success: function(html) {
$('#pageContentContainer').html(html);
}
});
});
$('.prev').bind('click', function() {
curPage--;
if(curPage < 0)
curPage = (pages.length -1);
$.ajax({
url: pages[curPage],
success: function(html) {
$('#pageContentContainer').html(html);
}
});
});
});
HTML:
<div id = "pageContentContainer">
This is the default content to display upon page load.
</div>
<a class = "prev">Previous</a>
<a class = "next">Next</a>
To migrate this solution to one that does not have the pages themselves hardcoded but instead loaded from an external database, you could simply write a PHP script that outputs a JSON encoded array of the pages, and then call that script via AJAX and parse the JSON to replace the pages array above.
var pages = [];
$.ajax({
url: '/ajax/pages.php',
success: function(json) {
pages = JSON.parse(json);
}
});
You can do this without ever effecting the structure of the URL.
Create a function too control the page flow, with an ajax call
function changePage(page){
$.ajax({
type: 'POST',
url: 'myPaginationFile.php',
data: 'page='+page,
success: function(data){
//work with the returned data.
}
});
}
This function MUST be created as a Global function.
Now we call the function on page load so we always land at the first page initially.
changePage('1');
Then we need to create a Pagination File to handle our requests, and output what we need.
<?php
//include whatever you need here. We'll use MySQL for this example
$page = $_REQUEST['page'];
if($page){
$q = $("SELECT * FROM my_table");
$cur_page = $page; // what page are we on
$per_page = 15; //how many results do we want to show per page?
$results = mysql_query($q) or die("MySQL Error:" .mysql_error()); //query
$num_rows = mysql_num_rows($result); // how many rows are returned
$prev_page = $page-1 // previous page is this page, minus 1 page.
$next_page = $page+1 //next page is this page, plus 1 page.
$page_start = (($per_page * $page)-$per_page); //where does our page index start
if($num_rows<=$per_page){
$num_pages = 1;
//we checked to see if the rows we received were less than 15.
//if true, then we only have 1 page.
}else if(($num_rows % $per_page)==0){
$num_pages = ($num_rows/$per_page);
}else{
$num_pages = ($num_rows/$per_page)+1;
$num_pages = (int)$num_pages;
}
$q. = "order by myColumn ASC LIMIT $page_start, $per_page";
//add our pagination, order by our column, sort it by ascending
$result = mysql_query($q) or die ("MySQL Error: ".mysql_error());
while($row = mysql_fetch_array($result){
echo $row[0].','.$row[1].','.$row[2];
if($prev_page){
echo ' Previous ';
for(i=1;$i<=$num_pages;$i++){
if($1 != $page){
echo "<a href=\"JavaScript:changePage('".$i."');\";> ".$i."</a>";
}else{
echo '<a class="current_page"><b>'.$i.'</a>';
}
}
if($page != $num_pages){
echo "<a class='next_link' href='#' id='next-".$next_page."'> Next </a>';
}
}
}
}
I choose to explicitly define the next and previous functions; so here we go with jQuery!
$(".prev_link").live('click', function(e){
e.preventDefault();//not modifying URL's here.
var page = $(this).attr("id");
var page = page.replace(/prev-/g, '');
changePage(page);
});
$(".next_link").live('click', function(e){
e.preventDefault(); // not modifying URL's here
var page = $(this).attr("id");
var page = page.replace(/next-/g, '');
changePage(page);
});
Then finally, we go back to our changePage function that we built initially and we set a target for our data to go to, preferably a DIV already existing within the DOM.
...
success: function(data){
$("#paginationDiv").html(data);
}
I hope this gives you at least some insight into how I'd perform pagination with ajax and php without modifying the URL bar.
Good luck!
i'm using $.get() to get some elements from a php script and then show the results by "writing" them into a div. This is done periodically, as well as when the div is clicked or when the page reloads. Here's the code:
function fetchnew(){
var status = $J.cookie("status_on");
if (status == 'on'){
//fetch new items
//results from new-items.php have this format:
//<p>Item1</p><p>Item2</p>...
$J.get(modulebaselink+'new-items.php', '', function(newitems){
$J('#content').html(newitems);
updatestatus();
});
}
fetchnew_timeout = setTimeout('fetchnew();', refresh_rate);
}//end fetchnew()
function updatestatus(){
var status = $J.cookie("status_on");
if (status == 'on'){
//Show number of loaded items
var totalItems=$J('#content p').length;
$J('#status').html("Items ("+totalItems+")");
}
}
My problem is that the #status contents display with some delay after page reload. When the page loads i get 'Items(0)' for about ~1 sec, and then 0 changes to the real value. Is there any way to void the 'Items(0)' before displaying the real value? Or at least, cache the previous value and display 'Items(old_value)' instead of 'Items(0)' before the 'Items(new_value)' appears. I tried cookies to do the last one, but 'Items(0)' was there again...
Sounds like a reasonable usecase for the localStorage. Extend updatestatus() like this:
// this should be called at some entry point of your script
var ls_available = 'localStorage' in window;
if(ls_available && localStorage.getItem('totalItems'))
$J('#status').html("Items ("+localStorage.getItem('totalItems')+")");
function updatestatus(){
var status = $J.cookie("status_on");
if (chat_status == 'on'){
var totalItems=$J('#content p').length;
$J('#status').html("Items ("+totalItems+")");
if(ls_available) localStorage.setItem('totalItems', totalItems);
}
}
If your page (the one where fetchnew() is called) is rendered in PHP, call the same function that the Ajax file (new-items.php) calls. That way, your content is there immediately.
I'm creating a online training 'powerpoint' like series of pages. It will be pretty straight forward and have the pages set out as such:
page1.php
page2.php
page3.php
...
page20.php
I'll be going old school and use an iframe to hide the address bar as people shouldn't be able to catch onto the naming convention and skip ahead. (Its not too serious, so I want to keep it simple).
What I want to do is based on the current page that they are on, say for example page5.php create links to page4.php and page6.html. Obviously without having to code each page manually.
It would be ideal if ths were a javascript function as I dont want the address to show up in the browsers info bar but I'm open to php tricks as well.
Any ideas how to do this?
Use window.location. You can put it in a function like so:
<script type='javascript'>
function goto(url) { window.location=url; }
</script>
<a href='#' onclick='goto("page3.php"); return false;'>Previous</a>
<a href='#' onclick='goto("page5.php"); return false;'>Next</a>
You could also go so far as to use a session variable to hide it, that way you could just do something like this (I hope my PHP skills are still good):
<?php
// At Beginning of first script
start_session();
$MAX_PAGE = 20; // Set this to the highest page number
if(!isset($_SESSION['curpage'])) {
$_SESSION['curpage'] = 1;
} else {
// __EDIT: Added page max and mins.
if($_GET['go'] == 'prev' && $_SESSION['curpage'] > 1) {
$_SESSION['curpage']--;
} else if($_GET['go'] == 'next' && $_SESSION['curpage'] < $MAX_PAGE) {
$_SESSION['curpage']++;
}
}
?>
And then put this in the page where you need it.
<?php
include("page$_SESSION[curpage].php");
if($_SESSION['curpage'] > 1) {
echo "<a href='page.php?go=prev' rel='prev'>Previous</a>";
}
if($_SESSION['curpage'] < $MAX_PAGE) {
echo "<a href='page.php?go=next' rel='next'>Next</a>";
}
?>
Note that Web Crawlers won't be able to do much with this though, when it returns a different page each time.
A little expansion on Pikrass's function, to deal with first/last scenarios:
function goto(url) { window.location=url; }
var curPage = parseInt(location.href.replace(/page([0-9]+)\.php/, ''))
if (curPage <= 1) {
// First page, no 'back' link
document.write('Back');
} else {
var backPage = curPage-1;
document.write("Back");
}
if (curPage >= 9) { // Replace with highest page number
// Last page, no 'next' link
document.write('Next');
} else {
var nextPage = curPage+1;
document.write("Back");
}
URLs are not hidden if you view the source of the page, but they don't show up in the browser's status bar when hovering over the link, as requested.
Edit Updating RegEx with Pikrass' more specific one, to deal with other digits elsewhere in the URL. Thanks Pikrass!
var actuPage = parseInt(location.href.replace(/[^0-9]/, ''))+1;
location.href = 'page'+actuPage+'.php';
That should work if you have no other number in your URLs. If you do, you'll have to change the pattern for replace.
The code is for the next page, change the +1 to -1 for the previous one.
Here is MidnightLightning's version with a better RegExp to get the current page, which works even if you have other numbers in your URLs.
function goto(url) { window.location=url; }
var regPage = /page([0-9]+)\.php/;
var match = regPage.exec(location.href);
var curPage = parseInt(match[1]);
if (curPage <= 1) {
// First page, no 'back' link
document.write('Back');
} else {
var backPage = curPage-1;
document.write("Back");
}
if (curPage >= 9) { // Replace with highest page number
// Last page, no 'next' link
document.write('Next');
} else {
var nextPage = curPage+1;
document.write("Back");
}
I love when an answer is built by several guys. :)
If you can, prefer a PHP code, as suggested. It's much more "clean".
Sounds like you want to use query string variables, so page.php?page=1, page.php?page=2, page.php?page=3 and so on
Why dont you use ajax instead of an iframe?
Well, doesnt matter, you tagged the question jquery so i think you can find usefull using another link attribute to 'tell' js where to redirect.
I mean:
$.(document).ready(funciton(){
//i use the live method becose.. you know, maybe in the future
//you will go with ajax ;)
//live method is avbaiable in jquery 1.3!
$("a.navigation").live('click', function(){
window.location = $(this).attr("rel");
});
});
This let your html markup free from many onclick functions in the <a> tags.
So, your markup will then look something like:
Go to page 1
Go to page 2
<!-- .. and so on.. -->
Or, if you still wanna hide real urls, you can do:
Go to page 1
Go to page 2
<!-- .. and so on.. -->
with this js (maybe not embedded into the page source?)
$.(document).ready(funciton(){
$("a.navigation").live('click', function(){
window.location = 'page' + $(this).attr("rel") + '.php';
});
});
But you'll never be able to completely hide the page urls, if youre planning to use js links.
You could hide them using php, and an hashed strings twin, but i dont know if it worth the game.
Other suggested a regexp way to calculate the pages number and pages links; I will go printing the links via PHP: will let you control the global behavior much better (we dont know how many pages you have, and if theyre numbers is database-related, even the information you gave us would make me think that you have all the page[x].php fisically on your server)