473,385 Members | 1,569 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

cloneNode/appendChild and children

Hello everyone. I'm playing around with some AJAX-ish stuff and
encountered some problem in the JS side of the universe. Maybe someone
here can suggest an alternative that works.

I have developed a simple ASP.NET application with a web page that
should display a list of users. This list page is designed to start
with an empty table (with columns defined), and, onload, send an
XmlHttp request to a server component (a.k.a. ListServer). This
ListServer is currently simulating a long-running operation. So, it
sleeps for 3 seconds, and then grabs a list of 4 users from an xml
file. It applies an xsl transformation and returns the result.

The xslt is designed to take the xml data and convert it to a
<ListChunkroot element containing a <trfor each user in the XML
data. Each row contains 4 columns (Id, Login, Password, Name). The
javascript in the list page grabs the responseXML from the XmlHttp
object and should, for each <trin it, create a copy of the row
coming from the server and adding it to the list on the client.

I actually got all that to work quite fine. The js snipplet dealing
with copying the row coming from the server and adding it to the table
on the client is:

(listChunk is the responsseXML fromt he XmlHttp object, and tableBody
is the body of the table in the page)

var userRows = listChunk.getElementsByTagName("tr");
if(userRows==null || userRows.length==0)
{
EndAsyncLoading();
return;
}
for(var rowIndex=0; rowIndex<userRows.length; rowIndex++)
{
var serverRow = userRows[rowIndex];
var clientRow = tableBody.insertRow(-1);

var serverCells = serverRow.getElementsByTagName("td");
for(var cellIndex=0; cellIndex<serverCells.length; cellIndex+
+)
{
var serverCell = serverCells[cellIndex];
var clientCell = serverCell.cloneNode(true);
clientRow.appendChild(clientCell);
}
}

As you can see, it's a call to insertRow followed by a call to
cloneNode and appendChild for each cell int he row.

Today I modified the xsl on the server to make the Id and Login
columns links. The odd thing is that the table rows added to the table
on the page include the links in the first two cells, but the browser
does not let me click on them.

Even better.. if I save the resulting page locally, and then re-open
it in the same browser, the links are recognized as such and
clickable.

I'm working in Firefox 2 for now, but would certainly like to find a
solution that works at least in FF2 and IE7 (although IE7 is still
yelling at me for using appendChild /sigh)

Thanks in advance,
F.O.R.

Apr 30 '07 #1
4 8301
On May 1, 8:27 am, Olorin <francesco.ri...@gmail.comwrote:
Hello everyone. I'm playing around with some AJAX-ish stuff and
encountered some problem in the JS side of the universe. Maybe someone
here can suggest an alternative that works.

I have developed a simple ASP.NET application with a web page that
should display a list of users. This list page is designed to start
with an empty table (with columns defined), and, onload, send an
XmlHttp request to a server component (a.k.a. ListServer). This
ListServer is currently simulating a long-running operation. So, it
sleeps for 3 seconds, and then grabs a list of 4 users from an xml
file. It applies an xsl transformation and returns the result.

The xslt is designed to take the xml data and convert it to a
<ListChunkroot element containing a <trfor each user in the XML
data.
It seems rather pointless to use XSLT to convert XML to XML. Why not
convert it to HTML and save yourself a lot of trouble?
Each row contains 4 columns (Id, Login, Password, Name). The
javascript in the list page grabs the responseXML from the XmlHttp
object and should, for each <trin it, create a copy of the row
coming from the server and adding it to the list on the client.

I actually got all that to work quite fine. The js snipplet dealing
with copying the row coming from the server and adding it to the table
on the client is:

(listChunk is the responsseXML fromt he XmlHttp object, and tableBody
is the body of the table in the page)

var userRows = listChunk.getElementsByTagName("tr");
if(userRows==null || userRows.length==0)
In what circumstance will userRows be null?

If supported, getElementsByTagName returns a NodeList object, always.
If it's not, attempting listChunk.getElementsByTagName("tr") will
cause your script to fail before the test is reached.

{
EndAsyncLoading();
return;
}
for(var rowIndex=0; rowIndex<userRows.length; rowIndex++)
{
var serverRow = userRows[rowIndex];
var clientRow = tableBody.insertRow(-1);

var serverCells = serverRow.getElementsByTagName("td");
for(var cellIndex=0; cellIndex<serverCells.length; cellIndex+
+)
{
var serverCell = serverCells[cellIndex];
var clientCell = serverCell.cloneNode(true);
clientRow.appendChild(clientCell);
}
}

As you can see, it's a call to insertRow followed by a call to
cloneNode and appendChild for each cell int he row.
Why not send HTML instead of XML and just append the rows to the table
(insert the HTML as the innerHTML of a div to convert it to a DOM
object, just wrap the trs in table tags)? You could also just grab
the tbody and append it to the current table or replace the current
tbody - done in one go.

