A warning about dynamic table creation

  • Thread starter Rex the Strange
  • Start date
R

Rex the Strange

BIG WARNING!!

I just spent hours trying to figure this out! If you're doing dynamic
javascript and you're trying to create a table on the fly using
createElement then HEED THIS WARNING!


You would think that you could get away with this:

var page_element = document.getElementById ("parent_element_name");

var table = document.createElement ("table");
var row = document.createElement ("tr");
var cell = document.createElement ("td");

page_element.appendChild (table);
table.appendChild (row);
row.appendChild (cell);

cell.innerHTML = "this is where the live stuff goes";

And Firefox has no problems with this. Internet Explorer will puke!
Well, actually, IE does nothing at all and you can poll your page for
the elements and you will find them. They're there, but they don't
show up on the page. You need:

var body = document.createElement ("tbody"); (or thead or tfoot)

Link that to the table and the row to that:

table.appendChild (body);
body.appendChild (row);

And everything is hunky dorey! I just wasted a big piece of my life on
this one so I'm hoping I can save some people the same heartache. By
the way, Firefox doesn't care either way, so use the latter for better
cross-browser compatibility (also works in Opera and PC Safari - don't
know about Mac Safari).
 
H

Henry

BIG WARNING!!

I just spent hours trying to figure this out! If you're
doing dynamic javascript and you're trying to create a
table on the fly using createElement then HEED THIS
WARNING!

Or at least the warning implied by this warning.
You would think that you could get away with this:

var page_element = document.getElementById ("parent_element_name");

var table = document.createElement ("table");
var row = document.createElement ("tr");
var cell = document.createElement ("td");

page_element.appendChild (table);
table.appendChild (row);

No, you absolutely should not expect to be able to "get away with"
that in an HTML DOM. The structural constraints of HTML do not allow a
TR element to be the direct child of any type of element except a
table section element (TBODY, THEAD or TFOOT). It makes as little
sense to attempt to make a TR a direct child of a TABLE as it would to
attempt to make one a direct child of a SELECT element.
row.appendChild (cell);

cell.innerHTML = "this is where the live stuff goes";

And Firefox has no problems with this.
Internet Explorer will puke!

No it doesn't. IE just does not tolerate your mistake or take any
action to correct it. That could never be an unexpected outcome as the
spectrum of possible mistakes is far too great to allow them all to be
accommodated, or even for those that are handled to be consistently
handled (over time or across browsers).
Well, actually, IE does nothing at all and you can poll your
page for the elements and you will find them. They're there,
but they don't show up on the page.

So IE does do something. In fact it does precisely what you programmed
it to do; it is just that the nonsense structure you have created
cannot be visually represented by a system that is expecting a
structure resembling an HTML DOM.
You need:

var body = document.createElement ("tbody"); (or thead or tfoot)

Not "need". Any table section element will do as an intermediate
between the TABLE and the TRs, and in some circumstances a TBODY would
be an inappropriate choice.
Link that to the table and the row to that:

table.appendChild (body);
body.appendChild (row);

And everything is hunky dorey!

So building a DOM structure that conforms to the structural
constraints of HTML results in the (reasonably) consistent handling of
that structure (including its rendering)? Now that is something that
you should expect to be able to "get away with".
I just wasted a big piece of my life on this one so I'm
hoping I can save some people the same heartache.
<snip>

Which would be better done by identifying the cause and effect
relationship that resulted in your issue rather than shouting about a
specific manifestation of the effect.

You problem is that you are attempting the script the interactions
with an HTML document before understanding what HTML is. That is an
approach that will leave you spending big pieces of your life stabbing
about in the dark trying to solve problems that never needed to occur
in the first place. And that is the real warning here.
 
T

Thomas 'PointedEars' Lahn

Henry said:
No, you absolutely should not expect to be able to "get away with"
that in an HTML DOM. The structural constraints of HTML do not allow a
TR element to be the direct child of any type of element except a
table section element (TBODY, THEAD or TFOOT). It makes as little
sense to attempt to make a TR a direct child of a TABLE as it would to
attempt to make one a direct child of a SELECT element.

The restriction enforced by the DOM is based on

http://www.w3.org/TR/html4/struct/tables.html#h-11.2.1
http://www.w3.org/TR/html4/sgml/loosedtd.html

However, it should be noted that the TBODY element is not necessary to write
in HTML 4.01 markup because both its start tag and its end tag are optional
in all relevant DTDs. Therefore it makes rather little sense to me to
enforce its creation in DOM scripting instead of having it automatically
generated where needed, but there it is.


PointedEars
 
H

Henry

Thomas said:
The restriction enforced by the DOM is based on

http://www.w3.org/TR/html4/struct/tables.html#h-11.2.1
http://www.w3.org/TR/html4/sgml/loosedtd.html

However, it should be noted that the TBODY element is not
necessary to write in HTML 4.01 markup because both its
start tag and its end tag are optional in all relevant DTDs.

That still results in a TBODY existing. Except in XHTML or course,
where TR may be direct children of TABLE (not a good idea but
understandable given XHTML having some desire to be 'compatible'
with HTML while not tolerating optional tags or implied elements).
Therefore it makes rather little sense to me to enforce its
creation in DOM scripting instead of having it automatically
generated where needed, but there it is.

While it is (obviously as it already happens) possible to 'fix'
attempts to create erroneous DOM structures that programmers attempt
to create by inserting omitted elements the attempt is not without
its issues. First there is what you would do in an XHTML DOM, where
the intervening table section elements is not required, but can be
used; do you add one regardless or always omit them. Then there is
the situation in HTML; if a TR is appended to a table and the table
already has a TBODY do you instead append to the existing TBODY or
add a new one, and if a second TR is appended does it get added to
an existing TBODY (possibly the one added by the last appended TR)
or does it get a new TBODY of its own. Without a very clear
standard on how this situation it to be handled you are likely to
get different outcomes from each and every browser. Followed by lots
of complaints that browsers have bugs because they are not doing
precisely the same as other browsers.

On the whole it is probably better to have the browser create the
DOM structure exactly as the programmer asks it to, and let the
programmer be responsible for building a structure that makes
sense in the type of DOM they are using.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top