PhoneGap RSS Reader - Part 3

This post is more than 2 years old.

Welcome to my third entry for my (what was at first) simple PhoneGap RSS reader. If you haven't yet, please be sure to read part 1 and part 2 so you have some context about how this application works. In this part, I'm going to tackle two enhancements suggested to me by my readers:

  1. First - support rendering the entries if the user is offline.
  2. Second - clean up the UX a bit so that when a user views an entry, leaves, and then comes back to another entry, they don't see the old text there for a split second.

Let's tackle the offline question first. I spent some time thinking about this and tried a few things that didn't quite work out the way I wanted. The first thing I tried was checking navigator.onLine. (See this Stackoverflow entry for details.) This did not work well for me. When I switched my device to airplane mode it still reported me as online. I then looked into PhoneGap's Connection API. This kinda worked. It didn't seem to grok my Airplane mode at all. It certainly didn't report it as online (it returned a null actually) and I could have handled it, but I then had the issue of how I was going to handle coordinating the deviceready event along with the jQuery Mobile pageinit method.

Then I realized something. I already had an Ajax error handler. And it worked. That's obvious of course, but it occurred to me. Why not use this error handler? It would not only support offline mode, but any error on the remote server as well. At the end of the day, if I can't get the RSS feed, who cares if I'm offline or if the server is down. I could see caring, and if so, you would obviously want to use the PhoneGap Connection value, but I figured, why not go with the simple route.

As for storage - that turned out to be trivial - LocalStorage. Have you guys figured out yet that I really love HTML5 LocalStorage?

So, I decided to get rid of AjaxSetup. I only have one Ajax call in the entire application, so why not tie it to that call. So I switched from a $.get to a $.ajax:

$.ajax({ url:RSS, success:function(res,code) { entries = []; var xml = $(res); var items = xml.find("item"); $.each(items, function(i, v) { entry = { title:$(v).find("title").text(), link:$(v).find("link").text(), description:$.trim($(v).find("description").text()) }; entries.push(entry); }); //store entries localStorage["entries"] = JSON.stringify(entries); renderEntries(entries); }, error:function(jqXHR,status,error) { //try to use cache if(localStorage["entries"]) { $("#status").html("Using cached version..."); entries = JSON.parse(localStorage["entries"]) renderEntries(entries); } else { $("#status").html("Sorry, we are unable to get the RSS and there is no cache."); } } })

This is - for the most part, the same code as before, just using the core $.ajax method. You can see where the error function will look into LocalStorage for the cached copy, and where the success function always stores a copy. The renderEntries function is simply an abstracted out version of the display code:

function renderEntries(entries) { var s = ''; $.each(entries, function(i, v) { s += '<li><a href="#contentPage" class="contentLink" data-entryid="'+i+'">' + v.title + '</a></li>'; }); $("#linksList").html(s); $("#linksList").listview("refresh"); }

Woot. That works. Now for the next request. We want to ensure that users don't see the old content when loading in the RSS entry detail page. This turned out to be a bit weird. jQuery Mobile has logic to say, "Do this when a page is hiding, or before it hides", but for the life of me (and please correct me if I'm wrong) there doesn't seem to be a good way to get the page that is leaving. You get passed the page you are going to, but not the current page. I really feel like I'm missing something here, so please note this may get corrected later. For me though I simply added an event listener to the main page. It now sees if a previous page exists, and if so, clears out the text:

$("#mainPage").live("pagebeforeshow", function(event,data) { if(data.prevPage.length) { $("h1", data.prevPage).text(""); $("#entryText", data.prevPage).html(""); }; });

And that's it. I've included the entire JavaScript file below (the HTML hasn't changed from the previous entry) and a zip of the entire project may be downloaded for the low cost of free.

//EDIT THESE LINES //Title of the blog var TITLE = "ColdFusion Jedi"; //RSS url var RSS = "http://feedproxy.google.com/RaymondCamdensColdfusionBlog"; //Stores entries var entries = []; var selectedEntry = "";

//listen for detail links $(".contentLink").live("click", function() { selectedEntry = $(this).data("entryid"); });

function renderEntries(entries) { var s = ''; $.each(entries, function(i, v) { s += '<li><a href="#contentPage" class="contentLink" data-entryid="'+i+'">' + v.title + '</a></li>'; }); $("#linksList").html(s); $("#linksList").listview("refresh"); }

//Listen for main page $("#mainPage").live("pageinit", function() { //Set the title $("h1", this).text(TITLE);

$.ajax({
	url:RSS,
	success:function(res,code) {
		entries = [];
		var xml = $(res);
		var items = xml.find("item");
		$.each(items, function(i, v) {
			entry = { 
				title:$(v).find("title").text(), 
				link:$(v).find("link").text(), 
				description:$.trim($(v).find("description").text())
			};
			entries.push(entry);
		});
		//store entries
		localStorage["entries"] = JSON.stringify(entries);
		renderEntries(entries);
	},
	error:function(jqXHR,status,error) {
		//try to use cache
		if(localStorage["entries"]) {
			$("#status").html("Using cached version...");
			entries = JSON.parse(localStorage["entries"])
			renderEntries(entries);				
		} else {
			$("#status").html("Sorry, we are unable to get the RSS and there is no cache.");
		}
	}
});

});

$("#mainPage").live("pagebeforeshow", function(event,data) { if(data.prevPage.length) { $("h1", data.prevPage).text(""); $("#entryText", data.prevPage).html(""); }; });

//Listen for the content page to load $("#contentPage").live("pageshow", function(prepage) { //Set the title $("h1", this).text(entries[selectedEntry].title); var contentHTML = ""; contentHTML += entries[selectedEntry].description; contentHTML += '<p/><a href="'+entries[selectedEntry].link + '">Read Entry on Site</a>'; $("#entryText",this).html(contentHTML); });

Download attached file.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Raymond Camden posted on 1/25/2012 at 4:25 AM

By the way, I made one more small change. I'm loading jQuery 1.6.4 instead of 1.7. 1.7 isn't supported in jQuery Mobile yet.

Comment 2 by Ivan Ilijasic posted on 1/25/2012 at 4:40 AM

Hey Raymond. Nice work and useful articles. Local storage and PhoneGap - these are some of the things I want to read about.

I wanted to ask you, since you tested lot of Adobe mobile technologies, are you satisfied with jQuery Mobile performances.

Some things work better than in AIR but jQuery transitions take time. They are not instant, takes 1 second to load another page, item renderers work nice and some things look much easier to develop than in mobile AIR. Just my 2 cents.

Cheers,
Ivan

Comment 3 by Raymond Camden posted on 1/25/2012 at 9:10 AM

I know page transitions are something the JQM folks are working on improving. But for now, you can totally turn them off:

http://forta.com/blog/index...

Comment 4 by Johannes Wilm posted on 1/25/2012 at 10:18 AM

Hey! As far as I can tell this doesn't take care of pictures, right? I did follow your suggestions you posted as a comment on the second part. I still needed a todatauri plugin as the javascript implementation on android apparently doesn't have that builtin. It worked on small pictures, but not on larger ones. But even when I overrode the image size and had it all included in the html-stream,the android browser simply refused to show datauri images. S that was the end of that, I guess... Let me know if you attempt to fix this somehow.

Comment 5 by Raymond Camden posted on 1/25/2012 at 7:17 PM

@Johannes: You mean in terms of being offline? No - it would not handle that. I think it's ok not to as folks can still see the content.

Comment 6 by Niclas posted on 1/26/2012 at 7:04 PM

Hi Raymond

First af all I'm a newbie so my skills aren't that good at all.

I've dowloaded the attached file from above.
I've tried with several feeds, some works, the most of them doesn't. I'm not sure if the not are supported or not. But one thing make me very uncertain and that is why I got this messege "Sorry, we are unable to get the RSS and there is no cache" when I try with the feed you included in the file. (var RSS = "http://feedproxy.google.com...";)

Do you know why? At this moment I've only tried to run this on my PC /Win 7, browser Chrome) or do I HAVE to run it inside Phonegap?

Best regards Niclas

Comment 7 by Raymond Camden posted on 1/26/2012 at 7:08 PM

It _has_ to be via PhoneGap. Regular JS apps cannot make a cross domain request. Ie, a file on foo.com cannot load an XML feed from goo.com. There are ways around this (JSON/P, or uses your own server side code to proxy it), but for the most part, the answer is no. :)

