Ajax Workshop 4: Live Data with JSON & Prototype.js
This workshop we will be building a live data viewer similar to that of Digg.com’s Digg Spy. We will be using the Prototype.js library as well as the Script.aculo.us library. This type of feature is great if you have a lot of user interaction with your site and want to see what is happening in real time. Let’s get started.
View the demo
First thing we need to do is get the XHTML and CSS out of the way, this is very straight forward but I will explain what everything does below.
The XHTML
<ul>
<li id="pl" class="tab" onclick="ld.playFunc(); this.style.color = 'black'; $('st').style.color = '#CCC';">Play</li>
<li id="st" class="tab" onclick="ld.stopFunc(); this.style.color = 'black'; $('pl').style.color = '#CCC';" style="margin-right:0; color:#CCCCCC">Stop</li>
</ul>
<div id="container">
<div class="hold" id="hold_0" style="border-top:1px solid #999"></div>
<div class="hold" id="hold_1"></div>
<div class="hold" id="hold_2"></div>
<div class="hold" id="hold_3"></div>
<div class="hold" id="hold_4"></div>
</div>The XHTML is pretty basic we start out with an unordered list for our controller buttons (play & stop), we also attach some events for usability as well as function calls onclick to our live data object. We then create a container that will hold our live data. Inside of the container we have 5 new divs that will be the temporary holders for the live data. We give each child div a separate ID, this is important as the live data object will populate the divs based on their ID.
The CSS
body {
font-family:Arial, Helvetica, sans-serif;
}
.hold {
font-size:12px;
color:#999999;
padding:10px;
border:1px solid #999;
border-top:0;
border-left:0;
border-right:0;
background: #F1FEFC;
}
a {
color:blue;
font-weight:bold;
text-decoration:none;
}
h1 {
font-size:24px;
letter-spacing:-1px;
}
ul {
margin:0;
padding:0;
margin-bottom:3px;
text-align:right;
}
ul li {
display:inline;
border:1px solid #999;
padding:4px;
border-bottom:0;
margin-right:5px;
text-align:center;
background:#F1FEFC;
font-size:10px;
}The CSS is straight forward as well, we add some styles here and there and set the unordered list’s display to inline so we can get the nice tab effect.
We should now have something that looks like the following:
Now let’s take a look at the JavaScript. We will start out by creating our liveData class using Prototype’s Class.create() function. We will then continue to build the class using JSON.
JavaScript: liveData Class
var liveData = Class.create();
liveData.prototype = {
data: [
// Dynamically generate on page load from server-side
{'id':0, 'name':'Article 1', 'desc':'This is article one...', 'url':'article1.html'},
{'id':1, 'name':'Article 2', 'desc':'This is article two...', 'url':'article2.html'},
{'id':2, 'name':'Article 3', 'desc':'This is article three...', 'url':'article3.html'},
{'id':3, 'name':'Article 4', 'desc':'This is article four...', 'url':'article4.html'},
{'id':4, 'name':'Article 5', 'desc':'This is article five...', 'url':'article5.html'}
],
pe: 0,
interval: 2,
status: 1,
initialize: function () {
this.fillHolder();
this.pe = new PeriodicalExecuter(this.getNewData.bind(this), this.interval);
},
fillHolder: function () {
this.data.each(function(item, index) {
var holder = 'hold_' + index;
if (index == 0) {
// EXPERIMENTAL ANIMATION
//Element.hide(holder);
//new Effect.Appear(holder);
new Effect.Highlight(holder);
}
$(holder).innerHTML = '<a href="' + item.url + '">' + item.name + '</a><br />' + item.desc;
});
},
getNewData: function () {
var showNewData = this.showNewData.bind(this);
var url = 'liveData.php';
var rand = Math.random(9999);
var pars = 'id=' + this.data.last().id + '&rand=' + rand;
var myAjax = new Ajax.Request( url, {method: 'get', parameters: pars, onComplete: showNewData} );
},
showNewData: function (originalRequest) {
this.data.unshift(eval('(' + originalRequest.responseText + ')'));
this.data.pop();
this.fillHolder();
},
playFunc: function () {
if (this.status == 0) {
this.pe = new PeriodicalExecuter(this.getNewData.bind(this), this.interval);
this.status = 1;
}
},
stopFunc: function () {
this.pe.stop();
this.status = 0;
}
};We first created our class then used the prototype to extend the class and add our properties and methods. The first property is data, data will be the actual data that is displayed in the live data viewer. For this demo we have an ID, name, description and URL, but you can have as many or as little fields as you like. We put in some dummy data for now but in a production enviroment you should populate this from your database.
Next we have three (3) more properties. pe: this is the PeriodicalExecuter, we set this so that we can access the same PeriodicalExecuter without creating a new one every time we play and stop the live data. interval: this is the interval in seconds that the live data updates from the serverside. status: the status is used to let us know whether the PeriodicalExecuter is live or not.
Now onto our methods. We start with the initialize function that is mandatory when using Prototype’s Class.create(). This is the constructor and will be called when the object in initialized hence the name. In this method we call another method in the class fillHolder which populates the live data holder divs and start the PeriodicalExecuter. You will notice that we used the bind function from prototype so that we can pass the object along with the method .
We now have the fillHolder method that populates the holder divs. We start by iterating through the data property filling the appropriate div with the appropriate data. You will notice we have a conditional statement that checks to see if the index is equal to zero. If it is we add a nice little highlight effect from the Script.aculo.us library.
Next is the getNewData method, in this method we create our Ajax object and send off for our new data. We cover using Prototype’s Ajax object more in depth in previous workshops.
Onto our next method showNewData. showNewData is called when the Ajax object has finished communicating with the server side and then adds a new record to the data property using the array unshift() function. We now have one extra row in our data property so we need to remove the last one, we do this by using the array function POP(). We then call the fillHolder method again to replace the holders with the new data from the server.
Next we have two (2) new methods, playFunc and stopFunc. These are pretty straight forward and either play the live data or stop the live data. In the playFunc we check to make sure that the movie isn’t already playing using a conditional statement checking to see if the status is already equal to one (1).
That’s it for the liveData class. Let’s take a look to see how we use it.
JavaScript: Using the liveData Class
var ld;
window.onload = function () {
ld = new liveData;
var tabs = document.getElementsByClassName('tab');
$('hold_3').style.opacity = 0.50;
$('hold_4').style.opacity = 0.25;
tabs.each(function (item, index) {
item.style.cursor = 'pointer';
item.onmouseover = function () {
this.style.background = '#fff';
this.style.borderBottom = '1px solid #999';
}
item.onmouseout = function () {
this.style.background = '#F1FEFC';
this.style.borderBottom = 0;
}
});
}First we create a global variable of ld (for liveData). We need to do this so we can access the object outside of the window.onload function. We then create a new event for window.onload so when the window is loaded we create a new instance of the liveData class. We then add some events for mouse overs and mouse outs on the control tabs and set the opacity of the second last and last div holder to 50% and 25% respectively.
All of the client side is now complete. Time to take a look at the serverside.
PHP: liveData.php
$id = $_GET['id'] + 1;
$content[0] = "{'id':$id, 'name':'Google', 'desc':'Google is the top search engine online.', 'url':'http://www.google.com'}";
$content[1] = "{'id':$id, 'name':'Yahoo!', 'desc':'Yahoo! is a great search engine and also a good place for developers.', 'url':'http://www.yahoo.com'}";
$content[2] = "{'id':$id, 'name':'Ajax Lessons', 'desc':'Resourse for Ajax lessons and tutorials.', 'url':'http://www.ajaxlessons.com'}";
$content[3] = "{'id':$id, 'name':'Ajaxian.com', 'desc':'Number one source online for up to the minute Ajax news.', 'url':'http://www.ajaxian.com'}";
$content[4] = "{'id':$id, 'name':'Digg.com', 'desc':'Great resource for user submitted news', 'url':'http://www.digg.com'}";
$content[5] = "{'id':$id, 'name':'Prototype.js', 'desc':'JavaScript library making Ajax simple.', 'url':'http://prototype.conio.net'}";
$content[6] = "{'id':$id, 'name':'SitePoint', 'desc':'Community surrounding web developers and designers.', 'url':'http://www.sitepoint.com'}";
$content[7] = "{'id':$id, 'name':'Script.aculo.us', 'desc':'DHTML library for making cool animations.', 'url':'http://script.aculo.us'}";
$content[8] = "{'id':$id, 'name':'IGN.com', 'desc':'Video game site that covers all popular platforms.', 'url':'http://www.ign.com'}";
$content[9] = "{'id':$id, 'name':'Gamespot', 'desc':'Video game site that covers all popular platforms', 'url':'http://www.gamespot.com'}";
print $content[rand(0,9)];The PHP is straight forward, we have set up an array with some dummy text then print out a random record. Ofcourse for live data you will want to make a call to the database to get the latest data or to an RSS feed. This is not limited to live data you could also use it to display archived data the choice is yours.
I hope you guys/girls enjoyed this workshop, I have another one on the way. If you have any questions, comments or need some support check out the Ajax Lessons Discussion Board.
View the demo
About this entry
You’re currently reading “Ajax Workshop 4: Live Data with JSON & Prototype.js,” an entry on Ajax Lessons

- 3.7.06 / 12pm

6 Comments
Jump to comment form | comments rss [?] | trackback uri [?]