Forum Moderators: open

Message Too Old, No Replies

Help with innerhtml and concatenation

how do I get the contents of a div that contains other divs?

         

codebreaker

8:25 pm on Jul 12, 2004 (gmt 0)

10+ Year Member



An example html document is at the bottom of this post. I am relatively new to innerhtml, so any help, guidance, or suggestions are welcome. I am attempting to use a div as a template, to concatenate as many times as I need, depending on how many records there are. I have made the div (called 'buffer' in my example) invisible, I load in the data, and then append the div's innerhtml to a variable ('buff'), and repeat. Then I load the contents of the variable into another div (called 'disp' in my example) that is visible. Intuitively, this seems like it should work, but I only get the last record that was loaded. What am I doing wrong?

Is innerhtml not the way to do this? Will I need to go to the DOM? Or maybe just hard code the html table tags into the script? The layout isn't going to get any more complicated than this, so it wouldn't be the end of the world, but this post is more about why it doesn't work, and ideally, it would be nice to separate the script from the html.

Thanks alot, Code-Breaker


<!DOCTYPE html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<script type="text/javascript">
function process() {
var buff = "";
var names = new Array(2);
var emails = new Array(2);

names[0] = "Joe Smith";
names[1] = "Harry Jones";
emails[0] = "jsmith@here.com";
emails[1] = "hjones@here.com";

buff = "<P><B>Personnel: " + names.length + "</B></P>";
for(var e=0; e < names.length; e++) {
document.getElementById("name").innerHTML = names[e];
document.getElementById("email").innerHTML = emails[e];
buff += document.getElementById("buffer").innerHTML;
alert(buff);
}
document.getElementById("disp").innerHTML = buff;
}
</script>
</head>
<body BGCOLOR="#bebebe" onload="process()">
<TABLE CELLPADDING="0" CELLSPACING="9" BORDER="0">
<DIV ID="buffer" style="display: none">
<TR>
<TD>
<B><DIV ID="name">NAME</DIV></B>
<DIV ID="email">EMAIL</DIV>
</TD>
</TR>
</DIV>
<!-- #EndTemplate -->

<DIV ID="disp">
</DIV>

</TABLE>
</body>

</html>

Bernard Marx

10:38 pm on Jul 12, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I think I see what's going on. I dare say it's probably not the best way to go about it. It is true that, where IE is concerned, building really large tables dynamically can be done more quickly by concatenating, then using
innerHTML
. But then you'd have to build the entire table like that, rather than just parts of it. Some (all?) browsers don't like having their actual table structures manipulated using
innerHTML
.

There are a couple of things in your template that are, more than likely, illegal:

1.

<div>
wrapped in
<b>
tags. [block can't be child of inline element].
2.
<div> 
tags in table - hmmm...suspicious.

I've gone for a DOM approach, but using the normal element creation methods, rather than specific table methods. I've stayed with

innerHTML
. It's well supported these days, but you might want to think about using
createTextNode
, if you want to be 100% safe.

I have changed the arrays to a single, 2D array, just to keep the name/email pairs together, and written it in literal notation. In fact, an object would be even better for this, if you didn't want the length printed immediately. Oh yes, I didn't know where you wanted some bits, so I missed them out! Don't bother with formatting tags (<b> etc). Use CSS.

All things considered, it might be more sensible at the moment to just write the HTML!

<!DOCTYPE html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<script type="text/javascript">
function process()
{
var names =
[
["Joe Smith","jsmith@here.com"],
["Harry Jones","hjones@here.com"]
]

var table = document.getElementById("emailtable")
var tbody = table.getElementsByTagName("tbody")[0]
var row, cell;

for(var e=0; e<names.length; e++)
{
row = document.createElement("tr")
tbody.appendChild(row)

cell = document.createElement('<td class="name">')
cell.innerHTML = names[e][0]
row.appendChild(cell)

cell = document.createElement('<td class="email">')
cell.innerHTML = names[e][1]
row.appendChild(cell)
}
}
</script>
</head>
<body BGCOLOR="#bebebe" onload="process()">

<TABLE id="emailtable" CELLPADDING="0" CELLSPACING="9" BORDER="0">
<!-- could use a TH element here instead -->
<TR id="head"><TD>NAME</TD><TD>EMAIL</TD></TR>
</TABLE>
</body>

</html>

codebreaker

11:24 pm on Jul 12, 2004 (gmt 0)

10+ Year Member



Bernard, that is an awesome reply. Your example works perfectly. Thank you so much!

I avoided the DOM because I hadn't used it before, but I can see it isn't that intimidating.

One quick follow up...how do you set a cell property? In particular, I want to set a cell's colspan, as well as align properties.

Thanks again, this was really above and beyond. -Code-Breaker

codebreaker

4:14 am on Jul 13, 2004 (gmt 0)

10+ Year Member



Nevermind that last follow-up, I came to my senses and figured it out. Thanks again. -Code-Breaker