Today I modified the xsl on the server to make the Id and Login
columns links. The odd thing is that the table rows added to the table
on the page include the links in the first two cells, but the browser
does not let me click on them.
Without seeing the initial XML and the resulting markup I can only
guess.
Even better.. if I save the resulting page locally, and then re-open
it in the same browser, the links are recognized as such and
clickable.
Probably because you are sending XML, not HTML. Saving it locally as
HTML then loading it back in changes how the parser interprets the
markup.

I'm working in Firefox 2 for now, but would certainly like to find a
solution that works at least in FF2 and IE7 (although IE7 is still
yelling at me for using appendChild /sigh)
Do not feed XML to IE.
--
Rob

May 1 '07 #2
On Apr 30, 9:53 pm, RobG <r...@iinet.net.auwrote:
>
It seems rather pointless to use XSLT to convert XML to XML. Why not
convert it to HTML and save yourself a lot of trouble?
Possibly, but this is a simple mock-up, and I was following samples I
found online.
I was interested in learning a bit about the server-side application
of transforms anyway.
In what circumstance will userRows be null?
When, for instance, the server has finished sending all users.
Right now (again, this is a mock), the server will send
4 user-rows at the time, for a maximum of 4 times.
When it reaches the end of the simulkated users, it leaves
the response stream clear.
Why not send HTML instead of XML and just append the rows to the table
(insert the HTML as the innerHTML of a div to convert it to a DOM
object, just wrap the trs in table tags)? You could also just grab
the tbody and append it to the current table or replace the current
tbody - done in one go.
I actually tried to switch the xsl transformation output from xml to
html, just to see
if it made any difference, but it didn't.
I've been reading around and it seems that, indeed, cloneNode does not
copy
all attributes and/or event handlers (although in my case the href
attribute is cloned),
and that simply adding a node to an [x]html document is not enough.
See for instance this article: http://alistapart.com/articles/crossbrowserscripting
It focuses on importNode, rather than cloning and appending (like I am
doing), but the
problem seem to be the same.
Without seeing the initial XML and the resulting markup I can only
guess.
The source of users is an xml file as follows: (I'll show you a single
user, but there are 4 in the actual file)
<?xml version="1.0" encoding="UTF-8"?>
<ListPage>
<User id="1">
<Login>fred</Login>
<Password>Wilma</Password>
<FirstName>Fred</FirstName>
<LastName>Flinstone</LastName>
</User>
</ListPage>

The xslt, with the first 2 columns set to be links:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/
Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-
declaration="no" standalone="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<ListChunk>
<xsl:for-each select="ListPage/User">
<tr>
<td>
<a href="http://www.google.com"><xsl:value-of
select="@id" /></a>
</td>
<td>
<a href="http://www.google.com"><xsl:value-of
select="Login" /></a>
</td>
<td>
<xsl:value-of select="Password" />
</td>
<td>
<xsl:value-of select="FirstName" />
</td>
<td>
<xsl:value-of select="LastName" />
</td>
</tr>
</xsl:for-each>
</ListChunk>
</xsl:template>
</xsl:stylesheet>

Using firebug, I've been checking what gets sent by the server to the
client, and it seems to be:
<ListChunk>
<tr>
<td><a href="http://www.google.com">1</a></td>
<td><a href="http://www.google.com">fred</a></td>
<td>Wilma</td>
<td>Fred</td>
<td>Flinstone</td>
</tr>
</ListChunk>
As I said, changing the output method of the transform from xml to
html didn't seem to make any difference.

I can share the whole thing if needed (including the javascript that
kicks off the request on page load, etc etc), but it really seem to me
that there's something going on with the cloneNode/appendChild
sequence.
In the article I mentioned above, A. Holdener explains that

Apparently, in all browsers, elements must be passed through the HTML
parser before events and style will be activated.
That might be the reason why the links are not being treated as links
(but reloading the page from a local copy makes them act like proper
links).
Or maybe not, maybe it's totally unrelated and I'm missing something
else.
Do not feed XML to IE.
....so what's the recommended cross-browser 'closest-to-standard-
compliance' approach to take for something like this ?

Thanks for reading and answering,
F.O.R.
May 1 '07 #3
On May 1, 10:05 pm, Olorin <francesco.ri...@gmail.comwrote:
On Apr 30, 9:53 pm, RobG <r...@iinet.net.auwrote:
It seems rather pointless to use XSLT to convert XML to XML. Why not
convert it to HTML and save yourself a lot of trouble?

Possibly, but this is a simple mock-up, and I was following samples I
found online.
I was interested in learning a bit about the server-side application
of transforms anyway.
In what circumstance will userRows be null?

When, for instance, the server has finished sending all users.
getElementsByTagName is a method of the document object. By
definition, it always returns a NodeList object. It may not have any
nodes in the list (i.e. a length of zero) but it is still a NodeList
object, not null.

<URL: http://www.w3.org/TR/DOM-Level-2-Cor...tml#ID-A6C9094 >