Comment 8 by Niclas posted on 1/26/2012 at 7:20 PM

Hi Raymond

Thanks a lot. I've got an iPhone and an iPad but no Mac. I really have to get a Mac so I can try Phonegap :)

Do you have any ideas why http://blip.tv/nettuts/rss works? It just a feed I got online, it is not mine or anything.

//N

Comment 9 by Raymond Camden posted on 1/26/2012 at 7:28 PM

No idea. It should be impossible. :)

Comment 10 by Chad posted on 1/28/2012 at 2:50 AM

Hey again, you were so helpful in part 2 of course I had to come back for part 3!

Love the app so far but only one complaint. When reading an article (at least on android 4.0.3) and you hit the back button it closes the app vs returning to the home page.

http://wiki.phonegap.com/w/...

It wasn't too difficult to fix but I'm sure others will be looking for this at some point.

Also another thing I ran into was 4.0.3 has issues with phonegap and screen rotation. It pretty much kills the app. Had to modify the AndroidManifest.xml and force portrait to fix this.

<activity
android:label="@string/app_name"
android:name=".AppNameActivity" android:screenOrientation="portrait">

Otherwise its still awesome! v4 to tackle push/pull notifications?

Comment 11 by Raymond Camden posted on 1/28/2012 at 3:07 AM

Odd, the back button for me (Android 3.something) works ok, so maybe it's just 4.x. Ditto rotation.

Anyway... sorry to be dense, but what do you mean by push/pull notifications?

Comment 12 by Chad posted on 1/30/2012 at 6:19 PM

http://wiki.phonegap.com/w/...
and
http://developer.android.co...

Adding the notifications when the feed has been updated would make the app a bit more useful.

Comment 13 by Raymond Camden posted on 1/30/2012 at 7:59 PM

So for that, you need something that runs in the background. I know apps don't always close when you - well, close them - so it's possible you can "hope" for that. I don't believe, stress, believe, you can set up a PG app so that it can notice something even when not running.

Comment 14 by Chad posted on 1/30/2012 at 8:41 PM

ahh, touche! it'd be unrealistic to expect something like that out of phonegap :-P but I did find this gem
https://github.com/saileshm...

Also, I thought I had the back button issue resolved but apparently I made it worse for some users :-\

http://stackoverflow.com/qu...

It actually creates errors for me so I wasn't able to use this method to "fix" it. Thoughts?

Comment 15 by Raymond Camden posted on 1/30/2012 at 9:05 PM

1) My understanding (and again, let me stress I'm mostly talking out my rear here), is that this plugin too will require the app to actually be run by the user first. It's nice like the Twitter app, for example, which will run after you reboot the phone.

2) I'm ashamed to say it, but I didn't know navigator.app.* existed. I just now asked on the forums where this is documented.

Comment 16 by hary posted on 2/14/2012 at 3:51 PM

Hi Raymond,
Thanks for this code.
I tried it on a Galaxy S2 and the scrolling "jumps" a little bit, it's not smooth, do you also have the same problem ? Do you know where it could come from ?
Thanks,
Hary

Comment 17 by Raymond Camden posted on 2/14/2012 at 6:57 PM

Hmmmm, no, I haven't seen that. I know that on Android, sometimes page transitions can be a bit icky. They are working on fixing that asap.

Comment 18 by Arihant posted on 2/14/2012 at 7:29 PM

Hey Any ideas why i am unable to images & the full content in the app?

Here's my feed url
http://feeds.feedburner.com...

I am using wordpress on my original site. Any ideas on how to fix this?

Comment 19 by Raymond Camden posted on 2/14/2012 at 9:04 PM

What images? What content? You said full content, right? So I assume the titles work, but when you click, you don't see the entry, is that right?

Comment 20 by Arihant posted on 2/16/2012 at 10:08 AM

I am sorry for the confusion.

Your feed looks like this
http://feeds.feedburner.com...

And mine looks like this
http://feeds.feedburner.com...

I have enabled full feeds but when you view the xml version only the start description shows up with no image.

