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

17,501

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>
Share:
17,501
Gadgetster
Author by

Gadgetster

Updated on June 07, 2022

Comments

  • Gadgetster
    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:

    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!

  • Gadgetster
    Gadgetster about 10 years
    wow 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
    Sean about 10 years
    I 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 the var userid from a string to a int using parseInt(), and (3) need to check if not in array using !== -1 -> if($.inArray(userid, data) !== -1){
  • Gadgetster
    Gadgetster about 10 years
    alert($.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
    Gadgetster about 10 years
    I 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
    Sean about 10 years
    Sorry, 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
    Gadgetster about 10 years
    i 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
    Sean about 10 years
    Check 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
    Gadgetster about 10 years
    I 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
    Sean about 10 years
    You are missing 2 important steps/elements that I provided in both code samples - (1) var userid = parseInt($(this).attr('id').replace('user',''));. This takes your id="user#" and gets just the user number -#. (2) You are missing the value to search in the array -> if($.inArray(data) !== -1) should be if($.inArray(userid, data) !== -1)
  • Gadgetster
    Gadgetster about 10 years
    i 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
    Sean about 10 years
    What 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 the id in your class="status" div?