Yah… the title is a mouthful
I needed to import XML news items to a html page, simple as
it sounds, this needed to be on the client side, (I mean all the reading and html
construction) needed to happen on the browser.
Reading XML files using JavaScript is possible see…
Reading XML files using JavaScript is possible see…
And there is displaying XML data in html
But jQuery allows the use of Ajax, That is, jQuery allows
you to asynchronously read an XML file, iterate though all the elements and use
jQuery constructs to write html
My XML file… news.xml
<?xml version="1.0" encoding="UTF-8"?>
<NewsList>
<NewsItem>
<Id>1</Id>
<Name>News item 1</Name>
<thumbimage>images/thumbs/thumb1.jpg</thumbimage>
<image>images/img1.jpg</image>
<Description>DESC1</Description>
</NewsItem>
<NewsItem>
<Id>2</Id>
<Name>News item 2</Name>
<thumbimage>images/thumbs/thumb2.jpg</thumbimage>
<image>images/img2.jpg</image>
<Description>DESC2</Description>
</NewsItem>
<NewsItem>
<Id>3</Id>
<Name>News item 3</Name>
<Description>DESC2</Description>
</NewsItem>
</NewsList>
The Html page consists of a single element (div tag) to
which our data shall be appended using jQuery.
<div id= "NewsDiv"></div>
On the ready function jQuery Ajax is used to read the xml
and iterate through the news items…
<script>
$(document).ready(function () {
$.ajax({
type: "GET",
url: "news.xml",
dataType: "xml",
success: function (xml) {
$(xml).find('NewsItem').each(function () {
var id = $(this).find('Id').text();
var name = $(this).find('Name').text();
var image = $(this).find('image').text();
var
desc = $(this).find('Description').text();
//the styles are to make them look ok… I guess…
$('<div id="link_' + id + '" style="width:400px"></div>').html('<div style="border:2px solid
red;text-align:center">' + name + '</div><div
style="text-align:left;padding:10px 3px 3px 10px"><p><img
src="' + image + '"
style="float:left;padding:8px" />' + desc + '</p></div>').appendTo('#NewsDiv');
});
}
});
});
</script>
Above code reads the items, creates html, and appends it to
the NewsDiv.
Well, If you notice in the XML, the item 3 does not have an
image, hence if condition
if(image!='')
$('<div id="link_'+id+'"
style="width:400px"></div>').html('<div style="border:2px solid red;text-align:center">'+name+'</div><div style="text-align:left;padding:10px 3px 3px 10px;border:2px solid black"><p><img src="'+image+'" />'+desc+'</p></div>').appendTo('#NewsDiv');
else
$('<div id="link_'+id+'"
style="width:400px"></div>').html('<div style="border:2px solid red;text-align:center">'+name+'</div><div style="text-align:left;padding:10px 3px 3px 10px;border:2px solid
black"><p>'+desc+'</p></div>').appendTo('#NewsDiv');
Until now, it was the basics to read XML and display on a
page.
In a basic site, you would have a news ticker on the main
page where each item links to the main news page.
The idea is to create a new page, let’s say the index page
where the new items are shown in short (the thumbnail in the XML file is used
for this) each item links to the news page.
Simply, we have this
Adding a little more functionality would enhance this more
What if…
Well that’s easy use named anchor tags
Named anchor tags are links on the same page, you must have
seen the ‘top’ like on many sites that navigates to the top of a page.
Similarly we can link each news item to an anchor tag and navigate to that part
of the page when the news item is clicked.
The basic code to be used is…
<a name=position>POSTION</a>
- position on a
page
<a href=#position>navigate to postion</a>
- navigate to the position
To navigate to a part of the page from another page we have
to mention the anchor name in the url with the hash like…
<a name=position>POSTION</a>
- position on a.html
<a href=a.html#position>navigate to postion</a>
- navigate to the position from b.html
Or you could as Mr Google for more details
This calls for some changes in the code in the main page
(that shows all the detailed news items) news.html
The jQuery code to write the html need changes by adding a
named anchor for each item.
Just need to insert
this… <a name="+id+"></a>
since we already have the id of the news item we need to use it to add the anchor
since we already have the id of the news item we need to use it to add the anchor
Therefore the script has a minor change
if(image!='')
$('<div id="link_'+id+'"
style="width:400px"></div>').html('<div style="border:2px solid red;text-align:center">'+name+'
<a name="'+id+'"></a></div><div style="text-align:left;padding:10px 3px 3px 10px;border:2px solid black"><p><img src="'+image+'"
/>'+desc+'</p></div>').appendTo('#NewsDiv');
else
$('<div id="link_'+id+'"
style="width:400px"></div>').html('<div style="border:2px solid red;text-align:center">'+name+'
<a name="'+id+'"></a></div><div style="text-align:left;padding:10px 3px 3px 10px;border:2px solid black"><p>'+desc+'</p></div>').appendTo('#NewsDiv');
Now that we have the anchor set for each item on the news
page lets make news items on the main page.
Create a new page called index.html that will contain the
ticker
Keeping it simple…. Just add one div tag called newsticker
<div id="newsticker" style="height:210px;overflow-x:hidden;overflow-y:auto"></div></div>
This will contain only the name and the thumbnail (if
present)
In the script of the index.html
<script>
$(document).ready(function () {
$.ajax({
type: "GET",
url: "news.xml",
dataType: "xml",
success: function (xml) {
var newstable = '<table
border="1" align="center" cellpadding="20px"
width="90%"><tbody>';
$(xml).find('NewsItem').each(function () {
var id = $(this).find('Id').text();
var name = $(this).find('Name').text();
var desc = $(this).find('Description').text();
var image = $(this).find('thumbimage').text();
if (image != '') {
newstable += '<tr><td><a href="news.html#' +
id + '"><img src="' + image +
'" style="float:left;padding:8px"
/>' + name + '</a></td>'
}
else {
newstable += '<tr><td><a href="news.html#' +
id + '">' + name + '</a></td>'
}
});
newstable += '</tbody></table>';
$('#newsticker').html(newstable);
}
});
});
</script>
This shows a table that has the names and the thumbnail
images
So, here we are, we created two pages that read from a XML
file and display the contents, and link the news ticker items to their
corresponding detailed items.
The problem
This would work perfectly well if the page was not created
dynamically
The problem is, the named anchor link from the main page
cannot read the link on the news page as it’s not created as soon as the page
is loaded.
Therefore, we need to wait until the page is loaded and then
navigate to the anchor tags
For this we need to use javascript.
To navigate to a named anchor on a page using javascript,
location.hash = '#'+namedanchor;
we need to first get the name of the anchor from the url,
for this…
var pathname = window.location.pathname;
or in jQuery
var pathname = $(location).attr('href');
After this, the pathname is split to get the name of the
anchor…
var hash = '#'+pathname.split('#')[1];
then we use the setTimeout function to set a delay…
setTimeout(function(){location.hash = hash;}, 100);
Complete code:
var pathname = $(location).attr('href');
var
hash = '#'+pathname.split('#')[1];
setTimeout(function(){
location.hash
= hash;
},
100);
and so when this piece of code is added to the news.HTML script, the page loads up fine and points to the anchor.
To run this javascript after the page is loaded this code
can be used
$
(window
).bind
("load",function()
{
// code here
});
But the delay works just fine (in stand alone conditions).
Its better if we use this
$(window).bind("load", function() {
var
pathname = $(location).attr('href');
var
hash = '#'+pathname.split('#')[1];
setTimeout(function(){
location.hash
= hash;
},
400);
});
Hope this helps someone, and if you know a better way to delay
the script, please let’s have a conversation in the comments below.
No comments:
Post a Comment