I'm creating an events website using PHP. I have a database with an "events" table that includes id, title and date (Y-m-d).
My index page displays the first 30 events, in date order, starting with today. When you click "More", 30 more events are displayed via AJAX. AJAX loads more.php within index.php, and index.php passes the latest id/date to more.php via a PHP session.
I want to be able to display "More" again and again, so that each time the user clicks it, 30 more events are displayed beneath the previous events (like what happens when you scroll all the way down on Twitter).
Unfortunately, my "More" button works the first time (when clicked from index.php), but when clicked on in more.php, quickly loops again and again through the id/date variables until there aren't any more events left.
How do I create my desired More button via AJAX?
Here's relevant code from index.php:
<!-- "More" button JavaScript. Loads 10 more events when clicked -->
<script type="text/javascript" src="ajax.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("more").click(function(){
$("more").load('more.php');
});
});
</script>
<?php
session_start();
$today = date('Y-m-d');
$result = mysql_query("SELECT * FROM events WHERE date>='$today' ORDER BY date LIMIT 0, 30");
while($row = mysql_fetch_array($result))
{
echo $row['id'];
echo $row['title'];
echo $row['date'];
echo "<br />";
// Grabs date/id of last event echoed
$nId = $row['id'];
$nDate = $row['date'];
}
// Sends last date/id echoed to more.php
$_SESSION['nDate']=$nDate;
$_SESSION['nId']=$nId;
?>
<!-- This more tag seems to work with my JavaScript -->
<more>More</more>
And more.php:
<!-- "More" button JavaScript. Loads 30 more events when clicked -->
<script type="text/javascript" src="ajax.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("more").click(function(){
$("more").load('more.php');
});
});
</script>
<?php
session_start();
$nId = $_SESSION['nId'];
$nDate = $_SESSION['nDate'];
$result = mysql_query("SELECT * FROM events WHERE date>='$nDate' && id>='$nId' ORDER BY date LIMIT 1, 30");
while($row = mysql_fetch_array($result))
{
echo $row['id'];
echo $row['title'];
echo $row['date'];
echo "<br />";
$nId = $row['id'];
$nDate = $row['date'];
}
$_SESSION['nDate']=$nDate;
$_SESSION['nId']=$nId;
?>
<more>More</more>
Thanks a lot in advance, guys :)
You have extra unneeded data here. Try this example.
index.php:
<?php
// THAT SHOULD BE BEFORE ANY OUTPUT IS SENT TO THE BROWSER
session_start();
?>
<!-- "More" button JavaScript. Loads 10 more events when clicked -->
<script type="text/javascript" src="ajax.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("more").click(function(){
$('<div style="display:none;"/>').insertBefore($(this))
.load('more.php', function(){$(this).slideDown();});
});
});
</script>
<?php
include('more.php');
?>
<!-- This more tag seems to work with my JavaScript -->
<more>More</more>
And more.php:
<?php
// include here some code for connection to DB
if (!isset($_SESSION))
{
session_start();
$nId = $_SESSION['nId'];
$nDate = $_SESSION['nDate'];
$result = mysql_query("SELECT * FROM events WHERE date>='$nDate' &&
id>='$nId' ORDER BY date LIMIT 1, 30");
}
else
{
$today = date('Y-m-d');
$result = mysql_query("SELECT * FROM events WHERE date>='$today'
ORDER BY date LIMIT 0, 30");
}
while($row = mysql_fetch_array($result))
{
echo $row['id'];
echo $row['title'];
echo $row['date'];
echo "<br />";
$nId = $row['id'];
$nDate = $row['date'];
}
$_SESSION['nDate']=$nDate;
$_SESSION['nId']=$nId;
?>
And, probably, you should add the way to stop this expansion when there are no more records in db.
ps: and why do you need nonstandard tag more
? use, for example, <div id='more'>More</div>
. Then your $("more")
will change to $("#more")
.
When you use jQuery's load function you are only replacing what comes between the element and its closing tag. The javascript you have set up in the index.php document is still there after your AJAX load. So each time you click your button you are getting a duplicate of your javascript code executing again. When the new javascript from more.php is loaded you get another $(document).ready() which binds another click event to all tags that match "more", so now you are loading a lot more than you expected when you click again.
The first thing you should do is not include the javascript in your more.php. If I understand what you're trying to accomplish the next thing you'll want to do is change your click event to create a new <div>, call jQuery's load function on that, and append it somwhere in your document. It might look something like this:
$("more").click( function() {
$("body").append( $("<div>").load("mode.php") );
} );
I would also strongly advise against making up a new tag like <more>. Browsers will not know what to do with it so you can't be sure how it will be rendered, if at all. You can just use a <div> in these situations and give it an ID or class as necessary.
Furthermore, your algorithm for choosing which events to show next will fail if you have more than one event on the same day. What you really want to do there is just keep track of the offset value that you want to use as part of your LIMIT clause in the query.