Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

appendChild can be used to relocate a row inside a table? 1

Status
Not open for further replies.

Kirsle

Programmer
Jan 21, 2006
1,179
US
Today I discovered a rather strange anomaly in JavaScript, or more specifically in the DOM.

The Background - you can skip this if you'd like and read from the next bolded label.

I was recently assigned the task of making a complicated table be sortable by any column. The table is complicated because each row in the table contains, in its first cell, a "+" icon that can be clicked to expand additional data about that row. This extra data is really just the following <tr> row, which was set to "display:none" initially.

So every second row in this table is hidden by default until the user clicks a + icon. So, existing table sorting scripts wouldn't work, because they'd try to also take into account the contents of these hidden rows when figuring out how to re-order the rows in the table, which would either cause JS errors or, at the very least, totally mix up the table so it doesn't make any sense anymore to the human.

Rather than haxxor up an existing script until it works, I decided it would be better if I wrote one from scratch that has been built from the ground up specifically to handle complicated tables like this.

The Weirdness

The logical approach I was thinking of, for how to re-arrange the rows in the table, was to delete all the rows first and then reinsert them in the correct order.

This approach didn't work. The new rows seemed out-of-place; the cells in the new rows no longer lined up with the cells of the header row. For my approach to work I would have had to copy all attributes from all cells, and any style information, and then reapply all of these attributes and styles for each row I insert back. This isn't acceptable.

I was looking at other codes for sortable tables while I was coding mine, and the one I was looking at had a really strange way of re-ordering the rows:

Instead of deleting rows and re-adding them, it instead simply re-appended the already existing rows.

Basically, it did this to copy the row objects into an array:

Code:
newRows[ i ] = table.rows[ i ];

Then sorted newRows, and then it re-inserted them into the table by simply doing this:

Code:
table.tBody[0].appendChild (newRows[i]);

When I looked at the code, I logically assumed that this would duplicate all the rows in the table, and you'd wind up with a table twice as long as you started with. But in fact, when you do appendChild to insert a row that already exists in the table, it simply moves that row to the end of the table.

Can anyone explain why this is? I wondered if it was just a Firefox bug (the code I was referencing was used on our intranet, and everyone here uses Firefox so I was wondering if it's simply gone unnoticed all this time - but on IE 8 the code still works).

For the full code for my custom table sorter, look here: (its a temporary link and within 6 months it'll be gone for sure).

Kirsle.net | My personal homepage
Code:
perl -e '$|=$i=1;print" oo\n<|>\n_|_";x:sleep$|;print"\b",$i++%2?"/":"_";goto x;'
 
When I looked at the code, I logically assumed that this would duplicate all the rows in the table, and you'd wind up with a table twice as long as you started with. But in fact, when you do appendChild to insert a row that already exists in the table, it simply moves that row to the end of the table.

Can anyone explain why this is?

This has nothing to do with the fact that you're dealing with tables... it's standard behaviour for appendChild (and also many other DOM manipulation methods).

Basically, if the node you're appending already exists in the DOM, the existing reference is removed before being re-appended.

All of the good reference sites (MSDN, MDC, etc) should mention this, so I'm surprised you haven't found any reference to it in your research into the "phenomenon".

Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page [blue]@[/blue] Code Couch:
Code Couch Tech Snippets & Info:
 
Thanks!

Everyone I know in person that I talked to about this was just as surprised as I was, and when I was googling about appendChild I only found pages that talked about adding new elements to the page (i.e. after a createElement() call) and not about re-adding an already existing element. So I turned to the forums for an explanation.

Have a star.

Kirsle.net | My personal homepage
Code:
perl -e '$|=$i=1;print" oo\n<|>\n_|_";x:sleep$|;print"\b",$i++%2?"/":"_";goto x;'
 
Everyone I know in person that I talked to about this was just as surprised as I was

I guess you didn't talk to any good JS developers, then ;-)



Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page [blue]@[/blue] Code Couch:
Code Couch Tech Snippets & Info:
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top