Gadgetster Gadgetster - 1 month ago 9
Ajax Question

Display online users as green and offline as grey using real time updates

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:

enter image description here

And user1 logs in, it will become:

enter image description here

Then say user2 logs in as well at the same time:

enter image description here

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!

Answer

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>
Comments