Display online users as green and offline as grey using real time updates
In Status.php
you want to return an array, not just 1 users status. Also, since you are only selecting the online users, you just need their id. So you can just do $array[] = $row['user_id'];
header('Content-Type: application/json');
$array = array();
$res = mysql_query("SELECT * FROM `posts` WHERE status=1");
if(mysql_num_rows($res) > 0){
while($row = mysql_fetch_assoc($res)){
$array[] = $row['user_id']; // this adds each online user id to the array
}
}
echo json_encode($array);
Then in your Main Page
move your <script>
outside the loop, so it does not create it on each post loop. Then change it so it loops through the returned array -
updated
<script type="text/javascript">
$(document).ready(function() {
setInterval(function(){
$.ajax({
url: 'status.php',
dataType: "json",
type: 'GET',
success: function(data) {
if (data.length > 0){ // if at least 1 is online
$('.status').each(function(){ // loop through each of the user posts
var userid = parseInt($(this).attr('id').replace('user','')); // get just the userid #
if($.inArray(userid, data) !== -1){ // if userid # in the returned data array set to online
$(this).css({background: 'green'});
} else{ // else if userid # not in the returned data array set to offline
$(this).css({background: 'grey'});
}
});
}
else { // if no one is online, set all to offline
$('.status').css({background: 'grey'});
}
}
});
}, 2000); //2s just for testing. Set to 15s when code fully works.
});
</script>
Here is an example on JSFiddle - http://jsfiddle.net/f5xkZ/2/
UPDATE 2
$.inArray()
is a jQuery function that checks to see if the value is in an array. If in the array it will return the array key for the value (0,1,2,etc), and if not in the array it will return -1
. So that is why you check it see it it does not return -1
, therefore it is in the array -> if($.inArray(userid, data) !== -1)
. To make it easier, you could add the user
to the array value in php
while($row = mysql_fetch_assoc($res)){
$array[] = 'user'.$row['user_id'];
}
Then change
var userid = parseInt($(this).attr('id').replace('user',''));
to just
var userid = $(this).attr('id');
So now the script looks like
<script type="text/javascript">
$(document).ready(function() {
setInterval(function(){
$.ajax({
url: 'status.php',
dataType: "json",
type: 'GET',
success: function(data) {
if (data.length > 0){ // if at least 1 is online
$('.status').each(function(){ // loop through each of the user posts
var userid = $(this).attr('id'); // get the user#
if($.inArray(userid, data) !== -1){ // if userid # in the returned data array set to online
$(this).css({background: 'green'});
} else{ // else if userid # not in the returned data array set to offline
$(this).css({background: 'grey'});
}
});
}
else { // if no one is online, set all to offline
$('.status').css({background: 'grey'});
}
}
});
}, 2000); //2s just for testing. Set to 15s when code fully works.
});
</script>
Here is an updated jsFiddle - http://jsfiddle.net/f5xkZ/3/
update 3
To make it show immediately, and not wait for the 1st interval, place the ajax call in a function, call the function on page ready and then again in the setInterval()
<script type="text/javascript">
$(document).ready(function() {
// place ajax call in function that you will call on document ready, and in setInterval every 20 sec
function check_online_status(){
$.ajax({
url: 'status.php',
dataType: "json",
type: 'GET',
success: function(data) {
if (data.length > 0){ // if at least 1 is online
$('.status').each(function(){ // loop through each of the user posts
var userid = $(this).attr('id'); // get the user#
if($.inArray(userid, data) !== -1){ // if userid # in the returned data array set to online
$(this).css({background: 'green'});
} else{ // else if userid # not in the returned data array set to offline
$(this).css({background: 'grey'});
}
});
}
else { // if no one is online, set all to offline
$('.status').css({background: 'grey'});
}
}
});
}
check_online_status(); // call the function on document ready
setInterval(function(){check_online_status()}, 20000); // call the function every 20 sec
});
</script>
Gadgetster
Updated on June 07, 2022Comments
-
Gadgetster almost 2 years
I want to get each post to turn green when its author goes online. I have tried to solve my coding problem for at least a week now!!! Please help me out!
For example, if there are 3 users who posted something:
And user1 logs in, it will become:
Then say user2 logs in as well at the same time:
Now if user2 or user1 logs out, it goes back to grey. Everything is realtime - no refresh needed. I would like to make it so that when I open the website, I can see right away who is online and not wait the 2 seconds (in this case) to see a realtime update happen all at once.
I also want to be able to add a dynamic link to the posts. Is there a way to insert tag before the div that will be different depending if the user is logged in or not?
My attempts:
UPDATE:
Status.php
header('Content-Type: application/json'); $array = array(); $res = mysql_query("SELECT * FROM `users` WHERE `status` = 1"); if(mysql_num_rows($res) > 0){ while($row = mysql_fetch_assoc($res)){ $array[] = $row['user_id']; // this adds each online user id to the array } } echo json_encode($array);
Main page
$(document).ready(function() { setInterval(function(){ $.ajax({ url: 'status.php', dataType: "json", type: 'GET', success: function(data) { if (data.length > 0){ // if at least 1 is online $('.status').each(function(){ // loop through each of the user posts if($.inArray(data) !== -1){ // if userid in the returned data array, set to online $(this).css({background: 'green'}); //add a link here } else{ // if not, set to offline $(this).css({background: 'grey'}); alert($.inArray(data)); } }); } else { // if no one is online, set all to offline $('.status').css({background: 'grey'}); } } }); }, 2000); });
CSS styling
.status{ background: grey; }
Everything seems to start working but I cannot get the online user to go green. I tried alerting the array and I get "-1" alerted for some reason. How can I fix that?
I tried to be as clear as possible! All help is greatly appreciated!
-
Gadgetster about 10 yearswow I appreciate your time to help me! I tested your code and the background all stayed grey. I tried to alert a message to check and it went through the else but not through the if statement. I have a feeling something is wrong with if($.inArray(userid, data))
-
Sean about 10 yearsI found my issues and have updated the script code and provided an example on JSFiddle - jsfiddle.net/f5xkZ/2. The issues were (1) missing closing
});
at end of$('.status').each(function(){
, (2) need to convert thevar userid
from a string to a int usingparseInt()
, and (3) need to check if not in array using!== -1
->if($.inArray(userid, data) !== -1){
-
Gadgetster about 10 yearsalert($.inArray(data)); returns "-1", so in this case it will never show the green as it skips the if statement. How can I fix that?
-
Gadgetster about 10 yearsI can't seem to figure it out. But in this case alert($.inArray(data)); will always return "-1" so it make sense why I don't see green, I just don't know how to fix it
-
Sean about 10 yearsSorry, had a project that took me away from stackoverflow for awhile. I have updated/edited my answer with clarification about
$.inArray()
, and a couple simple changes that should make it easier to check if in the returned array. -
Gadgetster about 10 yearsi still get -1 alerted and that skips the if statement where it should make it green. I tried logging in with a different user and I still get -1 alerted.. I assume I am supposed to get 1,2 (if user1 and user2) logged in but i still get -1
-
Sean about 10 yearsCheck your browser console for the returned array from
Status.php
. Verify that the returned array has values that are the same as your post ids. I have provided 2 working jsFiddles that show it should work, so without seeing your updated code I don't know what the issue would be. -
Gadgetster about 10 yearsI did updated the code in the question! the console return the correct values but it doesn't do what it supposed to for some reason
-
Sean about 10 yearsYou are missing 2 important steps/elements that I provided in both code samples - (1)
var userid = parseInt($(this).attr('id').replace('user',''));
. This takes yourid="user#"
and gets just the user number -#
. (2) You are missing the value to search in the array ->if($.inArray(data) !== -1)
should beif($.inArray(userid, data) !== -1)
-
Gadgetster about 10 yearsi tried that but it does the same thing. all the difference is the word user which isn't really needed as my user_id is returned as a number only and not "user1". But either way, I get the same result with adding these in
-
Sean about 10 yearsWhat does you html code look like for the posts? Originally you showed it as something like
<div class="status" id="user1">Post 1</div>
. Is that still the same? What do you have for theid
in yourclass="status"
div?