I am asking if the app can be modified to read the hidden <[CDATA thing?
OR
How do i optimize my feed so that it shows the complete feed with images.

Any Ideas?

Comment 21 by Raymond Camden posted on 2/16/2012 at 8:01 PM

When I view source on your feed, I see HTML, not XML.

Comment 22 by Stefan posted on 2/16/2012 at 9:01 PM

i have the same problem. i want to read out an <item> with a field named <content-encoded> that includes the content in a <![CDATA field. ... this code:

entry = { title:$(v).find("title").text(), link:$(v).find("link").text(), description:$.trim($(v).find("content:encoded").text())

doesnt work :(

best regards
stefan

Comment 23 by Raymond Camden posted on 2/16/2012 at 9:07 PM

Oh, I ran into this before. Let me whip up a quick demo.

Comment 24 by Raymond Camden posted on 2/16/2012 at 9:18 PM

Ok, for me, .text works perfectly fine. Whipping up a quick blog demo and will post the link.

Comment 25 by Stefan posted on 2/16/2012 at 9:24 PM

you mean .text() works with content-encoded?

my rss feed looks like this:

<item>
<title>MT...</title>
<pubDate>Thu, 09 Feb 2012 13:24:05 +0100</pubDate>
<link>https://...</link>
<guid>https://...</guid>
<content:encoded><![CDATA[Fachbereich:]]></content:encoded>
</item>

and i want to read out the line with content-encoded?!

Comment 26 by Raymond Camden posted on 2/16/2012 at 9:30 PM

Quick example code for you -

http://www.raymondcamden.co...

Comment 27 by Raymond Camden posted on 2/16/2012 at 9:30 PM

Ah, you didn't say that (actually, you probably did, and I missed it), I thought the issue was ONLY CDATA. Let me update my example.

Comment 28 by Raymond Camden posted on 2/16/2012 at 9:39 PM

Ok, I knew I remembered this. See:

https://plus.google.com/115...

and specifically:

http://www.steveworkman.com...

Comment 29 by Vince posted on 2/20/2012 at 7:58 AM

Hi, this code is working fine on Android 2.3. But on Android 2.2, the only field properly displayed from the feed is PubDate :
pubDate: $(v).find("pubDate").text()

Other fields (title, description) are ignored and not displayed. Any idea of a workaround on Android 2.2?

Comment 30 by Raymond Camden posted on 2/20/2012 at 6:45 PM

All I can suggest is some debugging. If you console.log the values, what are you seeing.

Comment 31 by Jesse posted on 2/21/2012 at 9:12 PM

Awesome tutorials, all 3. If you're looking for something to add in case there's a part 4, consider adding multiple feeds with a feed menu as the front page. Such as "view news from source 1" and "view news from source 2."

I've tried to set a new main page and set load a url into the RSS variable based on which link the user clicks, but I'm obviously borking it somewhere, so now I'm selfishly asking for help by suggesting it as a blog post :)

Either way, thanks for the tips so far!

Comment 32 by Vince posted on 2/22/2012 at 12:12 AM

At this point, debugging is showing that .ajax() is returning an [Object Element] on Android 2.3 and a [HTML Element] on Android 2.2, with the very same code. On Anroid 2.2, most of the elements in the result are empty (except PubDate), and I didn't manage to understand why.

I ended up using Google Feed API, which is much faster to execute, really easy to use and more reliable across platforms. The only drawback is that if the feed contains HTML, all "class" and "id" properties are removed. Here is the code to insert in your JS file, instead of your $.ajax() call:

var feed = new google.feeds.Feed("http//insert_your_feed_URL_here");
feed.setNumEntries(10);
feed.setResultFormat(google.feeds.Feed.JSON);

feed.load(function(result) {
if (!result.error) {
var entries = [];
for (var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
// Do whatever you want with each entry
entries.push(entry);
}
localStorage["entries"] = JSON.stringify(entries);
} else {
// If nos results in the feed
}
});

and add this in index.html:

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("feeds", "1");
</script>

To get the "class" and "id" properties back, I tried switching to a mixed result (JSON + XML) using "google.feeds.Feed.MIXED_FORMAT" parameter. The idea is to set entry.content from JSON with the value of <content:encoded> from the XML part of the result, as XML stores the full HTML without any cleanup.

I tried adding the 2 following lines in the FOR loop above:

entry.content = result.xmlDocument.getElementsByTagName('item')[i].getElementsByTagName("content:encoded")[0].firstChild.nodeValue; // Get <content:encoded> content and replace entry.content with full HTML of the item
entry.xmlNode = null; // To prevent a circular JSON Object

But it throws an error. It seems that <content:encoded> is not found. Console log shows: "Uncaught TypeError: Cannot read property 'firstChild' of undefined"

If somebody finds a way to make this work, it would be fantastic. For the moment, I stick with this solution, as it gives really good results with both Android 2.2 and 2.3. Moreover, response time is much better (maybe my custom server providing the feed is not that fast).

@Raymond: Feel free to use this code for a Part 4 ;) Parts 1,2 and 3 helped me a lot to understand how to parse a feed and to use the results. Thanks!

Comment 33 by Raymond Camden posted on 2/22/2012 at 6:15 PM

@Jesse: It won't be available terribly soon, but I'm building something like this for my jQuery Mobile book. In fact, it's pretty much _exactly_ that. Technically you should buy the book, but all the code will be available via Github too.

@Vince: Didn't know about the Google Feed API. It looks like your getting JSON back - that's sweet. All things being considered, you almost _always_ want to work with JSON, not XML.

Comment 34 by Peter posted on 2/25/2012 at 5:17 PM

Hi,

It has been driving my crazy for 3 days and I need to express it here :D So your code works perfectly side alone. However, when I try to link it from another html file, it seems not to work. Meant that I already have my index.html, and your code is feed.html, I try to call feed.html in the list in index.html as below:

<ul data-role="listview" data-inset="true">
<li><a href="feed.html"><img src="images/feed.png" width="25" height="22" class="ui-li-icon" title="Feed">Feed</a></li>

When the link is triggered, it shows only the head and footer. Not the content at all.

Do you have any ideas on this issue?

Comment 35 by Peter posted on 2/25/2012 at 5:25 PM

Hi again,

For the comment above, I have found a way to work around it.

The main.js needs to be included in the index.html not feed.html in order to make it work. I found an useful post that said jquery will create another 'blank' page with the used js and css in its parent.

It leads to another issue that, reanderentry function will not work to create a viewable frame for each entry.

Sorry to ask again, but how do you think about this? :)

Comment 36 by Ivan Ilijasic posted on 2/25/2012 at 5:34 PM

Peter,

try using rel="external" on your link

Comment 37 by Peter posted on 2/25/2012 at 6:41 PM

@Ivan,

Thank for your comment, that works! Also found another way to do it is to disable ajax by data-ajax="false" :)

Comment 38 by Raymond Camden posted on 2/25/2012 at 9:19 PM

While that works, I'd do what you did first - include the JS code in the first page. Unlike a "web" JQM site, your PhoneGap apps always start off with a root URL.

Comment 39 by Mike posted on 3/12/2012 at 12:58 AM

Hey Ray,
first off, this is awesome. Thanks for posting the RSS series.

Here's the question. I'm looking to present each RSS feed entry in its own container. Much like a pinterest board.
Second, i would also like to include several RSS Feeds under their own tab. How do i do that.

FYI> I am mashing the Foundation HTML5 Responsive Framework with your RSS JQuery Mobile framework. So far so good, just looking for a bit more adaptation.

Thanks a million again. Mike

Comment 40 by Raymond Camden posted on 3/12/2012 at 1:55 AM

The first question is easier to answer. Instead of a UL with LIs for each entry, just use <p>entry</p> for each one. Or use a <div> that you style whatever way you want.

Tabs or another issue though. I haven't found a good "tab" solution for mobile. The other issue too is size. What do you o when you have 20 feeds? You don't want 20 tabs at the bottom.

Comment 41 by Mike posted on 3/12/2012 at 2:15 AM

Here's my HTML markup. within the body tag. As of now, all the RSS entries pull in as a list. Can you explain the <p>entry</p> so it works dynamically? Again, thanks.

<!-- Panel -->
<div class="row">
<div class="twelve columns">
<div class="panel">

<!-- RSS Feed -->
<div data-role="content">
<div id="status"></div>

<ul id="linksList" data-role="listview" data-inset="true" data-split-icon="gear" data-split-theme="d">
</div>
<!-- RSS Feed -->

</div>
</div>
</div>

Comment 42 by Raymond Camden posted on 3/12/2012 at 2:18 AM

Well, instead of

s += '<li><a href="#contentPage" class="contentLink" data-entryid="'+i+'">' + v.title + '</a></li>';

You would change the li to p. And instead of the ul id="linklist", you can change it to a simple div with an ID of whatever you want. Then you inject it with

$("#someid").html(s)

Comment 43 by Mike posted on 3/12/2012 at 2:22 AM

i should clarify. There are only 5 or 6 feeds. Each with about 20 posts displayed at a time. The feeds are randomly updated throughout the day.

oh, one more thing. How would one display an img within the #mainpage list?

Also, the Foundation Framework works really well for tabs. Check it out.
http://foundation.zurb.com/

Comment 44 by Raymond Camden posted on 3/12/2012 at 2:27 AM

re:pictures - This was discussed in the comments in part 2:

http://www.raymondcamden.co...

Comment 45 by Mike posted on 3/12/2012 at 2:39 AM

Like This?

main.js >

$(".contentLink").live("click", function() {
selectedEntry = $(this).data("entryid");
});

function renderEntries(entries) {
var s = '';
$.each(entries, function(i, v) {
s += '<p><a href="#contentPage" class="contentLink" data-entryid="'+i+'">' + v.title + '</a></p>';
});
$("#pinBoard").html(s)
$("#pinBoard").listview("refresh");
}

html >

<!-- Panel -->
<div class="row">
<div class="twelve columns">
<div class="panel">

<!-- RSS Feed -->
<div data-role="content">
<div id="status"></div>
<div id="pinBoard"></div>
<!-- RSS Feed -->

</div>
</div>
</div>
<!-- Panel -->

Comment 46 by Raymond Camden posted on 3/12/2012 at 2:53 AM

Yep, but get rid of this:

$("#pinBoard").listview("refresh");

That tells jQuery Mobile to refresh a list view, which you don't have anymore.

Comment 47 by Mike posted on 3/12/2012 at 6:03 AM

Groovy. Thanks Raymond.

Comment 48 by Joshua posted on 3/13/2012 at 3:58 PM

Great tutorials, I've been looking for exactly this for quite awhile. However I'm working on a project that breaks for some reason when I add jQuery Mobile. Would it be possible to implement this without jQuery Mobile?

Comment 49 by Raymond Camden posted on 3/13/2012 at 5:49 PM

Absolutely. All jQuery Mobile does is make crap pretty. I don't mean that to belittle JQM, I love it, but at the end of the day, it's role is to help design the mobile friendly site. It's not required at all.

Comment 50 by Joshua posted on 3/14/2012 at 3:04 AM

Raymond, thanks for the reply. I tried removing jQuery Mobile from your example and it stops working, is there something that I'm missing?

Comment 51 by Raymond Camden posted on 3/14/2012 at 5:03 AM

Well, my code makes use of JQM to render the entries. You would need to modify that. You asked if this could be done w/o JQM, and of course, it can, but you can't just remove the library. You would need to modify some of the code too.

Comment 52 by Joshua posted on 3/14/2012 at 9:26 AM

Thanks again for the reply. I'll try to figure it out.

Comment 53 by Ihsan Canakoglu posted on 3/21/2012 at 6:10 PM

Hi Raymond,
First of all, this is awesome. Thanks for posting the RSS series.
I am newbee of jquery. I want to use your code in my application in that such a way:
I wrote an application using phonegap wizard. I want to make a link to your code via a button click such as:
<li><a href="#api-rss">RSS Feed</a></li>
When i copy and paste your code in my div where id's is "api-rss", the code doesn't work because your code include "pageinit" function. How can i adapt your code into a div section? Please help me.
Best regards.
PS: Sorry my bad English, I hope you understand me.

Comment 54 by Raymond Camden posted on 3/22/2012 at 4:31 PM

The pageinit event is used by jQuery Mobile. I have no idea what framework, if any, your PhoneGap wizard uses, but if it isn't including it, then it won't work.

To be clear, jQuery Mobile is NOT required for this type of app. I used it to handle the display. You could use my logic in a non-jQuery Mobile app. The changes for that would be a bit too much for the comments section though.

Comment 55 by jason sovick posted on 4/6/2012 at 9:33 AM

Fantastic rss reader! Thank you so much.

When I try to use jquery mobile's theme roller with your page the theme does not work and the page instead just uses the stock themes that come with jquery mobile. Any advice on fixing that?

Comment 56 by Raymond Camden posted on 4/6/2012 at 4:53 PM

Did you download the right bits from themeroller? Can you share some of your code (via pastebin)?

Comment 57 by Raymond Camden posted on 4/6/2012 at 8:50 PM

Jason, I deleted your comments. All you need to do is post the URL, not any HTML.

Comment 58 by jason sovick posted on 4/6/2012 at 8:51 PM

http://pastebin.com/raw.php...

Try that link, sorry.

Comment 59 by Raymond Camden posted on 4/7/2012 at 12:28 AM

Looks reasonable to me. Best I can suggest is double checking which swatch you modified and ensure you are using it. You can also open your stuff up in Chrome and use DevTools to inspect the DOM.

Comment 60 by Dennis posted on 4/7/2012 at 12:54 AM

Hey Raymond,

I want to make a app who can read 2 RSS feeds.

This is my first RSS feed:

http://www.hapdedag.nl/dagh...

It is a newsfeed who displays all the news correctly with your RSS reader.

Secondly i got a Food Feed:

http://www.hapdedag.nl/exte...

I want to display the restaurant and if people click on it they see the dish of the day and some more information.

How do i get these 2 RSS Feeds working???
The first one, the news feed is working but I do not know how to fix the other RSS Feed correctly???

Comment 61 by Raymond Camden posted on 4/7/2012 at 1:23 AM

I can think of a few different ways of doing it.

One would be to simply have your app start with a list of two items - one for RSS feed one, the other for the second.

Clicking that leads to the list of entries just for that feed.

Another way would be to get the RSS feeds for both and merge them together. That would require a bit more work.

Comment 62 by Dennis posted on 4/7/2012 at 1:27 AM

Yeah i want to make it simple.

But what is the best way to do it??
Make 2 JS files? Or 1 JS file with more functions??

Comment 63 by Raymond Camden posted on 4/7/2012 at 1:28 AM

There is no reason to add additional JS file. You can add a new html page to show your 2 rss feeds and then have them link to the page that will show the proper detail.

Comment 64 by Dennis posted on 4/7/2012 at 1:33 AM

I know! I got a second HTML file but the 2 RSS files are totaly different.

Do i need to copy and rename all the variables and functions or can I skip some??

Comment 65 by Raymond Camden posted on 4/7/2012 at 1:35 AM

Um well give it a shot man. At this point I've described the process in general. You need to take a stab at the work yourself.

Comment 66 by Dennis posted on 4/7/2012 at 7:42 PM

Got it working!

But i got only 1 problem.

It is a app for a meal of the day.

Now the app shows alle the meals from the whole week.

How do i fix this?

Looks at the feed:

http://www.hapdedag.nl/exte...

Comment 67 by Raymond Camden posted on 4/7/2012 at 7:44 PM

You can write some code to compare the data in the XML to the current day. Do some quick searching for JavaScript Date functions. It should be easy.

Comment 68 by Dennis posted on 4/7/2012 at 7:51 PM

Hmmm... i am a beginner in javascript.
I need the getDate() function and compare with <day>7</day> in XML...

Comment 69 by Dennis posted on 4/7/2012 at 9:22 PM

function renderfoodEntries(foodentries) {
var s = '';
var d = new Date();

if(d.getDate == v.day){

$.each(foodentries, function(i, v) {
s += '<li><a href="#contentfoodPage" class="contentfoodLink" data-entryfoodid="'+i+'">' + v.restaurant + '</a></li>';
});
$("#foodList").html(s);
$("#foodList").listview("refresh");
}
}

Something like this???

Comment 70 by Raymond Camden posted on 4/7/2012 at 10:10 PM

Err, almost. You want the date comparison INSIDE the each loop, not outside it. Also, getDate is a method, so you would have getDate().

Comment 71 by Dennis posted on 4/9/2012 at 12:32 PM

This function also not works:

function renderfoodEntries(foodentries) {
var s = '';
var d = new Date();
var n = d.getDate();

$.each(foodentries, function(i, v) {
if(n == v.day){
s += '<li><a href="#contentfoodPage" class="contentfoodLink" data-entryfoodid="'+i+'">' + v.restaurant + '</a></li>';
}
});
$("#foodList").html(s);
$("#foodList").listview("refresh");
}

Do I need to put more into my JS???

Comment 72 by Raymond Camden posted on 4/9/2012 at 4:30 PM

If, inside your loop, you console.log both n and v.day, what do you see?

Comment 73 by Dennis posted on 4/9/2012 at 8:28 PM

As I said I am a beginner in Javascript how do i console.log n and v?? console.log(v)???

Comment 74 by Raymond Camden posted on 4/9/2012 at 8:31 PM

In webkit enabled browsers and Firefox+Firebug, you can use console.log("...") to send messages to the console. Lots of examples here:

https://www.google.com/sear...

Comment 75 by Dennis posted on 4/12/2012 at 1:18 AM

Okay I know Firebug or the inspector from Google Chrome but not what line i have to put into the loop.

$.each(foodentries, function(i, v) {

Comment 76 by Raymond Camden posted on 4/12/2012 at 1:25 AM

I'm not quite sure what you mean. As I said, you want to use console to log the value of n, which is the date, and v.day. Compare them.

Comment 77 by Chuba Okanume posted on 4/14/2012 at 5:21 PM

A Phonegap and Jquery mobile application. The Background/splash image takes too long to transit to the main application and all html,css, JavaScript are packaged with the app. Any solution to reduce the splash screen to about 4 seconds before it transit to the main page?

Comment 78 by Raymond Camden posted on 4/14/2012 at 5:23 PM

"to about 4 seconds" - how long are you seeing? I only see a splash screen of a maybe 1-2 seconds.

Comment 79 by Chuba Okanume posted on 4/14/2012 at 6:26 PM

the time varies sometimes over 20seconds , i dont know if it depends on the network, bt like i said previously all assets a loaded in the app

Comment 80 by Chuba Okanume posted on 4/14/2012 at 6:31 PM

Please any solution to this problem?

Comment 81 by Raymond Camden posted on 4/14/2012 at 6:36 PM

Ohhhh - so your issue is possibly with the amount of time it takes to get and parse the RSS. So you are seeing a loaded page, but with no content, while it gets the RSS. True?

Comment 82 by Raymond Camden posted on 4/14/2012 at 6:37 PM

In regards to your last comment Chuba, I respond when I can. It is Saturday so may get not quick responses.

Comment 83 by Chuba Okanume posted on 4/14/2012 at 6:51 PM

Thanks for the reply. its Json. am seeing the splash screen for too long Before the main page loads even wen it fetches nothing from the internet

Comment 84 by Raymond Camden posted on 4/14/2012 at 6:54 PM

So wait - if you try a new PhoneGap project with no code and just simple html, like <h1>Hello</h1>, are you seeing a long amount of time for _that_ to render?

Comment 85 by Chuba Okanume posted on 4/14/2012 at 7:25 PM

its faster

Comment 86 by Raymond Camden posted on 4/14/2012 at 7:27 PM

So yeah then - I think your issue is the network call to get and load the RSS. So maybe the solution is to make it more obvious that it is loading crap when the page is shown?

Comment 87 by Chuba Okanume posted on 4/14/2012 at 8:11 PM

wow does it have to take that long to load files that is available in the deployed app already? ..cuz it doesnt connect to the internet

Comment 88 by Raymond Camden posted on 4/14/2012 at 8:48 PM

Err, well now wait. As you said, when you did a simple example with no remote calls, it loaded faster. Right? When you use my code, which has to use the network to fetch the RSS, it was slower.

That is -expected-.

What may be the issue though is that the app is not being vocal about what is doing when it loads up. We could improve that.

I can say in my testing it ran fast, but obviously, it depends on the RSS feed you are trying to load, network conditions, etc.

Any app that needs the network for it's data is going to have that "problem" - there isn't much you can do about it. (Outside of what I said above - ensuring there is good user feedback and you can employ caching too).

Comment 89 by Chuba Okanume posted on 4/14/2012 at 9:59 PM

k Thanks appreciate

Comment 90 by Grimm posted on 4/24/2012 at 5:23 PM

@STEFAN:

You need only this:

content:$(v).find("[nodeName='content:encoded']").text()

Comment 91 by Grimm posted on 4/24/2012 at 5:25 PM

But what i am not understand is why all my <p> Tags do nothing in my Application when i get the full Post via content:$(v).find("[nodeName='content:encoded']").text()

Comment 92 by Grimm posted on 4/27/2012 at 3:52 PM

Nice, now i got everthing working quite well.

Only one Question:
How can i put $.mobile.pageLoading(); and $.mobile.pageLoading( true );
into this script ?

Thanks.

Comment 93 by Raymond Camden posted on 4/27/2012 at 6:05 PM

Um... put it in? Just do it. :) Maybe you need to clarify more what you mean.

Comment 94 by Jroen posted on 5/5/2012 at 5:24 PM

Hey Raymond! I've been using your tutorial for a phonegap app I'm building and it's extremely helpful. Although I already have written android apps in Java, apparently some employers want experience with Phonegap. I've been using your tuts to hop on this bandwagon and with your help I'm almost there.

Cheers!

Comment 95 by Jroen posted on 5/5/2012 at 5:37 PM

I see you have gravatars enabled. Hi there!

Comment 96 by Raymond Camden posted on 5/5/2012 at 5:47 PM

Glad you like them. If you have any suggestions for other tutorials, let me know.

Comment 97 by Grimm posted on 5/5/2012 at 5:55 PM

Hello Raymond,

because of my last question.
All what i want to do is to add a loading cycle for the time the rss news will be synct.
I tryed a lot right now with $.mobile.pageLoading(); and $.mobile.pageLoading( true );
but with no results :(

Would be very nice if you can give me a tip :)

Comment 98 by Raymond Camden posted on 5/5/2012 at 6:25 PM

I'd need to see a bit of the code. Basically, you would call pageLoading _before_ the get() call and clear it _after_ it gets loaded.

Comment 99 by Jroen posted on 5/7/2012 at 1:04 AM

Hey Raymond,

Although I'm getting further and further with my app, it doesn't function properly when I click a feeditem. It loads mainPage but it doesn't show the feeditem or comes up with gibberish.

I've followed your tutorial step by step (part 1- 3) but I can't find out what I'm doing wrong. If I set up the app with the quickstart guide from phonegap and use your tutorial should it just 'work' or am I still missing something? Could I send you my eclipse project or is that too much to ask?

Cheers!

Comment 100 by Raymond Camden posted on 5/7/2012 at 1:20 AM

Could be anything. But sure - go ahead and send your project, I'll try importing it. No promises on how quickly.

Comment 101 by Jroen posted on 5/7/2012 at 1:40 AM

Raymond,

nevermind haha. I accidentally added the contentPage div two times to index.html. It loads the feeditem perfect but loads a blank contentPage immediately after it has been loaded.

Above comment can be removed if you want =)

Cheers!

Comment 102 by Raymond Camden posted on 5/7/2012 at 2:34 PM

I like leaving mistakes like that around - you won't be the first to make it. :)

Comment 103 by Jroen posted on 5/7/2012 at 6:07 PM

Hey Ramond,

The next thing I want to do is to show a twitterfeed in my app. I guess I can use this script pretty much in the same way for this, amiright?

I´ll be using this (for example) http://search.twitter.com/s...

Comment 104 by Raymond Camden posted on 5/7/2012 at 6:12 PM

Sure yeah - Twitter has a RSS format. If I'm remembering wrong, then you just have to adjust for the different XML.

Comment 105 by G-Man posted on 5/15/2012 at 8:37 AM

What an awesome resource! Thanks so much for posting this.

For my app, I tweaked the code in the main.js file to allow the "Read Entry on Site" to use the Childbrowser plugin in PhoneGap so I can view my blog without launching the web browser, plus I'm stuck using the WebView preference for an iFrame on one of my pages to keep it from wigging out. Since WebView is turned on, sending links to the web browser has not been possible... or at least I don't know how to make it happen. (Rookie at Javascript but learning.)

Anyway, here's my code for the childBrowser plugin:

contentHTML += '<p/><a href="#" onclick=window.plugins.childBrowser.showWebPage("'+entries[selectedEntry].link + '")>Read Entry on Site</a>';

I would like to use the Childbrowser plugin for other links that show up in my feed. Can you tell me how to make this happen?

Thanks in advance - G

Comment 106 by Raymond Camden posted on 5/15/2012 at 3:27 PM

You will want to ensure you trap any click events in the list of feed data. That is possible via jQuery (let me know if you need help with that).

Comment 107 by Alex Meers posted on 5/17/2012 at 10:37 PM

Let me start by saying that this tutorial has been great. It's exactly what I've been looking for to complete an app.

There is one interesting problem that I have. Peter in one of the earlier comments said that he was having trouble putting the feed on a different page than index.html. I put the main.js reference in my index file and the feed appears on the page (latest.html), but the links don't do anything when they are clicked.

I tried adding the rel="external" based on another comment, but that didn't work either. Do you have any insight into this?

Comment 108 by Raymond Camden posted on 5/18/2012 at 4:57 PM

By links do you mean the titles or do you mean the "Read Entry on Site" link?

Comment 109 by Alex Meers posted on 5/21/2012 at 5:35 PM

Whenever I click the titles. It will light up but then it won't go anywhere. I put a console.log into the script to figure out if it fired. It knows when it's clicked but won't open the page with the text and the link that says "Read Entry on Page".

Comment 110 by Raymond Camden posted on 5/21/2012 at 6:35 PM

Not sure then- can you post your code to pastebin please?

Comment 111 by Alex Meers posted on 5/21/2012 at 8:42 PM

I actually finally diagnosed the problem. It's the data-role="pages" attribute. I tried it on my subpage without referencing your code and that doesn't work either, so that would explain why nothing popped up. I'm going to work with this today.

It's not your code -- it's my own lack of knowledge with JQuery and PhoneGap.

Comment 112 by Raymond Camden posted on 5/21/2012 at 8:43 PM

Ok cool- just glad you got things working.

Comment 113 by G-Man posted on 5/23/2012 at 1:55 AM

I do need help. This is in reference to my post on 05-14-2012 at 11:37 PM. I replied via email, but don't think that worked.

My content is coming from blogger and using feed burner to convert the RSS to RSS2. When my feed comes to my app, any text or pictures that have links tied to them open up in WebView on my iOS device and I don't have a header with a back button to get back to the previous screen. I have to run the app with WebView enabled as I have an iFrame on one of my #pages that launches Safari when the app loads and enabling WebView is the only way I can prevent that from happening.

Here's my feed address: http://feeds.feedburner.com... so you can test.

All my code is on GitHub at https://github.com/jjgleim/....

Comment 114 by A-z posted on 5/23/2012 at 1:01 PM

Hello Raymond,

first of all, thanks a lot for the tutorial, it was really a big help!
I am trying to get the <media:thumbnail> from my RSS-Feed in the App, but unfortunately none of my pitifully attempts has been successful :/
Could you give me some hint how this could work, please?

Thanks a lot in advance!

Comment 115 by Raymond Camden posted on 5/23/2012 at 6:14 PM

@G-Man: I think I saw your email - I just haven't been able to go through my queue. Hopefully another person can possibly help out too since it is on Github. I'll try if I can get the time - just not sure I will soon.

@A-Z: You may need to ensure your JS code handles it right - maybe:

title:$(v).find("media:thumbnail").text(),

but I don't know if .text() is right for you - if that XML element has subkeys you will need to use a different way to get to it.

Comment 116 by A-z posted on 5/23/2012 at 7:17 PM

Hello Raymond, and thank you for your rapid reply!
The xml is simple, looks like this:
<item>
<title> </title>
<link> </link>
<description> </description>
<pubDate> </pubDate>
<media:thumbnail height="" url="" width="" />
</item>

and in the .js I tried something like this
media:$(v).find("media:thumbnail").text(),
or this
media:$(v).find("media:thumbnail").attr("url"),

The first one causes absolutely nothing, the second one "undefined"… ?
It is quite frustrating to be honest, because actually it should work! :(

Comment 117 by Raymond Camden posted on 5/23/2012 at 7:26 PM

Try this:

var ray = $(v).find("media:thumbnail");
console.log(ray);

See if it shows something.

Comment 118 by A-z posted on 5/23/2012 at 7:59 PM

Ok, I am not sure if I am putting it on the right place, but there is no reaction when it comes after the entries.push(entry); and as soon as I put it up, no matter where in the $("#mainPage").live("pageinit", function() {… or above or under it, then neither my list is displayed…
Here the modified code, perhaps you see something I don't?

...

function renderEntries(entries) {

var s = '';
$.each(entries, function(i, v) {
s += '<li><a href="#contentPage" class="contentLink" data-entryid="'+i+'">' + '<div class="navtitel">' + v.title + '</div>' + '<div class="small-nav">'+ v.pubDate + '</div>' + '</a></li>';
});
$("#linksList").html(s);
$("#linksList").listview("refresh");

}

//Listen for main page
$("#mainPage").live("pageinit", function() {

$.ajax({
url:RSS,
success:function(res,code) {
entries = [];
var xml = $(res);
var items = xml.find("item");
$.each(items, function(i, v) {
entry = {
title:$(v).find("title").text(),
link:$(v).find("link").text(),
pubDate:$(v).find("pubDate").text(),

description:$.trim($(v).find("description").text()),

};

entries.push(entry);
entries.reverse();
var ray = $(v).find("media:thumbnail");
console.log(ray);
});

//store entries
localStorage["entries"] = JSON.stringify(entries);
renderEntries(entries);
},

error:function(jqXHR,status,error) {
//try to use cache
if(localStorage["entries"]) {
$("#status").html("Using cached version...");
entries = JSON.parse(localStorage["entries"])
renderEntries(entries);
} else {
$("#status").html("Sorry, we are unable to get the RSS and there is no cache.");
}
}
});

});

$("#mainPage").live("pagebeforeshow", function(event,data) {
if(data.prevPage.length) {
$("h1", data.prevPage).text("");
$("#entryText", data.prevPage).html("");
};
});

//Listen for the content page to load
$("#contentPage").live("pageshow", function(prepage) {
//Set the title
$("h1", this).text(entries[selectedEntry].title);
var contentHTML = "";
contentHTML += '<div class="bg-txt-s">';
contentHTML += '<h3>'+ entries[selectedEntry].title + '</h3>';
contentHTML += entries[selectedEntry].ray;
contentHTML += '<div class="small">' + entries[selectedEntry].pubDate + '</div>';
contentHTML += entries[selectedEntry].description;

...

Comment 119 by Raymond Camden posted on 5/23/2012 at 8:12 PM

In the future, please use pastebin for big code blocks. Makes it easier to read then in here. You need to put it in the EACH block, ie, after this:

$.each(items, function(i, v) {

The line above is run for each of the items in the XML. Now - another thing to consider is that not all of your items may have a thumbnail.

Comment 120 by A-z posted on 5/23/2012 at 8:52 PM

Oh sorry, I didn't think about the readableness of the code, my mistake!

Ok, tried it the other way, still not working unfortunately… I am sure that every entry has got a thumbnail, here the whole construct of the xml and the url in <media:thumbnail url="" > is always filled with an image url:
http://pastebin.com/1ysXTsiZ
And just to make sure, I made not more failures, here also the code of my main.js:
http://pastebin.com/NPKuqe0e

Thanks a lot for your effort!

Comment 121 by A-z posted on 5/23/2012 at 9:40 PM

Ok, me again ;)

I tried changing the <media:thumbnail> in my .rss to <media> and in the main.js I added ray:$(v).find("media").attr("url"),
and now at least the url of the image is displayed! That could been seen as a little progress perhaps, yippie! :)
Sorry, I am an absolute newbie in this field, this is my first app at all...
Do you think I should rather try on this way with the <media> and the .attr("url"), and if so, what would be the wisest way?

Comment 122 by A-z posted on 5/23/2012 at 10:00 PM

It works! I just have to put
contentHTML += '<img src="';
contentHTML += entries[selectedEntry].ray;
contentHTML += ' "/>';
in my main.js, and the pictures are there!
Thanks for your help! :)))

Comment 123 by Raymond Camden posted on 5/23/2012 at 11:34 PM

Glad you got it. One thing I'd recommend - to everyone - is to consider the Google Feed API. It allows you to parse XML and return a simple array of objects. It is MUCH easier than working with XML. It even includes a JSON/P service. For the jQuery Mobile book I wrote, I did a RSS example and made use of that instead. A heck of a lot cleaner.

Comment 124 by A-z posted on 5/24/2012 at 11:13 AM

Good morning Raymond, one last question, I hope:
do you see any possibility to use a feed which doesn't end with .rss in the app? Like a Yahoo Pipes feed (ends with ;_render=rss") or a Flickr feed?

Comment 125 by Raymond Camden posted on 5/24/2012 at 6:53 PM

It should not matter what the extension is. The JS code requests the URL and uses it. It should just work.

Comment 126 by Alex Meers posted on 5/24/2012 at 9:49 PM

Hey Raymond,

Alright, I got the RSS feed working exactly as I wanted except for one thing. When they tap the entry, I want it to show everything in the description tag. For example, if you look at the source code of my feed ( http://www.lambdachi.org/ca... ), the description tag has the text for the entire post. However, in Firefox and in your RSS feed, it shows "Continue Reading". Any ideas on how to show the full tag?

-Sandy Meers

Comment 127 by Raymond Camden posted on 5/24/2012 at 11:53 PM

When I view that RSS, it says continue reading too. That's the content of the RSS feed. So I'm a bit confused. If you want the entire post, the RSS data has to include the entire post. (You can build another way to get the full post of course.)

Look at your blog provider. (I say "your" because I assume this is your feed.) Some blogs provide a 'short' RSS feed and some provide a full entry version.

Comment 128 by Alex Meers posted on 5/29/2012 at 6:42 PM

Figured it out finally! I guess a long weekend finally knocked some sense into me...

I needed to use my RSS2 feed (/feeds/rss2), and that generated the content in the source code. I modified your Ajax call as well. Where you looked for description:$.trim($(v).find("description").text()), I changed the part in quotes to "encoded". RSS adds a <content:encoded> tag around the content and looking for just encoded gave me the near-close result that I was looking for.

Again, thanks for all of your help and for the great tutorial!

Comment 129 by Raymond Camden posted on 5/29/2012 at 6:43 PM

Cool. I strongly recommend the Google Feed API still though. I probably need to do a follow up.

Comment 130 by Jroen posted on 6/5/2012 at 6:02 PM

Hey Raymond,

With your help my app is running superb. With a lot of tweaking it is now showing the thumbnail and title of a the items (directly from my custom Wordpress feed) on mainPage and featured images, attached images (if any), title and content on page blogContent.

I came up with another idea. What I'd love to have is more pages which only show the items in certain categories (my feed now also shows the category in which the item was posted). Could you help me or point me in the good direction?

Thanks!

Comment 131 by Raymond Camden posted on 6/5/2012 at 6:06 PM

There are a few ways to handle this (well, probably many!), here are some basic ideas.

1) How do you do more pages? That is up to the UI framework you use. You could use tabs at the bottom of the screen for categories - but that would be a bit limited width wise. You could have a button that linked to a page that then listed categories. Again, there's different ways of doing this.

2) And of course -your category list is dynamic. Your blog may add the "Raymond Camden" category one day. Do you try to support that or do you get by with hard coded categories? You could simply use the categories from the RSS feed, but that's going to be dependent on your current content. If my last 10 entries are JUST on ColdFusion, then you wouldn't know that I have a jQuery category as well. And heck - even if you cache - people remove categories too. I did in my last redesign.

3) Probably the easiest aspect would be the filtering. Just use XPath. Of course, most blog engines support category specific RSS feeds, so you would simply switch to that URL.

Comment 132 by Jroen posted on 6/5/2012 at 6:30 PM

Hey Ray,

I'm using JqueryMobile. I already ran into the problem of limited width. I fixed it with using custom buttons in custom CSS without any JQMobile.

I want three extra pages. The first one, (home (or mainpage)) which show all the items in my feed. The second, third and fourth need to show items which are in the main feed but are rarely posted but interesting enough to have an own page (these categories have a lot of views compared to other categories). My problem is not the feed but more the javascript itself, I don't know where to start. Could you give me a simple example of javascript (main.js) where one page shows category X and one page shows category Y? I'll be able to work it out from there. At the moment I don't know how to let certain pages load certain items of the feed.

Thanks :)

