This is where we take everything we learned in Workshop 3 and push it up to the next level by consuming another RSS feed, this time on the client side with AJAX (XmlHttpRequest). (We're going to need to use the JavaScript SDK, and our local development environment for this one, too.) Okay, let's go!
For this workshop, we're going to create a module that displays the most recent sports headlines from AOL Sports.
First, we'll describe the module:
<h3>Description</h3>
<p class="description">The top five sports headlines from <a href="http://sports.aol.com" rel="proxy">AOL Sports</a>.</p>
<h3>Detail</h3>
<p class="detail">This module grabs the <a rel="proxy" href="http://xml.news.aol.com/aolnewsrss.xml?cid=1690&feedtype=manual"> AOL Sports RSS feed</a> via AJAX, parses it, and displays five headlines.</p>
Since we're getting headlines from the RSS feed, the markup for our module is pretty simple:
<div class="view top-sports-headlines-example">
<div class="head">
<h3>Top Sports Headlines</h3>
</div>
<div class="body">
<ul class="top-sports-headlines-list">
<li>Loading...</li>
</ul>
</div>
</div>
Now, we have to do the hard part and go get our headlines!
First, we need to create a JavaScript function that grabs our headlines and displays them. This is a slightly complicated, because XmlHttpRequest has security rules that only allow connections back to the original server that served the page. We'll get around that with our proxy server.
We want to create unique functions that aren't going to be replaced by someone else, so we'll start with this shell, which we'll call "top-sports-headlines.js" and place it in the same directory as the module HTML:
function topSportsHeadlines(instance, action) {
var success=function(xml) { };
var error=function(xml) { };
}
Before we go any further, we need to add a few things to our module so we can get some Ajax going. In the head of the module code, we add the following:
<script type="text/javascript" src="jssdk/lop.js"></script>
<script type="text/javascript" src="top-sports-headlines.js"></script>
The two jssdk files may be in different locations, depending on where you installed them when you set up your local development environment. Change the paths to them in the code accordingly.
We also need to make sure our JavaScript runs when the module is viewed, so we'll make the body tag look like this:
<body class="module" id="top-sports-headlines" onload="topSportsHeadlines();">
Now we need to write some JavaScript. Here goes:
We need to tell the SDK to use the Ajax stuff, and we also need to set up our success and error functions. We'll start with this:
function topSportsHeadlines() {
var headlineURL = "http://xml.news.aol.com/aolnewsrss.xml?cid=1690&feedtype=manual";
var success=function(xml) { }
var error=function(xml) { }
lop.Ajax.prototype.simpleGet(headlineURL,success,error,null);
}
This code won't actually display anything if we run it, but it will probably be the basis for almost any module you build with Ajax, so it's nice to see it this way. The lop.Ajax.prototype.simpleGet() is a library function in the SDK that simply gets XML at a URL, and calls a success or error callback.
We need to fill out our skeleton with some muscles. Here's our plan:
Find all the ul (list) elements in our module.
Of those, we only want to save the one that has a class="top-sports-headlines-list". If we don't find our ul, we can't continue, because we'll have nowhere to put our headlines. And here's the code that does that (additions in blue):
function topSportsHeadlines() {
var headlineURL = "http://xml.news.aol.com/aolnewsrss.xml?cid=1690&feedtype=manual";
var module=dojo.byId(instance);
if ( !module ) {
// This should only happen in standalone mode, so it's OK that we're only grabbing the first one.
var modules=dojo.html.getElementsByClass("top-sports-headlines");
for (var i=0;i<modules.length;i++ ) {
if (dojo.html.hasClass(modules[i],"view")){
module=modules[i];
break;
}
}
}
var list=dojo.html.getElementsByClass("top-sports-headlines-list",module)[0];
var success=function(xml) { };
var error=function(xml) { };
lop.Ajax.prototype.simpleGet(headlineURL,success,error,null);
}
Now that we have our ul, it's time to define our error and success conditions. Here's our plan for this part:
ul.And here's the code to do that (additions in blue):
function topSportsHeadlines(instance, action) {
var headlineURL = "http://xml.news.aol.com/aolnewsrss.xml?cid=1690&feedtype=manual";
var module=dojo.byId(instance);
if ( !module ) {
// This should only happen in standalone mode, so it's OK that we're only grabbing the first one.
var modules=dojo.html.getElementsByClass("top-sports-headlines");
for ( var i=0;i<modules.length;i++ ) {
if ( dojo.html.hasClass(modules[i],"view")) {
module=modules[i]; break; }
}
}
var list=dojo.html.getElementsByClass("top-sports-headlines-list",module)[0];
var success=function(xml) {
var dom=xml.responseXML;
var items =dom.getElementsByTagName("item");
for (var i=0;i<items.length;i++ ) {
var item=items[i];
var title=item.getElementsByTagName("title")[0].childNodes[0].nodeValue;
var link=item.getElementsByTagName("link")[0].childNodes[0].nodeValue;
output+="<li><a href='" + link + "'>" + title + "</a></li>";
}
list.innerHTML=output;
}
var error=function(xml) {
output = "<li class='error'>There was an error retrieving the headlines. <a href='javascript:topSportsHeadlines()'>Please try again</a>.</li>";
list.innerHTML=output;
}
lop.Ajax.prototype.simpleGet(headlineURL,success,error,null);
}
When the module is viewed on an AIM Page, it will first display "loading..." and then it will go out and grab the RSS feed. It will look something like this:
That's it? we've completed our RSS module with Ajax! We validated it with the Module Validator, and it reports no errors.
Our module id is: "top-sports-headlines," so to package it up for uploading, we create a zip file named "top-sports-headlines.zip," which contains a directory called "top-sports-headlines." That directory should contain a file called "index.html" which has the complete HTML of our module, and the top-sports-headlines.js file with our Ajax code. Here is the HTML file.
Now, we've got some more goodies for you in Workshop 5.
function topSportsHeadlines(instance, action) {
var headlineURL = "http://xml.news.aol.com/aolnewsrss.xml?cid=1690&feedtype=manual";
var module=dojo.byId(instance);
if ( !module ) {
// This should only happen in standalone mode, so
// it's OK that we're only grabbing the first one.
var modules=dojo.html.getElementsByClass("top-sports-headlines");
for ( var i=0;i<modules.length;i++ ) {
if ( dojo.html.hasClass(modules[i],"view")) {
module=modules[i];
break;
}
}
}
var list=dojo.html.getElementsByClass("top-sports-headlines-list",module)[0];
var success=function(xml) {
var dom=xml.responseXML;
var items=dom.getElementsByTagName("item");
for ( var i=0;i<items.length;i++ ) {
var item=items[i];
var title=item.getElementsByTagName("title")[0].childNodes[0].nodeValue;
var link=item.getElementsByTagName("link")[0].childNodes[0].nodeValue;
output+="<li><a href='" + link + "'>" + title + "</a></li>";
}
list.innerHTML=output;
}
var error=function(xml) {
output = "<li class='error'>There was an error retrieving the headlines. <a href='javascript:topSportsHeadlines()'> Please try again</a>.</li>";
list.innerHTML=output;
}
lop.Ajax.prototype.simpleGet(headlineURL,success,error,null);
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:pub="http://aimspace.com/modulet/xmlns">
<head profile="http://iamalpha.com/.developer/profile">
<title>Top Sports Headlines</title>
<link rel="stylesheet" type="text/css" id="manifest" href="http://iamalpha.com/.developer/css/manifest.css"/>
<script type="text/javascript" src="../../resource/jssdk/lop.js"></script>
<script type="text/javascript" src="top-sports-headlines.js"></script>
</head>
<body class="module" id="top-sports-headlines" onload="topSportsHeadlines()">
<h1>Top Sports Headlines: Version <span class="version">1.0</span></h1>
<h2>Edit Interface</h2>
<p>There is no edit interface for this module.</p>
<h2>View Interface</h2>
<div class="view top-sports-headlines">
<div class="head">
<h3>Top Sports Headlines</h3>
</div>
<div class="body">
<ul id="hlist" class="top-sports-headlines-list">
<li></li>
</ul>
</div>
</div>
<h3>Description</h3>
<p class="description">The top five sports headlines from <a href="http://sports.aol.com/">AOL Sports</a>.</p>
<h3>Detail</h3>
<p class="detail">This module grabs the <a rel="proxy" href="http://xml.news.aol.com/aolnewsrss.xml@cid=1690&feedtype=manual">AOL Sports RSS feed</a> via AJAX, parses it, and displays five headlines.</p>
<h3>Author Information</h3>
<ul>
<li class="author vcard"><a href="mailto:you@somedomain.com" class="email fn">Your Name</a> - <a href="http://somedomain.com" class="url">Homepage</a></li>
</ul>
</body>
</html>