Load content from MySQL on scroll with AJAX post - php

I have a segment of my website which needs to dynamically load content when the user reaches the bottom. I'm using jQuery, and this is the code to detect the scroll:
$(document).ready(function() {
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
alert("Bottom reached");
$('div#loadMoreComments').show();
dataStr = "from=" + $(".n:last").attr('id')
$.ajax({
type: "POST",
url: "ajax/query.php",
data: dataStr,
success: function(html) {
if(html){
$("#hold").append(html);
alert("Data was added");
}
else{
$('div#loadMoreComments').replaceWith("<center><h1 style='color:red'>End of countries !!!!!!!</h1></center>");
alert("Data was not added");
}
}
});
}
});
});
The first problem I have is that the scroll to the bottom is only detected when the user reaches the top of the page. The second problem is that it doesn't load any content, at all, because the variable doesn't seem to be posted, here's my code in the query.php:
if(array_key_exists('from', $_POST)) {
$from = htmlspecialchars(stripslashes(mysql_real_escape_string($_POST['from'])));
$to = 15;
$re = ("SELECT status as status, sid as sid, UNIX_TIMESTAMP(timestamp) as timestamp FROM mingle_status WHERE uid = '$uid' ORDER BY timestamp DESC LIMIT $from,$to"); //query
}
else {
$re = ("SELECT id as id, status as status, sid as sid, UNIX_TIMESTAMP(timestamp) as timestamp FROM mingle_status WHERE uid = '$uid' ORDER BY timestamp DESC LIMIT 1"); //query
}
$result = mysql_query($re) or die (mysql_error());
while($st = mysql_fetch_assoc($result)) {
$status = nl2br($st['status']);
$sid = $st['sid'];
$td = $st['timestamp'];
$id = $st['id'];
?>
<div id="<?php echo $id; ?>" class="id">
<!-- stuff -->
</div>
<?php
}
?>
And the error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '",15' at line 1
If anyone could help me with this, it'd be great, I'd really appreciate it.
EDIT: Okay, I can now get a div generated, but only when I scroll to the top of the page, and it only appends one div, and if I scroll to the top again, it appends the exact same div.