Comment 133 by Raymond Camden posted on 6/5/2012 at 7:47 PM

Well, I can talk about it at a high level.

My code works by listening to pageinit for mainPage. Basically, "When this page is created, do this." When you add other pages, you can add your own code for them. You could- if you wanted -almost cut and paste my existing code and simply use a different RSS url (the category specific one).

I hope that helps. If I feel the code makes sense for a blog entry, I will write it, but right now, I don't think I will. As I mentioned, I think my next entry will be an update to the latest PG code base, latest JQM code base, and make use of the simpler Google Feeds API.

I actually did an example of this for my jQuery Mobile book. This code is open source here:

https://github.com/cfjedima...

Of course, for a detailed explanation you need to buy the book:

http://www.amazon.com/dp/18...

Comment 134 by A-z posted on 6/11/2012 at 6:49 PM

Hey Ray, I have nearly finished my first app, but now I am running against a wall… I want to output the entries in reverse order in the list, but when I try entries.reverse(); it just makes a mess of the order. Any idea?
Thanks!

Comment 135 by Raymond Camden posted on 6/11/2012 at 6:51 PM

You got me there. Where are you doing the reverse? Can you post to pastebin your code?

Comment 136 by A-z posted on 6/12/2012 at 10:38 AM

I put it directly after the entries.push(entry), here the code:
http://pastebin.com/EbMRYtFh

