Jump to content

Using infinite scroll on multiple pages?


man5

Recommended Posts

I am in a bit of confusion.

 

I have an infinite scroll script that works great.  The only problem is, it works on all pages. 

 

The basic set up is like this.

 

index.php page includes

<script type="text/javascript" src="js/scroll.js"> </script>

 

scroll.js includes $.post('query.php')

 

query.php

$query = mysqli_query(SELECT * FROM table...etc );

 

 

So what I want to do is create multiple different queries that retrives different data from the database.  How do I do that?  The above setup only allows 1 query to be used with the inifinte scroll.

 

Link to comment
Share on other sites

If i create multiple query.php files, then I would have to create multiple scroll.js files.  That won't work, especially with how I have the html page set up.  I split it up to header, body,footer.

 

I would like to know how to set up parameters via url.  Can you show me please?  Thanks.

Link to comment
Share on other sites

It's a pretty simple idea.

 

We haven't seen whats in your scroll.js. From your description we can assume that's its not very self contained.

 

So, first thing is first, fix that. Make it into an object, or at very least a function that excepts an argument.

 

You could then do something this:

 

<script src="js/scroll.js"> </script>
<script>
  scroll('page1');
</script>
Then, within your scroll function, instead of simply calling:

 

$.post('query.php');
You could do something like:

 

$.post('query.php?page=' + page);
(where page is the variable you pass into the function)

 

Then, finally, within php you could do something like:

 

<?php

switch($_GET['page']) {
  case 'page1':
    $sql = "SELECT a,b,c FROM foo";
    break;
  case 'page2':
    $sql = "SELECT a,b,c FROM bar";
    break;
}

$query = mysqli_query($sql);
Of course this is a very simple example that could (and should) be improved upon, but hopefully it's enough to get you started in the right direction.
Link to comment
Share on other sites

Alright I've created a simple sample code to test all that. File names are same as in that demo link i posted.

 

Index.php

 

<?php

 
$hostname='127.0.0.1';
$username='root';
$password='';
 
$dbh = new PDO("mysql:host=$hostname;dbname=cave",$username,$password);
?>
 
<!DOCTYPE HTML>
<head>
<script type="text/javascript" src="jquery-1.11.0.min.js"></script>
<script src="javascript.js"></script>
<script type="text/javascript" src="//use.typekit.net/vue1oix.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
<script>
 
$(document).ready(function() {
 
$('#content').scrollPagination({
 
nop     : 4, // The number of posts per scroll to be loaded
offset  : 0, // Initial offset, begins at 0 in this case
error   : 'No More Posts!', // When the user reaches the end this is the message that is
// displayed. You can change this if you want.
delay   : 500, // When you scroll down the posts will load after a delayed amount of time.
  // This is mainly for usability concerns. You can alter this as you see fit
scroll  : true // The main bit, if set to false posts will not load as the user scrolls. 
  // but will still load if the user clicks.
 
});
 
});
 
</script>
<style>
 
h1 {
font-size: 50px;
}
 
</style>
</head>
 
<body>
 
<div id="content"> </div>
 
 
</body>
</html>

 

 

 

ajax.php

 

<?php

$hostname='127.0.0.1';
$username='root';
$password='';
 
$dbh = new PDO("mysql:host=$hostname;dbname=cave",$username,$password);
 
$offset = is_numeric($_POST['offset']) ? $_POST['offset'] : die();
$postnumbers = is_numeric($_POST['number']) ? $_POST['number'] : die();
 
 
$getPosts = $dbh->prepare("SELECT * FROM posts ORDER BY id DESC LIMIT ".$postnumbers." OFFSET ".$offset);
$getPosts->execute();
$post = $getPosts->fetchAll();
 
if(count($post) > 0) {
foreach($post as $row) {
 
$title = $row['title']; 
$post = $row['post'];
 
?>
<h1><?php echo $title ?></h1>
<h3><?php echo $post ?></h3>
<?php
}
}
?>
 

 

 

javascript.js