Right now (again, this is a mock), the server will send
4 user-rows at the time, for a maximum of 4 times.
When it reaches the end of the simulkated users, it leaves
the response stream clear.
Why not send HTML instead of XML and just append the rows to the table
(insert the HTML as the innerHTML of a div to convert it to a DOM
object, just wrap the trs in table tags)? You could also just grab
the tbody and append it to the current table or replace the current
tbody - done in one go.

I actually tried to switch the xsl transformation output from xml to
html, just to see
if it made any difference, but it didn't.
>From what you have posted below, your response text is not valid
HTML. TR elements must be in a table. I don't know how a browser
treats an XML "tr" node placed into an HTML document.
I've been reading around and it seems that, indeed, cloneNode does not
copy
all attributes and/or event handlers (although in my case the href
attribute is cloned),
Whether or not handlers are cloned depends on how they are added and
which browser you are using.

<URL:
http://groups.google.com.au/group/co...c9b4debcac1543
>
cloneNode *should* copy all attributes and their values, whether or
not it does might be browser dependent:

<URL: http://www.w3.org/TR/DOM-Level-2-Cor...ml#ID-3A0ED0A4 >
[...]
The source of users is an xml file as follows: (I'll show you a single
user, but there are 4 in the actual file)
<?xml version="1.0" encoding="UTF-8"?>
<ListPage>
<User id="1">
<Login>fred</Login>
<Password>Wilma</Password>
<FirstName>Fred</FirstName>
<LastName>Flinstone</LastName>
</User>
</ListPage>

The xslt, with the first 2 columns set to be links:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/
Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-
declaration="no" standalone="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<ListChunk>
<xsl:for-each select="ListPage/User">
<tr>
There you are, invalid HTML (though it might be fine as XML).

[...]
Using firebug, I've been checking what gets sent by the server to the
client, and it seems to be:
<ListChunk>
<tr>
<td><a href="http://www.google.com">1</a></td>
<td><a href="http://www.google.com">fred</a></td>
<td>Wilma</td>
<td>Fred</td>
<td>Flinstone</td>
</tr>
</ListChunk>
But that's not valid HTML.

As I said, changing the output method of the transform from xml to
html didn't seem to make any difference.
Put table tags around the tr's.

[...]
Do not feed XML to IE.

...so what's the recommended cross-browser 'closest-to-standard-
compliance' approach to take for something like this ?
Most send HTML then put it into the document using innerHTML. Look at
a couple of AJAX libraries:

<URL: http://www.ajaxtoolbox.com/ >
--
Rob

May 1 '07 #4
Hey Rob,
thanks again for the help.

I modified my solution so that the server sends simple xml to the
browser, and the js function handling the response iterates over it
and creates the table rows and their content.

In the meanwhile, I'm still hopeful to find a solution that lets the
server sends the pre-formatted rows to the client.
As you suggested, I made the server produce html instead of xml.
It seems that, in this case, the response is received in the
responseText (rather than responseXml) of the XmlHttp object in the
browser's js.

At this point, if I was handling html content that I could happily
dump in a div or other container via .innerHtml, I guess I'd be done
(but I'd still feel uneasy about innerHtml.. I'm that kind of person).
However, as you;ve seen in the previous example, I was dealing with
table rows and such...
...is there a quick way for me to read the responseText into some tree-
like structure so that I can then iterate over it as needed (other
than parsing the html myself) ?

Thanks again,
~O

May 3 '07 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: johkar | last post by:
This is a shortened version of my problem. Below I am cloning the first data row and appending it to create a new row. If you make selections/add values and then press Add Row, the text box value...
1
by: Ryan Stewart | last post by:
If you don't want to read this post because of its length, I understand. I've spent two and a half days on this problem and have a good deal of information to relate. And this is kind of a long...
2
by: Marco | last post by:
Hello! Can anyone explain why the following code does not work? (I'm using python2.4.) Cheers, Marco --
7
by: garthb | last post by:
Hello, In Mozilla (Firefox 1.0.7) I can cloneNode a file input element that has a selected file value and appendChild it to another form without a problem. IE 6 loses the selected file value....
1
by: jaktharkhan | last post by:
Hi, I really really need help in trying to figure out how can I do a CloneNode on an Iframe where the cloned IFRAME clones with all its contents?. Basically what I am doing is dynamically building...
1
by: bs9999 | last post by:
Can someone please tell me why when i use <object>.clondeNode that when I appendChild it to my document, the new node doesnt properly work? I'm making a clone of a <scriptand <linknode from an...
1
by: Dmitry Kulinich | last post by:
var iframe = document.createElement("<IFRAME id='frame0' style='PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px' border='no' name='frame0'...
3
by: santosh.pjb | last post by:
I have a button on a page whose onclick funtion is posted below. I am basically trying to get all the spans in the page and list them in 2 columns. I get the list of spans using...
2
by: Alino | last post by:
hello, i need help with this javascript <script type="text/javascript"> function addfile() { var obj = document.getElementById("sprytextfield2").cloneNode(true);...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.