Comment 137 by Raymond Camden posted on 6/12/2012 at 3:34 PM

You put the reverse call in the each() block. That means your calling it every time you add an item. You need to put it immediately _after_ the each block.

Comment 138 by A-z posted on 6/12/2012 at 4:23 PM

I could have sworn that I already tried it out at that position, but then I probably had forgotton the semicolon or made some other ridiculous little neglect...
Thanks a lot, of course it works! :)

Comment 139 by Lynx posted on 6/12/2012 at 5:30 PM

Hey Raymond,I am a beginner with phonegap and jquery,and I tried your awesome app but it couldn't work,it just show the title and "Sorry, we are unable to get the RSS and there is no cache."
Here are some questions:why there are no
"<script type="text/javascript" src="cordova-1.8.0.js"></script><script type="text/javascript">"
in the index.html file?
why can't the program work properly for me?Does it because I missed some setting in elipse or jquery?Thanks for your help.

Comment 140 by Raymond Camden posted on 6/12/2012 at 5:33 PM

1) why there are no
"<script type="text/javascript" src="cordova-1.8.0.js">

Almost always you need the Cordova JS file to speak to the hardware. But this application doesn't need it. It actually doesn't do anything device specific at all.

2) "why can't the program work properly for me"

No idea. You will need to do some debugging on your side.