(function($) {

	$.fn.scrollPagination = function(options) {
		
		var settings = { 
			nop     : 4, // The number of posts per scroll to be loaded
			offset  : 0, // Initial offset, begins at 0 in this case
			error   : 'No More Posts!', // When the user reaches the end this is the message that is
			                            // displayed. You can change this if you want.
			delay   : 500, // When you scroll down the posts will load after a delayed amount of time.
			               // This is mainly for usability concerns. You can alter this as you see fit
			scroll  : true // The main bit, if set to false posts will not load as the user scrolls. 
			               // but will still load if the user clicks.
		}
		
		// Extend the options so they work with the plugin
		if(options) {
			$.extend(settings, options);
		}
		
		// For each so that we keep chainability.
		return this.each(function() {		
			
			// Some variables 
			$this = $(this);
			$settings = settings;
			var offset = $settings.offset;
			var busy = false; // Checks if the scroll action is happening 
			                  // so we don't run it multiple times
			
			// Custom messages based on settings
			if($settings.scroll == true) $initmessage = 'Scroll for more or click here';
			else $initmessage = 'Click for more';
			
			// Append custom messages and extra UI
			$this.append('<div class="content"></div><div class="loading-bar">'+$initmessage+'</div>');
			
			function getData() {
				
				// Post data to ajax.php
				$.post('ajax.php?page=' + page, {
						
					action        : 'scrollpagination',
				    number        : $settings.nop,
				    offset        : offset,
					    
				}, function(data) {
						
					// Change loading bar content (it may have been altered)
					$this.find('.loading-bar').html($initmessage);
						
					// If there is no data returned, there are no more posts to be shown. Show error
					if(data == "") { 
						$this.find('.loading-bar').html($settings.error);	
					}
					else {
						
						// Offset increases
					    offset = offset+$settings.nop; 
						    
						// Append the data to the content div
					   	$this.find('.content').append(data);
						
						// No longer busy!	
						busy = false;
					}	
						
				});
					
			}	
			
			getData(); // Run function initially
			
			// If scrolling is enabled
			if($settings.scroll == true) {
				// .. and the user is scrolling
				$(window).scroll(function() {
					
					// Check the user is at the bottom of the element
					if($(window).scrollTop() + $(window).height() > $this.height() && !busy) {
						
						// Now we are working, so busy is true
						busy = true;
						
						// Tell the user we're loading posts
						$this.find('.loading-bar').html('Loading Posts');
						
						// Run the function to fetch the data inside a delay
						// This is useful if you have content in a footer you
						// want the user to see.
						setTimeout(function() {
							
							getData();
							
						}, $settings.delay);
							
					}	
				});
			}
			
			// Also content can be loaded by clicking the loading bar/
			$this.find('.loading-bar').click(function() {
			
				if(busy == false) {
					busy = true;
					getData();
				}
			
			});
			
		});
	}

})(jQuery);

Can you please plugin your code in my code above? It'll be more clear that way for both of us.

Link to comment
Share on other sites

I understand your code now and where to implement it.  I just have one question. 

<script>
  scroll('page1');
</script>

The name 'scroll'. Is it a variable name taken from the javascript file or is that the name of the javascript page; because as you can see, both name are the same.

 

And if i understand it correctly, I apply that in the header of every page and change only the page#.

Link to comment
Share on other sites

Alright so here is my setup based on your code.

 

ajax.php

$offset = is_numeric($_POST['offset']) ? $_POST['offset'] : die();
$postnumbers = is_numeric($_POST['number']) ? $_POST['number'] : die();
 
 switch($_GET['page']) {
		
	  case 'index':
               $getPosts = $dbh->prepare("SELECT * FROM posts ORDER BY id DESC LIMIT ".$postnumbers." OFFSET ".$offset);
		break;
	  case 'records':
		 $getPosts = $dbh->prepare("SELECT * FROM posts ORDER BY id DESC LIMIT ".$postnumbers." OFFSET ".$offset);
		break;
}

$getPosts->execute();
$post = $getPosts->fetchAll();
 
