1

Right now, every time a user logs in, all the posts made by that user will turn green, while all the offline users' posts are grey.

I want to add a link to a javascript function for when the div is green, and a different link for when it's grey. I did this in php no problem but I want it to work realtime just like the color change without a page refresh.

The html

<div class="main_ads status" id="user'.$user_id.'">post</div>

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[] = 'user'.$row['user_id'];  // this adds each online user id to the array         
    }
}
echo json_encode($array);

ajax code

$(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: '#40A547'}); 
                            } else{                                     // if not, set to offline
                                $(this).css({background: '#7f8c8d'});
                            }
                        });
                    } else {                                            // if no one is online, set all to offline
                        $('.status').css({background: '#7f8c8d'});
                    }           
                }
            });
        }, 2000);
    });

I tried to think of a way to do this and thought to assign a variable with a html tag that will be different for online and offline but wasn't sure how to call that variable from the ajax code into html.

All help is much appreciated!

Gadgetster
  • 473
  • 3
  • 12
  • 33

2 Answers2

2
  1. Do not add inline styles, use css classes.
  2. In case the request takes longer than 2 seconds, abort it!
  3. I suggest not using id's, mabye data-user or .user# as class

HTML

<div class="main_ads status" id="user1">post1</div>
...
<div class="main_ads status" id="user10">post10</div>

CSS

.online{
    background:red;
    padding:3px;
}

JQUERY

var global_ajax_request = null;
$(document).ready(function() {
    setInterval(function(){
        if (global_ajax_request){
            global_ajax_request.abort();
        }
        global_ajax_request = $.ajax({
            url: 'ajax.php',
            dataType: "json",
            type: 'GET',
            success: function(data) {
                $('.status').removeClass('online');
                for(var i in data){
                    $('#'+data[i]).addClass('online');
                }
            }
        });
    }, 2000);
});
$('.status').on('click',function(e){
    e.preventDefault();
    if ($(this).hasClass('online')){
        alert('function for ONLINE');
    }else{
        alert('function for OFFLINE');
    }
});

Explanations:

global_ajax_request holds the reference to a request. Just before launching a new one, kill the old one. (!) This will make the browser not listen for a response, but the server will continue to work.

Each time you get a response, clear the online class and add it only to the returned userId's. (This should be Optimized.)

The last bit $('.status').on(...) will be fired each time someone clicks on a div. Then inside you see if it's green (online) or not and launch the appropriate function.

Unamata Sanatarai
  • 6,475
  • 3
  • 29
  • 51
  • I am confused about your first point. And it's 2 seconds for testing only. It will be 15 seconds later. And can you explain what your code does? I can't see how to add a link. would 'online' class contain the link in it and it is add to the div? – Gadgetster Apr 06 '14 at 08:18
  • #1 try to avoid `.css('background...)`. #2 even if it's 15 seconds, it's, in my opinion, good practice to abort any previous requests, as they may still be pending. #3 sorry, missed the part about the links. I updated it. Is this what you were looking for? – Unamata Sanatarai Apr 06 '14 at 08:23
  • I did something similar to that and it worked as well! thank you for the help! – Gadgetster Apr 07 '14 at 04:42
2

You could make use of the wrapInner() property of jQuery. This could enclose the text place inside your div into <a></a> tags such as:

if($.inArray(userid, data) !== -1){  // if userid # in the returned data array set to online
  $(this).css({background: '#40A547'}); 
  //for the online users, you could fill in the javascript function
  $(this).wrapInner('<a href="javascript:void(0);" onclick="javascript:online_clicked();"></a>');
} else{                                     // if not, set to offline
  $(this).css({background: '#7f8c8d'});
   //over here write the link for offline users
   $(this).wrapInner("<a href='www.google.com'></a>");
}

Fiddle

AyB
  • 11,609
  • 4
  • 32
  • 47
  • that's more of what i want. Is there a way to wrap the div rather than just the text inside the div? I want the padding of the text to be link-able as well – Gadgetster Apr 07 '14 at 00:50
  • @Gadgetster For that simply use `.wrap()` in place of `.wrapInner()` – AyB Apr 07 '14 at 04:23