Comment 141 by Lynx posted on 6/12/2012 at 6:08 PM

Sorry to bother you again.I open the main.js with system editor and it says in line 11
$(".contentLink").live("click", function()
"Object Expected"
Please help me.

Comment 142 by Lynx posted on 6/12/2012 at 6:19 PM

By the way,I used Android 2.2 version

Comment 143 by Raymond Camden posted on 6/12/2012 at 6:19 PM

You get that error where? You said your system error, but are you testing on the mobile device?

Comment 144 by Lynx posted on 6/12/2012 at 6:28 PM

I ran it on the Android Visual Device 2.2,and it just showed the titles...

Comment 145 by Raymond Camden posted on 6/12/2012 at 6:36 PM

So the issue is with clicking to view the entries then?

Comment 146 by Lynx posted on 6/12/2012 at 6:45 PM

It only shows "ColdFusion Jedi" and "SimpleBlog by Raymond Camden",there are nothing for me to click...

Comment 147 by Raymond Camden posted on 6/12/2012 at 6:48 PM

So what do you see in console? Please read this blog entry:

http://www.raymondcamden.co...

Comment 148 by Lynx posted on 6/12/2012 at 7:09 PM

After I ran the Console told this:
ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.camden.rssdemo/.RSSDemoActivity }
And I just read your blog and filter the "Web Console" and "Console",nothing there