This is just wrong:
$from = htmlspecialchars(stripslashes(mysql_real_escape_string($_POST['from'])));
If from is supposed to be an integer, just use:
$from = (int) $_POST['from'];
I also see that that number comes from an id in the html and ids cannot start with a number.
Edit: An additional problem is that you are not selecting the ID in your sql query if from exists and even if you would do that, this approach can lead to problems in the future when you delete records and your IDs are not sequential any more.
About the first problem, I can solve that in firebug changing:
if($(window).scrollTop() + $(window).height() == $(document).height()) {
to:
if( ($(window).scrollTop() + $(window).height()) > ($(document).height() - 10) ) {
Edit 2: To solve your non-sequential ID problem, the easiest way would be to calculate from in javascript using something like:
dataStr = "from=" + $(".n").length; // just count the number of elements you are showing already

Related

Loop through a list of div using setInterval to refresh data every x seconds

I have this page that consists of a list of user posts / message. When a post is liked, I want it to reflect on all other users, and based on my research setInterval can get the job done by refreshing a specific content for a number of seconds. Currently, I'm having trouble looping through all the user messages and show the updated number of likes. What's happening is that the number displayed is constantly changing and looping through all the values for a single post. Example: If I have 1, 0, and 2 likes respectively on three different posts, the number for the first post changes to 1, 0, and 2 instead of just showing "1". I'm kind of a beginner when it comes to AJAX.
Here's my code:
Jquery / Ajax
function refreshPostLikes() {
setInterval(function() {
$(".posts .id").each(function() { //get id for each post
var postid = $(this).attr("value");
updatePostLikes(postid); //pass the postid variable
});
}, 1000);
}
function updatePostLikes(postid) {
$.ajax({
url: "/main/refresh-post-like.php",
type: "post",
data: {postid: postid}, //send data to php file
success: function(data) {
$(".posts .like").html(data); //output number of likes
}
});
}
PHP Query
<?php
require_once('../connection.php');
$postID = $_POST['postid'];
$likeCountQuery = "select count(*) as total_likes from posts_likes WHERE like_status=1 AND post_id=".$postID; //query number of posts with a like
$likeQueryResult = mysqli_query($conn, $likeCountQuery);
while($likeNumber = mysqli_fetch_assoc($likeQueryResult)) {
$likes = $likeNumber['total_likes'];
if($likes != 0) {
echo $likes;
}
else {
echo '';
}
}
?>
Still not sure this is the best way to go, but the reason your code doesn't work is due to omitting the postid when updating the HTML in the success part of your code.
function updatePostLikes(postid) {
$.ajax({
url: "/main/refresh-post-like.php",
type: "post",
data: {postid: postid}, //send data to php file
success: function(data) {
$(".posts .like").html(data); //output number of likes
}
});
}
with this command $(".posts .like").html(data); //output number of likes
You are updating all the divs which have these classes specified with the same value.
Set postid as id for the div and change the command to
$("#postid").html(data); //output number of likes
is constantly changing and looping through all the values for a single
post
This happens because there is no reference to the post that needs to be updated. What you are doing now is to cycle through all the elements that have the ".posts .id" classes, therefore the update applies to all the posts and not the single one. You should modify your function to make it update only that post (try passing it a unique id in html)
Where N is the id of your post. (For example postid)
Then update the value using this
function updatePostLikes(postid) {
$.ajax({
url: "/main/refresh-post-like.php",
type: "post",
data: {
postid: postid
}, //send data to php file
success: function(data) {
//$(".posts .like").html(data); //output number of likes
$("#post-"+postid).html(data); // in this way we're get the right post
}
});
}
function refreshPostLikes() {
$(".posts .id").each(function() { //get id for each post
var postid = $(this).attr("value");
updatePostLikes(postid); //pass the postid variable
});
setTimeout(refreshPostLikes, 1000); //Check every sec if there are update
}
setTimeout(updateChat, 1000); //Start the check
Prevent SQL Injection
Escape is not enough
<?php
require_once ('../connection.php');
$postID = $_POST['postid']; //Escape this value before use inside the query see linked question
// NEVER TRUST USER INPUT
//$likeCountQuery it could be used for perform a SQL Injection NEVER TRUST USER INPUT
//NEVER !!!
$likeCountQuery = "SELECT COUNT(*) AS total_likes FROM posts_likes WHERE like_status=1 AND post_id=".$postID; //query number of posts with a like
$likeQueryResult = mysqli_query($conn, $likeCountQuery);
while ($likeNumber = mysqli_fetch_assoc($likeQueryResult))
{
$likes = $likeNumber['total_likes'];
if ($likes != 0)
{
echo $likes;
}
else
{
echo '';
}
}
?>

Php: Display something if First Record is Reached

I have a database where it has 10+ records:
Accid | Firstname | Lastname
1. John Marshall
2. Sherlock Holmes
3. Random Dude
...
I'd display this using echo on php but with AJAX... it first loads up 5 users, and when the user has scrolled at the bottom of the page, it will load another 5 on the list (it adds the Offset's value +=5). Here's my display code:
$sql = "SELECT * FROM users ORDER BY lastname DESC LIMIT 5 OFFSET 5";
$result = mysqli_query($connection,$sql);
While($row=mysqli_fetch_assoc) {
echo $row['lastname']." ".$row['firstname']."<br/>";
}
This list could be very long if I have 100 users let's say.
Whenever the user scrolls at the bottom, another 5 users pops up. Now, if I reached the end of the whole records in the USERS database, I'd like to display something like - "End of User List"
How can I achieve this?
Jquery Code
$.ajax({
type: "GET",
url: "getusers.php",
data: {
'offset': 4
},
success: function(data){
$('#displayusers').append(data);
}
});
I'd like to disagree with #PressingOnAlways answer.
You can just send back a different response from PHP and check it in javascript.
$sql = "SELECT * FROM users ORDER BY lastname DESC LIMIT 5 OFFSET 5";
$result = mysqli_query($connection,$sql);
if(mysqli_num_rows($result) == 0){
die("last");
}
While($row=mysqli_fetch_assoc) {
echo $row['lastname']." ".$row['firstname']."<br/>";
}
Now you can just check it in javascript:
if(response == "last"){
mydiv.append('This is the end');
}
Now, I would like to show you my way of doing things, which (imo) is a lot cleaner:
First, your ajax calls
We're going to make sure our data will be in json format automatically from now on:
$.ajax({
type: 'GET',
url: "getusers.php",
cache: false,
data: {'offset': 4},
dataType: "json"
}).done(function(json){
if(json.hasOwnProperty("last"){
//No more results
//do your thang;
return false;
}
if(getLength(json) < 5){
//Smaller then 5, must have hit the last. Do your thang;
return false;
}
//It came here, so it's all good. Go on
$('#displayusers').append(data);
});
Secondly: Your PHP side
It's never a good plan to echo html over AJAX. It's way more efficient (takes up less servertime + sends smaller amounts of data over the internet highway) than doing it in PHP.
$sql = "SELECT * FROM users ORDER BY lastname DESC LIMIT 5 OFFSET 5";
$result = mysqli_query($connection,$sql);
$lastResponse = array("last" => "last");
if(mysqli_num_rows($result) == 0){
//Always send back json or it'll give you an error
die(json_encode($lastResponse));
}
$return = array();
While($row=mysqli_fetch_assoc) {
$return[] = $row['lastname']." ".$row['firstname'];
}
echo json_encode($return);
Third: A js function to check the arrayLength
//Checks the length of a json object or array
//Returns false if length is 0 or unable to check it
function getLength(obj) {
if (typeof obj == 'undefined') {
return false;
}
var l = 0;
if (typeof obj == 'object') {
l = Object.keys(obj).length;
}
else {
l = obj.length;
}
return (l == 0 ? false : l);
}
The best place to implement this feature would be on the JS client side. Since your PHP script has no way of knowing if it is the end of the list or not, you need to do this on the client. The JS code should check if the results returned from your php script is less than 5, if so, the "End of User List" should be printed.

Get the latest messages only from MySQL using jQuery (Ajax) and PHP ? (Live Chat APP)

I'm trying to figure out how I can fetch the latest (newest) messages from MySQL that has not already been fetched.
What I want:
If user A sends a message, I would like user B to fetch that message, but only once.I don't want to fetch everything, as this would be bad in the long run.
My current solution kinda works but the problem is that it sometimes fetches the same message twice and another problem is that if a client where to get a lagspike, he would miss those messages because the current solution is based upon a timeframe.
What I currently got:
jQuery (Ajax)
setInterval(function () {
console.log('Attempting to update');
$.ajax({
type: "GET",
url: "palenc.php?hb=<?php echo $hb; ?>",
dataType: "json",
success: function(data) {
if (data == 2) {
console.log('No messages to fetch');
} else {
var password = "<?php echo $key; ?>";
for (i = 0; i < data.length; ++i) {
var from = data[i][0];
var emsg = data[i][1];
var pmsg = decrypt(emsg, password);
var msg = pmsg.toString(PalieEncryption.enc.Utf8);
$("#chat").append('<div class="left spotmsg"><div class="chat-
avatar pull-left"><img src="https://example.net/img/them.png"
alt="avatar" width="48" height="48"></div><div class="message">
<div class="arrow-left"></div><p><strong>#'+from+'</strong></p>
<p
class="txt">'+msg+'</p></div></div>');
}
$('textarea').focus();
$(".chat_area").animate({ scrollTop: $(".chat_area")
[0].scrollHeight}, 1000);
}
}
});
}, 1350);
PHP
$stmt = $mysqli->prepare('SELECT chat_user, chat_msg FROM chat_msg
WHERE chat_id = ? AND chat_time > (NOW() - INTERVAL 2 SECOND) AND
chat_user != ?');
$stmt->bind_param('ss', $id,$_SESSION['sess_user']);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_all()) {
header('Content-Type: application/json');
ob_end_clean();
echo json_encode($row);
}
Assuming you have an autoincrementing primary key on the messages table, why not send the primary key along with the message to the client? Then when the client requests newer messages, it can send back the primary key of the most recent message received, and the server can query for all messages for that user with a primary key greater than the one returned.

Auto Refresh DIV contents from Mysql table - one at a time

I need to automatically refresh content from a mysql data table every 5 seconds, but showing only one distinct record at a time, going through every record in a endless loop.
I load news.php, that has this js :
<script type="text/javascript">
var auto_refresh = setInterval(function () {
$('#canvas').load('content.php').fadein("medium");}, 5000);
// refresh every 5 seconds
</script>
content.php has the db connection
$query_Recordset5 = "SELECT * FROM news";
$Recordset5 = mysql_query($query_Recordset5, $connection) or die(mysql_error());
$row_Recordset5 = mysql_fetch_assoc($Recordset5);
$totalRows_Recordset5 = mysql_num_rows($Recordset5);
As well as the fields echoed to the page.
I understand that you would have to create a counter and bring back one different record everytime, but I am having a tough time with it.
Thanks
If your table has an auto increment field (say "id"). You start by passing page.php and id of 0, so it will grab the auto increment field greater than 0, and then you pass that fields ID back through jquery. When you send it a second time it will not be included because you will be using the greater than sign.
The if num_rows == 0 checks to see if there are any fields, if none, then it will assume that the auto increment field you sent it is the last one, and then it will run the sql statement with the very first auto increment value.
<?php
// page.php
$id = (int) $_REQUEST['id'];
$sq = "select * from news where id > ".$id." order by id asc limit 0,1";
$qu = $con->query($sq);
if ($qu->num_rows == 0) {
$sq2 = "select * from news order by id asc limit 0,1";
$qu2 = $con->query($s2);
while ($fe = $qu->fetch_assoc()) {
echo $fe['id']."|".$fe['content'];
}
} else {
while ($fe = $qu->fetch_assoc()) {
echo $fe['id']."|".$fe['content'];
}
}
?>
<script>
$(document).ready(function() {
setInterval(function(){ updateNews(); }, 5000);
});
function updateNews() {
var id = 0;
id = $("#hidden-id").val();
$.get("page.php?id=" + id, function(data) {
// I use $.get so that I can split the data that it returns before populating
// the #canvas. This way we can strip off the first part which is the auto
// increment
var ref = data.split('|');
$("#hidden-id").val(ref[0]);
$("#canvas").html(ref[1]);
});
}
</script>

Make A Next Button For More More Data?

Hi dear friends,
I hope u are all fine.
I want to make a next button for getting more data from mysql database.
For example:
$sql = mysql_query("SELECT * FROM table LIMIT 0,7");
It get 7 rows.For next data code is that.
$sql = mysql_query("SELECT * FROM table LIMIT 7,7");
I can i do that using ajax.
As you can see in many website like facebook,When you click on comment it give a limited
comment and when you click on more comment it give more and so on.In this proccess you can see
that the other content of page does not change.It means it can use ajax and how can I do that in ajax.
Please help me.Thanks.
your ajax would be something like this
var numberOfdata = 0;
$('#button').click(function () {
$.ajax({
url: 'load.php',
data: {
'limit' : numberOfdata,
// other data ...
},
type : 'post',
// other parameters...
}).success(function (data) {
// adding data to your website
numberOfdata += 7;
});
});
and in your server side, you could do something like this
... other operations
mysql_query("SELECT * FROM table LIMIT " . $_POST['limit'] . ",7");
... continuting the work
Note: You should be able to handle SQL injections on your own.
Edit: please note that mysql_query is not recommended.
You have to send the current comments count via Ajax, get the new ones from the response and display them.
Javascript:
$(document).ready(function() {
$('a.pagination-more').click(function() {
var current_comments_count = $(this).data("current_comments_count");
$.ajax({
type: "POST",
url: "pagination/pagination_ajax_more.php",
data: { "limit_start":current_comments_count },
beforeSend: function() {
$('a.pagination-more').html('<img class="loading-gif" src="pagination/loading.gif" />');
},
success: function(html){
$("#more").remove(); // This is the "More" button. It is appended to the end again in the 'html' variable
$("ul#updates").append(html);
if($("a#end")[0]) {
$("div#more").remove();
}
}
});
return false;
});
});
On the PHP side you just get $limit_start, get results from the database and echo the html like:
$limit_start = $_POST['limit_start'];
$query = mysql_query("SELECT COUNT(*) FROM `table` LIMIT 0, $limit_start");
$current_comments_count = mysql_num_rows($query);
$query = mysql_query("SELECT * FROM `table` LIMIT $limit_start, 7");
while($row = mysql_fetch_assoc($query)) {
echo '<li>
blah blah...
</li>';
}
if(mysql_num_rows($query) == 7)
echo '<div id="more"><a data-current_comments_count="$current_comments_count" class="button pagination-more" href="#">More</a></div>';
else
echo '<div id="more"><a id="end" class="button pagination-more" href="#">The button will be removed from jQuery...</a></div>';
Of course it is strongly recommended to secure your application and not to use only mysql_query(). This code is working but I removed some other stuff and didn't test it now. So, some errors may occur.

Categories