if(count($post) > 0) {
foreach($post as $row) {
 
$title = $row['title']; 
$post = $row['post'];

echo $title;
echo $post;

Here is the javascript.js

$.post('ajax.php?page=' + page, {
						
   action        : 'scrollpagination',
   number        : $settings.nop,
   offset        : offset,
					    
}

and index.php

<script type="text/javascript" src="js/autoscroll.js"> </script>
	<script type="text/javascript">
		$(document).ready(function() {

			$('#results').scrollPagination({

				nop     : 7, // The number of posts per scroll to be loaded
				offset  : 0, // Initial offset, begins at 0 in this case
				error   : 'No More Posts!', // When the user reaches the end this is the message that is
											// displayed. You can change this if you want.
				delay   : 500, // When you scroll down the posts will load after a delayed amount of time.
							   // This is mainly for usability concerns. You can alter this as you see fit
				scroll  : true // The main bit, if set to false posts will not load as the user scrolls. 
							   // but will still load if the user clicks.
				
			});
			
		});
	</script>


<body>
     <div id="results"></div>
</body>

Where exactly in the above script tags would I add the following?


  scroll('index');

I hope I am on the right track.

Link to comment
Share on other sites

I'm trying to. Forgive me, Javascript is still new to me. 

 

This part.

$.post('ajax.php?page=' + page,

It works if I have it like this.

$.post('ajax.php?page=index',

If you can point out again what's wrong, that would be great. 

Link to comment
Share on other sites

I'm not sure it can be explained any simpler.

 

We haven't seen whats in your scroll.js. From your description we can assume that's its not very self contained.

 

So, first thing is first, fix that. Make it into an object, or at very least a function that excepts an argument.

 

You could then do something this:

 

<script src="js/scroll.js"> </script>
<script>
  scroll('page1');
</script>
Then, within your scroll function, instead of simply calling:

 

$.post('query.php');
You could do something like:

 

$.post('query.php?page=' + page);
(where page is the variable you pass into the function)

 

Link to comment
Share on other sites

Alright so I have defined the page varible and given it the case value.  Results show up. Which is good.

var page = 'index';
     $.post('autoload.php?page=' + page);

Now I'm guessing the final step is this.

<script>
  scroll('index');
</script>

I added that  script to the top of my index page. It won't work.

 

This is the full script in my header.

<script type="text/javascript">
		$(document).ready(function() {

			$('#results').scrollPagination({

				nop     : 7, // The number of posts per scroll to be loaded
				offset  : 0, // Initial offset, begins at 0 in this case
				error   : 'No More Posts!', // When the user reaches the end this is the message that is
											// displayed. You can change this if you want.
				delay   : 500, // When you scroll down the posts will load after a delayed amount of time.
							   // This is mainly for usability concerns. You can alter this as you see fit
				scroll  : true // The main bit, if set to false posts will not load as the user scrolls. 
							   // but will still load if the user clicks.
				
			});
			
		});
	</script>

Can you please show me where you would put

 

scroll('index');
 

 

in that header script?

Link to comment
Share on other sites

Update.

 

I've split my site into sections. Header, body, footer.  I have come a solution for the problem above. I am not sure if it is the same solution you've intended. 

 

For the script to work on seperate pages, I created multiple scroll.js files with different page var for each. And of course, different filename for each file.

<script src="js/scroll.js"> </script>
<script src="js/scroll2.js"> </script>

so the above files has to be placed on each body of page that I want to run a different query on. 

 

My only gripe with this is, it's not really clean having js script running in the body section. I wanted to keep all the js in the head section.

 

 

 

Anyways, is this what you were talking about trq?

Link to comment
Share on other sites

Again.

 

Wrap the code you already have within your scroll.js in a function. You can then call this function passing it a page argument.

 

scroll.js

function scroll(page) {

    // your code

    // At some stage calls
    $.post('query.php?page=' + page);
}
Then you can just use:

 

<script src="js/scroll.js"> </script>
<script>
    scroll('page1');
</script>
On page one and...

<script src="js/scroll.js"> </script>
<script>
    scroll('page2');
</script>
on page two etc.
Link to comment
Share on other sites

the method (pun intended, read on) you used with the multiple .js files ignores the purpose of variables in programming. variables exist so that one piece of code can be used over and over and can operate on different values simply by changing the values in the input variable(s) the code uses when you call it.

 

scrollPagination is already a method that has been added to the jquery library as a plug-in. it has a list of existing input parameters, the nop, offset, error... that tell it what to do when it runs (which btw are the defaults defined inside the code and don't need to be listed in the calling code unless you want to use different values than the defaults.)

to make what you are adding to the code general purpose, just add a page : some value parameter in the calling code and then use that page variable inside ONE copy of the .js file.

Link to comment
Share on other sites

To trq,

 

Yes I understand all that and it works.  The only issue with that is, I can only pass 1 defined variable at a time, in the (page).  For example.

function scroll(page) {

    var page = 'page1';

    // At some stage calls
    $.post('query.php?page=' + page);
}

So yes it will show results of 'page1' on index.php.  However, I can't define 'page2' with the same variable name(var page = 'page2').  I must be missing something.

 

 

 

 

 

To mac-gyver,

 

I did not know that scrollPagination is already added to the jquery library. That's good to know. It makes it more clear now.

 

Link to comment
Share on other sites

To trq,

 

Yes I understand all that and it works.  The only issue with that is, I can only pass 1 defined variable at a time, in the (page).  For example.

function scroll(page) {

    var page = 'page1';

    // At some stage calls
    $.post('query.php?page=' + page);
}
So yes it will show results of 'page1' on index.php.  However, I can't define 'page2' with the same variable name(var page = 'page2').  I must be missing something.

 

Where was "var page = 'page1';" in the example I posted? It wasn't. You pass it in as an argument to the function. Do you know what a function is? Do you know what an argument is?

Link to comment
Share on other sites

I am doing exactly what you are saying.  Below is a new simple demo I made just for you to look at.

 

It just won't display the results unless I define page as a variable; which you are saying not to do. And I am passing it as an argument to the function on the index.php and food.php.

 

 

index.php

<?php require_once 'connect.php'; ?>

<!DOCTYPE HTML>
<html lang="en">
<head>
	<script type="text/javascript" src="jquery-1.8.3.min.js"></script>
	<script type="text/javascript" src="//use.typekit.net/vue1oix.js"></script>
	<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
	<script type="text/javascript" src="autoscroll.js"> </script>
	<script type="text/javascript">
		$(document).ready(function() {

			$('#results').scrollPagination({

				nop     : 7, // The number of posts per scroll to be loaded
				offset  : 0, // Initial offset, begins at 0 in this case
				error   : 'No More Posts!', // When the user reaches the end this is the message that is
											// displayed. You can change this if you want.
				delay   : 500, // When you scroll down the posts will load after a delayed amount of time.
							   // This is mainly for usability concerns. You can alter this as you see fit
				scroll  : true // The main bit, if set to false posts will not load as the user scrolls. 
							   // but will still load if the user clicks.
				
			});
			
		});
	</script>	
</head>
<body>

<script type="text/javascript">
    getData('index');
</script>

<ul>
	<li><a href="index.php">Home Page</a></li>
	<li><a href="food.php">Food</a></li>
</ul>



<div id="results"></div>


</body>

 

autoload.php

<?php require_once 'connect.php'; 

	$offset = is_numeric($_POST['offset']) ? $_POST['offset'] : die();
	$postnumbers = is_numeric($_POST['number']) ? $_POST['number'] : die();
	
	switch($_GET['page']) {
		case 'index':
				
			$sth = $dbh->prepare("SELECT * FROM posts ORDER BY id DESC LIMIT ".$postnumbers." OFFSET ".$offset);
			$sth->execute();
			$records = $sth->fetchAll();
			
			if(count($records) > 0){
				foreach($records as $row){
				
					?><h1><?php echo $row['title']; ?></h1><?php
					?><h3><?php echo $row['desc']; ?></h3><?php
				}
			}	
				
		break;
		
		case 'food':
				
			$sth = $dbh->prepare("SELECT * FROM posts WHERE id = 5 ORDER BY id DESC LIMIT ".$postnumbers." OFFSET ".$offset);
			$sth->execute();
			$records = $sth->fetchAll();
			
			if(count($records) > 0){
				foreach($records as $row){
				
					?><h1><?php echo $row['title']; ?></h1><?php
					?><h3><?php echo $row['desc']; ?></h3><?php
				}
			}	
				
		break;
	
	}
	
	
	
	
	
	
?>

 

autoscroll.js

(function($) {

	$.fn.scrollPagination = function(options) {
		
		var settings = { 
			nop     : 7, // The number of posts per scroll to be loaded
			offset  : 0, // Initial offset, begins at 0 in this case
			error   : 'No More Posts!', // When the user reaches the end this is the message that is
			                            // displayed. You can change this if you want.
			delay   : 500, // When you scroll down the posts will load after a delayed amount of time.
			               // This is mainly for usability concerns. You can alter this as you see fit
			scroll  : true // The main bit, if set to false posts will not load as the user scrolls. 
			               // but will still load if the user clicks.
		}
		
		// Extend the options so they work with the plugin
		if(options) {
			$.extend(settings, options);
		}
		
		// For each so that we keep chainability.
		return this.each(function() {		
			
			// Some variables 
			$this = $(this);
			$settings = settings;
			var offset = $settings.offset;
			var busy = false; // Checks if the scroll action is happening 
			                  // so we don't run it multiple times
			
			// Custom messages based on settings
			if($settings.scroll == true) $initmessage = 'Scroll for more or click here';
			else $initmessage = 'Click for more';
			
			// Append custom messages and extra UI
			$this.append('<div class="content"></div><div class="loading-bar">'+$initmessage+'</div>');
			
			function getData(page) {
				
				$.post('autoload.php?page=' + page, {
						
					action        : 'scrollpagination',
				    number        : $settings.nop,
				    offset        : offset,
					    
				}, function(data) {
						
					// Change loading bar content (it may have been altered)
					$this.find('.loading-bar').html($initmessage);
						
					// If there is no data returned, there are no more posts to be shown. Show error
					if(data == "") { 
						$this.find('.loading-bar').html($settings.error);	
					}
					else {
						
						// Offset increases
					    offset = offset+$settings.nop; 
						    
						// Append the data to the content div
					   	$this.find('.content').append(data);
						
						// No longer busy!	
						busy = false;
					}	
						
				});
					
			}
			
			getData(); // Run function initially
			
			// If scrolling is enabled
			if($settings.scroll == true) {
				// .. and the user is scrolling
				$(window).scroll(function() {
					
					// Check the user is at the bottom of the element
					if($(window).scrollTop() + $(window).height() > $this.height() && !busy) {
						
						// Now we are working, so busy is true
						busy = true;
						
						// Tell the user we're loading posts
						$this.find('.loading-bar').html('Loading Posts');
						
						// Run the function to fetch the data inside a delay
						// This is useful if you have content in a footer you
						// want the user to see.
						setTimeout(function() {
							
							getData();
							
						}, $settings.delay);
							
					}	
				});
			}
			
			// Also content can be loaded by clicking the loading bar/
			$this.find('.loading-bar').click(function() {
			
				if(busy == false) {
					busy = true;
					getData();
				}
			
			});
			
		});
	}

})(jQuery);

food.php

<?php require_once 'connect.php'; ?>

<!DOCTYPE HTML>
<html lang="en">
<head>
	<script type="text/javascript" src="jquery-1.8.3.min.js"></script>
	<script type="text/javascript" src="//use.typekit.net/vue1oix.js"></script>
	<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
	<script type="text/javascript" src="autoscroll.js"> </script>
	<script type="text/javascript">
		$(document).ready(function() {

			$('#results').scrollPagination({

				nop     : 7, // The number of posts per scroll to be loaded
				offset  : 0, // Initial offset, begins at 0 in this case
				error   : 'No More Posts!', // When the user reaches the end this is the message that is
											// displayed. You can change this if you want.
				delay   : 500, // When you scroll down the posts will load after a delayed amount of time.
							   // This is mainly for usability concerns. You can alter this as you see fit
				scroll  : true // The main bit, if set to false posts will not load as the user scrolls. 
							   // but will still load if the user clicks.
				
			});
			
		});
	</script>
</head>
<body>

<script type="text/javascript">
    getData('food');
</script>

<ul>
	<li><a href="index.php">Home Page</a></li>
	<li><a href="food.php">Food</a></li>
</ul>



<div id="results"></div>





</body>
</html>
Link to comment
Share on other sites

You must have misread my replies.

 

 

I suppose it seems like that.  You have to forgive me, Javascript is still new to me.  And from the looks of it, the problem I am having has a such a simple solution, as you put it. I find it odd that I am not understanding it correctly.

Link to comment
Share on other sites

okay, you already have a method/function - scrollPagination() that has parameters defined that tell each instance of it how it should behave. that this code has the url where it's going to make the ajax request to hard coded and buried in the javascript.js file isn't helping (the code is not general purpose now, making it harder than it should be to customize.) since the code in javascript.js is supposed to be defining a jquery plug-in, it should have been written completely configurable so that you don't have to touch the code in it at all and everything it does should be definable in the page where you use that code.
 
for the purpose of making the 'ajax.php' url a call time parameter/variable, make the following changes to the original index.php and javascript.js files -
 
in index.php, add the url     : 'ajax.php', line (line #5 in the following) -  

<script>
$(document).ready(function() {
    $('#content').scrollPagination({

        url     : 'ajax.php', // url to get data from, via .post method, to add a get parameter, just add it on the end of this
        nop     : 10, // The number of posts per scroll to be loaded
        offset  : 0, // Initial offset, begins at 0 in this case
...

 
in javascript.js, add that same line in the var settings = { block (line #7 in the following) - 

(function($) {

    $.fn.scrollPagination = function(options) {
        
        var settings = {

            url     : 'ajax.php', // url to get data from, via .post method, to add a get parameter, just add it on the end of this url
            nop     : 10, // The number of posts per scroll to be loaded
            offset  : 0, // Initial offset, begins at 0 in this case
...

next, find the line in javascript.js that looks like this - $.post('ajax.php', { and change it to -

$.post($settings.url, {

the above makes the url (ajax.php in the example) a parameter that you can change or add anything to.

 


 

for the usage in the code you posted immediately above this reply, for the index.php page, change the url : .... value to the following (this is the same line #5 in snippet of code from the original index.php that i had you change as the first step in this process, all you are doing now is making it into the url and any get parameters you want the code to use) -

        url     : 'autoload.php?page=index',

for the food page, use this for that line -

        url     : 'autoload.php?page=food',
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.