Comment 149 by Raymond Camden posted on 6/12/2012 at 8:39 PM

Nothing stands out to me - at this point - I'd have to say I don't know what to tell you - and to go further would require some one on one - which would be a paid engagement. Sorry.

Comment 150 by Lynx posted on 6/13/2012 at 6:01 AM

That's ok,thank you all the same,I'll try it myself:)

Comment 151 by Lynx posted on 6/15/2012 at 5:54 AM

Hi,it's me again:)I got it worked and thank you so very much.
By the way,the jquery-moblie-1.0 has a "flash back" problem,that is when clicking a link it will flash back to the mainpage ,then go to the next page,after update to jquery-moblie-1.1,this problem is solved,hope someone would find this useful:)

Comment 152 by GUNNER posted on 6/18/2012 at 3:46 PM

Hey Raymond, thanks you for sharing this app for us.But this app couldn't work not only on the emulator but also my device.they all show the title and "Sorry, we are unable to get the RSS and there is no cache."
But when I put the .xml file in to the project file and open it locally, it works fine.
I wonder it may be the cross-domain problem,can you give me some suggests,thanks.

Comment 153 by Raymond Camden posted on 6/19/2012 at 5:05 AM

Have you tried adding the RSS URL to the whitelist?

Comment 154 by GUNNER posted on 6/19/2012 at 9:01 AM

