RSS Cross-Origin Request using an AJAX promise ('-' * 46) Cross-Origin RSS Feed requested with AJAX and a JQuery Promise. This example requires a Web Service with CORS enabled.
A Pen by Siôn J. Lewis on CodePen.
<div id="header"> | |
<h2>RSS Cross-Origin Request using an AJAX promise</h2> | |
</div> | |
<div id="content"> | |
<ul id="rss-feed"> | |
</ul> | |
<span id="error"></span> | |
</div> | |
<div id="footer" class="hide"> | |
<br/> | |
<a href="http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api" target="_blank">Enabling Cross-Origin Requests in ASP.NET Web API</a> | |
<br/> | |
<br/> | |
<div> |
RSS Cross-Origin Request using an AJAX promise ('-' * 46) Cross-Origin RSS Feed requested with AJAX and a JQuery Promise. This example requires a Web Service with CORS enabled.
A Pen by Siôn J. Lewis on CodePen.
var SJL = SJL || {}; | |
SJL.RSSFeed = SJL.RSSFeed || {}; | |
SJL.RSSFeed = function () { | |
var self = {}; | |
self.Config = { | |
// TODO: find a way to store this info in a config. | |
newsPods: { | |
dev: "https://arupdw-dev-cdn.azurewebsites.net/API/RSSNewsPod" | |
}, | |
newsCenter: { | |
dev: "s.codepen.io" | |
} | |
}; | |
self.Model = { | |
item: function (title, link, description, shortDesc, source, author, pubDate) { | |
this.title = title; | |
this.link = link; | |
this.description = description; | |
this.shortDesc = shortDesc; | |
this.source = source; | |
this.author = author; | |
this.pubDate = pubDate; | |
} | |
}; | |
self.Repository = { | |
getNewsPod: function (beforeComplete, onSuccess, onError) { | |
if (beforeComplete && typeof (beforeComplete) === 'function') { | |
beforeComplete(); | |
} | |
var promise = $.ajax({ | |
type: 'get', | |
url: self.Controller.getNewsPodUrl() | |
}).done(function (data) { | |
var xml = data.firstChild; | |
if (onSuccess && typeof (onSuccess) === 'function') { | |
onSuccess(xml); | |
} else { | |
alert('getNewsPod()', 'callback function has not been passed.'); | |
} | |
}).error(function (jqXHR, textStatus, errorThrown) { | |
var msg = jqXHR.responseText || textStatus; | |
if (onError && typeof (onError) === 'function') { | |
onError(msg); | |
} else { | |
alert('getNewsPod()', 'callback function has not been passed.'); | |
} | |
}); | |
} | |
}; | |
self.Controller = { | |
convertFeedToArray_Async: function () { | |
var dfd = new $.Deferred(); | |
try { | |
self.Repository.getNewsPod( | |
function() { | |
// Could show a loading graphic... | |
}, | |
function (data) { | |
var el = $(data).find("item"); | |
if ($(el).length > 0) { | |
var items = []; | |
$(el).each(function () { | |
var item = $(this); | |
var title = item.find("title").text(); | |
var link = item.find("link").text(); | |
var description = item.find("description").text(); | |
var shortDesc = self.Controller.trimText(description, 110); | |
var source = item.find("source").text(); | |
var author = item.find("author").text(); | |
var pubDate = item.find("pubDate").text(); | |
items.push(new self.Model.item(title, link, description, shortDesc, source, author, pubDate)); | |
}); | |
dfd.resolve(items); | |
} else { | |
// Error... | |
dfd.fail('Error: RSS XML data not found.'); | |
} | |
}, | |
function (data) { | |
dfd.fail('Error: RSS Feed not found.'); | |
}); | |
}catch(ex){ | |
dfd.fail('Error: ' + ex); | |
} | |
return dfd.promise(); | |
}, | |
getNewsPodUrl: function () { | |
var siteUrl = document.location.href; | |
if (siteUrl.indexOf(self.Config.newsCenter.dev) > -1) { | |
return self.Config.newsPods.dev; | |
} else { | |
return ""; // No match found... | |
} | |
}, | |
trimText: function (text, len) { | |
// Take into account the '...'. | |
len = len - 3; | |
if (text != undefined && text.length > len) { | |
var tmp = jQuery.trim(text).substring(0, len).split(" ") | |
var text = tmp.slice(0, tmp.length - 1).join(" ") + "..."; | |
} | |
// And replace any rogue commas. | |
return text = text.replace(',...', '...').replace('-...', '...'); | |
} | |
}; | |
self.View = { | |
itemTemplate: function(item, index) { | |
var html = $('#rss-feed').html(); | |
html += '<li>'; | |
html += '<a href="#" onclick="JavaScript:SJL.RSSFeed.View.displayDesc(' + index + ');return false;" id="rss-title-' + index + '">' + item.title + '</a>'; | |
html += '<ul class="meta">'; | |
html += '<li id="rss-source-' + index + '">' + item.source + '</li>'; | |
html += '<li id="rss-date-' + index + '">' + item.pubDate + '</li>'; | |
html += '</ul>'; | |
html += '<div id="rss-short-desc-' + index + '" class="description">' + item.shortDesc + '</div>'; | |
html += '<div id="rss-desc-' + index + '" style="display:none;" class="description">' + item.description + '<span><a id="rss-link-' + index + '" href="' + item.link + '" target="_blank">More...</span><div>'; | |
html += '</li>'; | |
$('#rss-feed').html(html); | |
}, | |
renderFeed: function () { | |
$.when(self.Controller.convertFeedToArray_Async()).done(function (items) { | |
// TODO: Check for error message... | |
$.each(items, function (index, item) { | |
self.View.itemTemplate(item, index); | |
}); | |
}); | |
}, | |
displayDesc: function (index) { | |
$('#rss-desc-' + index + ', #rss-short-desc-' + index).toggle("fast", function() {}); | |
} | |
}; | |
self.onLoad = function () { | |
self.View.renderFeed(); | |
}; | |
return self; | |
}(); | |
$(function () { | |
SJL.RSSFeed.onLoad(); | |
}); |
div { | |
/*border-style: solid; | |
border-width: 1px;*/ | |
} | |
.hide { | |
border-style: none; | |
display:none; | |
} | |
.show { | |
border-style: none; | |
display:block; | |
} |