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
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:
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:
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!