Thanks a lot.It really works!

Comment 155 by Sam posted on 6/21/2012 at 8:38 PM

hi,Ray.I have tested your code in eclipse platform for two days,unfortunately,it did not work.My android version is android 2.2?when I load code,it just displayed "SimpleBlog by Raymond Camden Home" .I am new to js,so I do not know how to debug that code.Can you give me some suggestions? thanks !

Comment 156 by Raymond Camden posted on 6/21/2012 at 8:46 PM

Sam,

This is a topic that is quite important to me. As I've blogged more on client side development over the past few years, I've seen a growing number of people like yourself. (That sounds a bit derogatory - please do not take it as such.) There is a serious lack of knowledge in regards to how to debug issues with JavaScript applications and mobile apps as well. Because of this I've begun work on a presentation to cover the basics. The topic is too much for this blog post, but it is sorely needed. For now what I'm recommending is some basic Googling on your part in terms of debugging JavaScript. There -is- a lot of content out there. In the meantime, I can say that when my presentation is done (I'm giving it to two places next month), I'll be giving it online as well so please subscribe to my blog for updates.

I feel like I'm letting you down here a bit - but at the same time - I feel like it is just too much for this entry now and it makes sense to address it more fully in a place of it's own.

Comment 157 by Sam posted on 6/21/2012 at 9:01 PM

Ray,thanks for replying ,I will learn to debug as soon as possible.

Comment 158 by Sam posted on 6/23/2012 at 7:30 AM

hi,Ray,it works,thanks.

Comment 159 by Alex posted on 6/28/2012 at 10:15 PM

Hi, I hava some problem with the attached file.
I think it miss some important files. So Can send an E-mail for me.(yjjxwx@qq.com or yjjxwx@sina.com)
I am a Chinese boy, study in a collage.
I am very poor in English, many information what I don't know how to say.
I am sorry for that.

Comment 160 by Raymond Camden posted on 6/29/2012 at 1:12 AM

I just checked the zip and everything is there. If you can tell me something specifically you think is missing, I'll try to find it for you.

Comment 161 by Alex posted on 6/29/2012 at 3:58 AM

Thank you!

Comment 162 by Larry posted on 7/4/2012 at 7:46 PM

I have this working perfectly on my local machine, but when I upload the files to my server and go to index.html, I get the following error: "Sorry, we are unable to get the RSS and there is no cache." I am not sure how to trouble shoot this problem.

Any suggestions would be helpful.

Comment 163 by Raymond Camden posted on 7/4/2012 at 9:11 PM

Your uploading the files to your server? This isn't meant to be run as a 'normal' web site, but rather as a PhoneGap application. If you run it as is, you will have the 'Same Domain' issue, where a file on foo.com can't do an XHR to goo.com. There are ways around this of course, but my main concern is with you trying to run it on your server.

Comment 164 by Jef posted on 7/18/2012 at 4:44 AM

For people trying to acces the content between the <![CDATA tags, you should use content:$.trim($(v).find("encoded").text())

Thanks for this tutorial, helped me a lot!

Comment 165 by elektrorl posted on 10/12/2012 at 3:28 PM

I try to reproduce this, except I'm using a JSON feed instead of regular RSS xml feed.

When feed is ok, use localStorage to store entries.

Please, take a look: http://jsfiddle.net/elektro...

Why I'm i getting only one entry, and this one is near the end of the list. Why only this one?

Comment 166 by Raymond Camden posted on 10/12/2012 at 3:58 PM

This line:

entries = [];

is inside your each loop, which means the array is getting destroyed each time. Move it to before the each loop.

Comment 167 by elektrorl posted on 10/12/2012 at 4:44 PM

Thank you so much Raymond, thanks for all your work by the way. Great tutorial. Now I have my feed OK. Great !

Comment 168 by budi posted on 3/27/2013 at 6:15 AM

Hi raymond ive try your code and its work in android but not in blackberry app, can you help me?

Comment 169 by Raymond Camden posted on 3/28/2013 at 12:41 AM

I don't normally test in Blackberry, sorry. I'd maybe try the latest version of this app (see Part 5). You could also tell me more about how it doesn't work. What do you see - etc.

Comment 170 by budi posted on 4/4/2013 at 9:35 AM

hi raymond i've try part 5 and deploy to blackberry app and its work, can you give me an example server side that using coldfusion code ? and what do you think is it the right methode to develop mobile who get data from remote site ? can you give me suggestion ?

Thank You

Budi

Comment 171 by Raymond Camden posted on 4/4/2013 at 3:23 PM

"can you give me an example server side that using coldfusion code"
Your question doesn't make sense. If you are asking how to handle RSS in general with CF, there is a <cffeed> tag.

"and what do you think is it the right methode to develop mobile who get data from remote site ?"

That is a bit broad. Libraries like jQuery make it relatively easy to load remote data. CF is also simple to use for generating JSON data.

Comment 172 by Saptaji posted on 9/3/2014 at 11:38 AM

Hai Raymond, i have a question about your rss.
How to show all title of the article? for example title is bla bla bla, not bla bla....
please answer my question raymond. Thanks before :).

Comment 173 by Raymond Camden posted on 9/3/2014 at 3:06 PM

Thats jQuery Mobile truncating it. I'd check their docs to see if that can be disabled, and of course if you aren't using jQM then it won't be a problem.

Comment 174 by Saptaji posted on 9/4/2014 at 1:47 AM

Ok thanks raymond. i will build a aplication about automatic summarization from article in rss, what should I do first ? do you have links to tutorials about it ? I'm sorry for your trouble :(. Thank you so much Raymond if you want help me :(.

Comment 175 by Raymond Camden posted on 9/4/2014 at 1:50 AM

Automatic summarization? Like taking an article and making a summary from it? You would need a powerful system to do that. I'm not aware of an API you can use for that. I do know of an API that will do text analysis (keywords, reading level, etc), but it won't summarize it for you.

Comment 176 by Saptaji posted on 9/4/2014 at 1:54 AM

I'm making a thesis about automatic news summarization. I was a dead end :'(.

Comment 177 by Saptaji posted on 9/4/2014 at 1:58 AM

yes thats true, so I can not do it? :'( :'(.

Comment 178 by Raymond Camden posted on 9/4/2014 at 2:10 AM

I'm not saying you can't do it - just that I don't know of an API you can call to do it for you. You could write the logic yourself I suppose.

Comment 179 by Saptaji posted on 9/4/2014 at 2:25 AM

ok raymond thank you so much for your answer. :)