Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic score board using PHP, AJAX, JQUERY & JSON

Tags:

json

jquery

ajax

Basically I have created an online leaderboared here that returns the top 100 user scores

and if users hit refresh and the ranks have changed it will show new positions. What I would like to do is have the ranks updated without doing a page refresh, using AJAX, jQuery and JSON.

The leaderboard is populated via an associative sql query and stored in an sql variable, I have managed to get the output in JSON format seen here using

    //Shows user details and the current top 100 ranks
while ($row = mysql_fetch_assoc($result)) {

    print json_encode ($row);
  }

So far so good, using this animated sorting example from [Tinysort][3]

function sort() {
    var $Ul = $('ul#leaderboard');
    $Ul.css({position:'relative',height:$Ul.height(),display:'block'});
    var iLnH;
    var $Li = $('ul#leaderboard>li');
    $Li.each(function(i,el){
        var iY = $(el).position().top;
        $.data(el,'h',iY);
        if (i===1) iLnH = iY;
    });
    $Li.tsort('h1:eq(0)',{order:'desc'}).each(function(i,el){
        var $El = $(el);
        var iFr = $.data(el,'h');
        var iTo = i*iLnH;
        $El.css({position:'absolute',top:iFr}).animate({top:iTo},500);
    });
}

I believe I am most of the way there but I am getting stuck on the poll() function below

poll();

function poll() {

    $.ajax({
        url: 'http://test.bmx-tube.com/ajax.php', // needs to return a JSON array of items having the following properties: id, score, facebook_id, username
        dataType: 'json',
        success: function(o) {
            for(i=0;i<o.length;i++) {
                if ($('#row-'+o[i].player_id).length == 0) {
                    // this id doesn't exist, so add it to our list.
                    $("#leaderboard").append('<li><h1 style="display:inline" player_id="row-' + o[i].player_id + '">' + o[i].score + '</h1> <img style="height:50px" src="http://graph.facebook.com/' + o[i].facebook_id + '/picture"/> ' + o[i].name + '</li>');
                } else {
                    // this id does exist, so update 'score' count in the h1 tag in the list item.
                    $('#row-'+o[i].player_id).html(o[i].score);
                }
            }
            sort();
        },
    }); 

    // play it again, sam
    var t = setTimeout(poll,3000);
}

I have tried changing all the variables around but have had no luck so far.

Any help greatly appreciated

like image 381
user1903887 Avatar asked Jul 23 '26 19:07

user1903887


1 Answers

Well firstly your JSON string is invalid. Your server isn't actually returning an array of objects.

Are you using echo json_encode($yourArray); to create the JSON server side?

Here is an example of a proper array of objects as a JSON string:

{"array":[
     {"object":"1","description":"this is an object"},
     {"object":"2","description":"this is an object"},
     {"object":"3","description":"this is an object"}
]}

NB: You can validate JSON strings with JSONLint: http://jsonlint.com/

Also you can use firebug or chrome's inspector tools to see if the object is valid or not, and to view the JSON string being returned by your server in a more intuitive way.

As for accessing the objects once you have a valid object, you can use jQuery .each() to do this easily and elegantly.

For example:

$.ajax({
        url: 'http://test.bmx-tube.com/ajax.php',
        type: "get", cache:false,
        dataType: 'json',
        success: function(ranks) 
        {
            $(ranks).each(function(index, rank)
            {
                if($('#row-'+rank.player_id).length == 0) 
                {
                    // this id doesn't exist, so add it to our list.
                    $("#leaderboard").append('<li><h1 style="display:inline" id="row-' + rank.player_id + '">'+rank.score+'</h1> <img style="height:50px" src="http://graph.facebook.com/'+rank.facebook_id + '/picture"/> ' + rank.name + '</li>');
                } 
                else 
                {
                    // this id does exist, so update 'score' count in the h1 tag in the list item.
                    $('#row-'+rank.player_id).html(rank.score);
                }
            });
            //now sort
            sort();
        },
        error: function()
        {
            alert("Ajax error: could not access URL");
        }
    });

Some other things to note

Its a good idea to disable caching on data that changes regularly when using GET with AJAX. That is what the type: "get", cache:false, is doing above.


Let me know if you need any further help...this should point you in the right direction though.

Cheers, Oisin

--- Edit 1 ---

I realise now what you intended to do with player_id="row-'+rank.player_id+'". That should actually be id="row-'+rank.player_id+'"

I've modified the code above to reflect this.

jsFIddle

Here is a JSFiddle demonstrating how you might go about with what you're trying to do. I've simplified things by cutting out your sort function for now and just used a very simple sort instead. I've also broken up the generated HTML into section so you can style them individually and modify the data in a more structured way. http://jsfiddle.net/DigitalBiscuits/fKcKF/6/

NB: due to the way jsFiddle works I have had to generate a mock dataset and modify the AJAX function to load it. On your website you would of course be loading the JSON from your own server.


if this helps you please upvote. If it solves your problem please mark this answer as correct.

Good luck!

like image 164
OACDesigns Avatar answered Jul 26 '26 09:07

OACDesigns