Right now I use a pagination system that requires url like
http://mypage.com/index.php?page=1
http://mypage.com/index.php?page=2
http://mypage.com/index.php?page=3
http://mypage.com/index.php?page=4
etc...
So it uses $_GET method to find out what page the user is on.
I decided to switch most of my website to ajax and came over a problem. When I use Ajax to load new content on a page the url stays the same all the time e.g. http://mypage.com/index.php . Therefore pagination system I use is useless.
I was not able to find efficient AJAX pagination systems, (e.g some where lagy, most required user to scrol to the tiop each time he / she clicked on a next page, because they stayed at the bottom of the page when they clicked next page. etc...)
So I decided to ask you lot if anyone has an efficient pagination solution that works with ajax.
Example of what needs to be paginated:
$sql = mysql_query("SELECT * FROM myMembers WHERE username='$username' LIMIT 1") or die (mysql_error("There was an error in connection"));
//Gather profile information
while($row = mysql_fetch_assoc($sql)){
$username = $row["username"];
$id = $row["id"];
$data_display .= '<b>'.Name.'</b> has an id of <span style="color: f0f0f0;">'.$id.'</span>';
}
<!doctype>
<html>
<?php echo "$data_display"; ?> //and I need to paginate this entries
</html>
jQuery that loads new content from different pages into #content div
<script type="text/javascript">
function viewHome(){
$('#woodheader').load("inc/home_top.php", function () {
$(this).hide().fadeIn(700)
});
$('#content').html('<span class="loader">Loading.. <img class="loaderimg" src="images/ajax_loader.gif"/></span>').load("inc/home.php", function () {
$(this).hide().fadeIn(700)
});
}
function viewAbout(){
$('#woodheader').load("inc/about_top.php", function () {
$(this).hide().fadeIn(700)
});
$('#content').html('<span class="loader">Loading.. <img class="loaderimg" src="images/ajax_loader.gif"/></span>').load("inc/about.php", function () {
$(this).hide().fadeIn(700)
});
}
function viewProducts(){
$('#woodheader').load("inc/products_top.php", function () {
$(this).hide().fadeIn(700)
});
$('#content').html('<span class="loader">Loading.. <img class="loaderimg" src="images/ajax_loader.gif"/></span>').load("inc/products.php", function () {
$(this).hide().fadeIn(700)
});
}
</script>
Pagination is not as hard as you can think, you can use jQuery's load() function to load content into an element with the page's content.
So for example you have:
<div id="page-content"></div>
Page 1
Page 1
Page 3
<script>
$.ready(function(){
var currPage = <?=$pageNumber; ?>; // The page number loaded on page refresh
$('#link1,#link2,#link3').onclick(function(){
// Get the first number inside the id
var pageNum = parseInt($(this).attr('id'));
// Don't load the same page
if(currPage == pageNum) return;
// Show loading animation or whatever
// Load the page using ajax
$('#page-content').load('pages.php?page='+pageNum, function(){
// End loading animation
currPage = pageNum;
});
return false; // Important for not scrolling up
});
});
</script>
Regarding the url, you have three options to choose from when a user clicks a page link:
Just load the page with no changing of the url
Use the HTML5 history.pushState(see MDN resource) if supported and with option 3 as fallback for unsupported browsers
Use #page1, #page1 etc. as the href value of the links so that the user knows on what page they are on and parse the value of the url in php:
$uri = explode('#page', $_SERVER['REQUEST_URI']);
$pageNumber = intval($uri[1]);
I would create a index.php that doesn't load any $data_display initially.
Internally in javascript I would keep a variable named $page that would initially equals 1.
After load it would make a ajax call to names.php?page=$page and pass the results to a handler that presents it to the user.
Then on the links to "back" and "next" I would put a javascript function that first sets $page to the previous or next number, then calls names.php?page=$page and pass the results to the same handler.
Related
I have a class which gets a result from the database and the result is being looped through, and the database is being updated regularly but i dont want to keep refreshing the page because of some reasons.
//file class.php
class order {
function getOrders(){
//gets data from database
}
}
//file main.php
$ai = new order();
$orders = $ai->getOrders();
foreach($orders AS $order){
//data displayed in a table
}
I want the table to be automatically updated without page reload.
I know i have to use ajax but i have no idea what to implement that in oop
Use something like this.
$(function () {
setInterval(function () {
$("#liveTable").load("path/to/orderList");
}, 1000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="liveTable"></div>
You need to use javascript and jQuery on your html page so as to reload a portion of the page.
you can add the following in your html page's head:
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
$(document).ready(function()
{
theIntervalHandle = setInterval(fetchNewOrders,3000);
});
function fetchNewOrders()
{
$('#ordersDiv').load('http://your.web.address/class.php');
}
</script>
and that
<div id="ordersDiv"></div>
inside your html file's body where you want the dynamic content to appear.
this assumes that the file that creates the output is called class.php and fetches data each 3 seconds as per second is quite often and can cause problems should your traffic increase beyond a few tens of users...
I have very limited knowledge with scripts so I hope you guys can help me with a simple solution to a small problem that I have...
I'm using the following jquery function to refresh a div with new content when a link is clicked
<script>
$(function() {
$("#myButton").click(function() {
$("#loaddiv").fadeOut('slow').load("reload.php").fadeIn("slow");
});
});
</script>
My problem is, I need to send 2 variables to the reload.php page to use in a mysql query (I have no idea how to accomplish that), also I need to make multiple links work with this function, at the moment I have multiples links with the same id and only the first link works so I guess I must associate different ids to the function in order for this to work, how can I do that?
here's the page where i'm using this: http://www.emulegion.info/teste/games/game.php
You may want to use document ready instead of function on your first line as this will make sure the code is not executed until the full page (and all elements) have loaded.
You can then use the callback functions of the fade and load to perform actions in a timely manner.
additional variables you can add after the .php, these can then be read in your reload.php file as $var1 = $_GET['var1'];
Do make sure to sanitize these though for security.
<script type="text/javascript">
// execute when document is ready
$(document).ready(function() {
// add click handler to your button
$("#myButton").click(function() {
// fade div out
$("#loaddiv").fadeOut('slow',function(){
// load new content
$("#loaddiv").load("reload.php?var1=foo&var2=bar",function(){
// content has finished loading, fade div in.
$("#loaddiv").fadeIn('slow');
}); // end load content
}); // end fade div out
}); // end add click to button
}); // end document ready
</script>
For different variables you could add a HTML5 style variable to your button.
<input type="button" id="myButton" data-var1="foo" data-var2="bar" />
You can retrieve this when the button is clicked:
// add click handler to your button
$("#myButton").click(function() {
// get vars to use
var var1 = $(this).data('var1');
var var2 = $(this).data('var2');
...
load("reload.php?var1="+var1+"&var2="+var2
if you have multiple buttons/links I would use class instead of id "myButton". that way you can apply the function to all buttons with the above script. Just replace "#myButton" for ".myButton"
First, you should use .on('click', function() or .live('click', function() to resolve your one click issue.
You'll want to do something like:
<script>
$(function() {
$("#myButton").on('click', function() {
var a = 'somthing';
var b = 'something_else';
$.post('url.php', {param1: a, param2: b}, function(data) {
//data = url.php response
if(data != '') {
$("#loaddiv").fadeOut('slow').html(data).fadeIn("slow");
}
});
});
});
</script>
Then you can just put var_dump($_POST); in url.php to find out what data is being sent.
Try creating a function that would accept parameters that you want.
Like:
$(document).ready(function(){
$('.link').click(function(){
reload(p1,p2);
});
});
function reload(param1, param2){
$("#loaddiv").fadeOut('slow').load("reload.php?param1="+param1+"¶m2="+param2).fadeIn("slow");
}
But by doing the above code your reload.php should be using $GET. Also you need to use class names for your links instead of id.
<script type="text/javascript">
// execute when document is ready
**$(document).ready(function() {**
**$("#myButton").click(function() {**
**$("#loaddiv").fadeOut('slow',function(){**
**$("#loaddiv").load("reload.php?var1=foo&var2=bar",function(){**
// content has finished loading, fade div in.
$("#loaddiv").fadeIn('slow');
});
});
});
});
</script>
$("#myButton").click(function() {
// get vars to use
var var1 = $(this).data('var1');
var var2 = $(this).data('var2');
Iam loading pages in dynamically with PHP like so:
<div id="content">
<div id="fadein">
<?php
/// load page content
$pages_dir = 'content';
if(!empty($_GET['p'])) {
$pages = scandir($pages_dir, 0);
//delete . and ..
unset($pages[0], $pages[1]);
$p = $_GET['p'];
// only files that are in the array can be loaded
if (in_array($p. '.php', $pages)) {
include($pages_dir. '/'.$p. '.php');
} else {
echo 'Helaas deze pagina bestaat niet';
}
} else {
include($pages_dir. '/index.php');
}
?>
</div>
</div>
If you use the navigation at the top of my site the PHP loads the relevant content.
And i got this script at the bottom of my page to change the background image:
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
// Alternatively you could use:
// (new Image()).src = this;
});
}
// Usage:
preload([
'../public/background/test2/1.jpg',
'../public/background/test2/2.jpg',
'../public/background/test2/3.jpg',
'../public/background/test2/4.jpg',
'../public/background/test2/5.jpg',
'../public/background/test2/6.jpg'
]);
var totalCount = 6;
function changeBackground()
{
var num = Math.ceil( Math.random() * totalCount );
backgroundUrl = '../public/background/test2/'+num+'.jpg';
$('body').css('background-image', 'url(' +backgroundUrl+ ')');
}
changeBackground();
But everytime different content is loaded, the script is executed...
I don't want that. I only want to change the background when the user refreshes the page. Not when different content is loaded when the user is navigating through the site.
As it is now (based on your comment), you are reloading the whole page when you really want to load only new content.
To be able to get the effect that you want, you should use ajax (combining php and javascript) to refresh only a part of your page when you hit a navigation link.
What you could do is (using jQuery for an easy introduction to ajax...):
separate your php script from the html so that you can call it separately and include it in your initial html;
attach an event handler to your navigation links, cancelling the default action (undo the click) and use jQuery's load method to replace your content with the new content (call your php script with the correct parameters).
As the javascript is located in the main html file, it will only execute your background script on the initial page load or page refresh.
If you are trying to manage this through JavaScript alone, then you can create a Cookie with an array of page visits, then on page load you can refer to that array to determine whether a user has visited that page already.
QUESTION: What is the proper way to use .get() in conjunction with .one() (or .live()) so that an external php file is appended only once?
MOST RECENT EDIT:
solution
<script>
$(document).ready(function(){
$('.tree li a').one("click", function() {
var currentAnchor = $('.tree li a').attr('href');
if(!currentAnchor){
var query = "page=1";
}
else
{
var splits = currentAnchor.substring(1).split('&');
//Get the section
var page = splits[0];
delete splits[0];
var query = "page=" + page;
alert ("page=" + page);
}
//Send the petition
$("#loading").show();
$.get("callbacks.php",query, function(data){
$("#content").append(data);
$("#loading").hide();
});
return false;
});
});
</script>
More Specifically:
I'm using Javascript and PHP to load some external PHP pages as sections in my main template.
I'm using a switch and append() so the included files keep appending. I need every file to be able to be appended ONLY ONCE. Here is the scenario as I'd like it to happen
1) downloads link is clicked
2) downloads.php appears
3) errors link is clicked
4) errors.php appears below downloads.php
5) downloads link is clicked again
6) page just scrolls up to top of downloads.php
I need the same functionality as the example on the documentation page of .one() where every div can be clicked only once.
I also looked at Using .one() with .live() jQuery and I especially liked the approach used in the accepted answer.
Iried using boolean flag as suggested below but all it did was limit my consecutive clicks on the same link to one. So if I click one link 1 multiple times it'll show page 1.php only once but if I click on link 1, then link 2, then link 1 again it will display page 1.php, then append page 2.php and append another page 1.php.
I'm starting to think that the setInterval is wrong and I may use .one() for the whole checkAnchor() function and bind it to the <a> tags. I tried this but it's not working either :(((
core.js - using .one()
var currentAnchor = null;
//$(document).ready(checkAnchor);
//Function which chek if there are anchor changes, if there are, sends the ajax petition checkAnchor
$("a").one("click", function (){
//Check if it has changes
if(currentAnchor != document.location.hash){
currentAnchor = document.location.hash;
//if there is not anchor, the loads the default section
if(!currentAnchor){
query = "page=1";
}
else
{
//Creates the string callback. This converts the url URL/#main&id=2 in URL/?section=main&id=2
var splits = currentAnchor.substring(1).split('&');
//Get the section
var page = splits[0];
delete splits[0];
var query = "page=" + page;
}
alert ("hello");
//Send the petition
$("#loading").show();
$.get("callbacks.php",query, function(data){
$("#content").append(data);
$("#loading").hide();
});
}
});
The other thing I liked as an approach is adding the names of the pages to an array and then checking that array to make sure the page wasn't displayed yet. I managed to fill up an array with the page names using .push() but I hit a dead end when looking up for a value in it. If you have an idea how that's supposed to look like that'd be very helpful as well.
core.js
///On load page
var contentLoaded;
$().ready(function(){
contentLoaded = false;
setInterval("checkAnchor()", 300);
alert (contentLoaded);
});
var currentAnchor = null;
//Function which chek if there are anchor changes, if there are, sends the ajax petition
function checkAnchor(){
//Check if it has changes
if(currentAnchor != document.location.hash){
currentAnchor = document.location.hash;
//if there is not anchor, the loads the default section
if(!currentAnchor){
query = "page=1";
}
else
{
//Creates the string callback. This converts the url URL/#main&id=2 in URL/?section=main&id=2
var splits = currentAnchor.substring(1).split('&');
//Get the section
var page = splits[0];
delete splits[0];
var query = "page=" + page;
}
alert ("hello");
//Send the petition
$("#loading").show();
alert (contentLoaded);
if (!contentLoaded){
$.get("callbacks.php",query, function(data){
$("#content").append(data);
$("#loading").hide();
});
alert (contentLoaded);
}
contentLoaded = true;
}
}
here is my
callbacks.php
<?php
//Captures the petition and load the suitable section
switch($_GET['page']){
case "4100errors" :
include 'template/4100errors.php';
break;
case "4100downloads" :
include 'template/4100downloads.php';
break;
}
?>
And my main file
4100.php
<?php
include 'template/header.php';
include 'template/4100menu.php';
include 'template/log.php';
include 'template/links.php';
include 'template/4100breadcrumbs.php';
?>
<div class="left-widget">
<div style="display:none; position:absolute; top:-9999; z-index:-100;">
</div>
<div id="side-nav-bar" class="Mwidget">
<h3>Contents</h3>
<ul class="tree">
<li><a href="#4100downloads" class="links" >Downloads</a> </li>
<li>Error Troubleshooting</li>
</ul>
</div>
</div>
<div id="content" style="margin-top:100px; margin-left:300px;">
<?
switch ($_GET['page'])
{
case "4100downloads": include 'template/4100downloads.php'; break;
case "4100errors": include 'template/4100errors.php'; break;
}
?>
</div>
</body>
</html>
4100dowloads.php
Downloads test page
4100error.php
Errors test page
Also you can look at the test page here http://period3designs.com/phptest/1/4100.php
"What is the proper way to use .get() in conjunction with .one() (or .live()) so that an external php file is appended only once?"
.one() and live() really have little to do with $.get. They're only for event handling.
If you intend to run the code every 50ms as you are, but want to replace the current content, then use .html() instead of .append().
$("#content").html(data);
This will overwrite the old content.
I assume you're aware of this, but just to be sure, your code is running at an interval because of this...
$().ready(function(){
setInterval("checkAnchor()", 50); // better--> setInterval(checkAnchor, 50);
});
If you only want it once on document load, then do this...
$(document).ready(checkAnchor);
Just use a boolean flag to determine if you loaded the data yet or not. Set it to false on page load, and just after the call to $.get set it to true. Then, wrap your $.get with an if (!contentLoaded) { $.get ... }.
That way you will execute the $.get only once.
BTW: $.one is used to bind an event to an element, that will execute only once and then unbind it self from it.
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!