vizskywalker 0 Report post Posted October 31, 2007 I'm writing a search function to search a MySQL database I have. The search uses AJAX with a php server to search the database and generate a result. The result is passed back as a DOM object to the javascript, which then parses the result into an xhtml table. I then add the table to my page. This works just fine under Firefox. However, under IE (version 7, so I assume others as well), the table doesn't display. I used the IE Developer Toolbar to look at the DOM, and the table has been successfully added to the DOM, but it isn't showing up. Interestingly, the property hasLayout is set to -1, which I assume means false even though MSDN claims that tables always have a hasLayout property of true. The javascript snippet is as follows: /* Add the Headers */ // Create the Headers Row var headers = document.createElement("tr"); headers.setAttribute("class", "Compendium"); // Create the Number Header var number = document.createElement("td"); number.setAttribute("class", "Compendium"); //number.innerHTML = "Number"; number.innerHTML = "Number"; headers.appendChild(number); // Create the Name Header var name = document.createElement("td"); name.setAttribute("class", "Compendium"); name.innerHTML = "Name"; headers.appendChild(name); // Create the Element Header var element = document.createElement("td"); element.setAttribute("class", "Compendium"); element.innerHTML = "Element"; headers.appendChild(element); // Create the Expansion Header var expansion = document.createElement("td"); expansion.setAttribute("class", "Compendium"); element.innerHTML = "Expansion"; headers.appendChild(expansion); // Create the Card Type Header var cardtype = document.createElement("td"); cardtype.setAttribute("class", "Compendium"); cardtype.innerHTML = "Card Type"; headers.appendChild(cardtype); // Create the Primary Type Header var primarytype = document.createElement("td"); primarytype.setAttribute("class", "Compendium"); primarytype.innerHTML = "Type 1"; headers.appendChild(primarytype); // Create the Secondary Type Header var secondarytype = document.createElement("td"); secondarytype.setAttribute("class", "Compendium"); secondarytype.innerHTML = "Type 2"; headers.appendChild(secondarytype); // Create the Cost Header var cost = document.createElement("td"); cost.setAttribute("class", "Compendium"); cost.innerHTML = "Cost"; headers.appendChild(cost); // Create the Cost Header var actions = document.createElement("td"); actions.setAttribute("class", "Compendium"); actions.innerHTML = "Actions"; headers.appendChild(actions); // Create the Attack Header var attack = document.createElement("td"); attack.setAttribute("class", "Compendium"); attack.innerHTML = "Attack"; headers.appendChild(attack); // Create the Defense Header var defense = document.createElement("td"); defense.setAttribute("class", "Compendium"); defense.innerHTML = "Defense"; headers.appendChild(defense); // Create the Move Header var move = document.createElement("td"); move.setAttribute("class", "Compendium"); move.innerHTML = "Move"; headers.appendChild(move); // Create the Game Text Header var gametext = document.createElement("td"); gametext.setAttribute("class", "Compendium"); gametext.innerHTML = "Game Text"; headers.appendChild(gametext); // Create the Story Text Header var storytext = document.createElement("td"); storytext.setAttribute("class", "Compendium"); storytext.innerHTML = "Story Text"; headers.appendChild(storytext); // Create the Rarity Header var rarity = document.createElement("td"); rarity.setAttribute("class", "Compendium"); rarity.innerHTML = "Rarity"; headers.appendChild(rarity); // Create the Artist Header var artist = document.createElement("td"); artist.setAttribute("class", "Compendium"); artist.innerHTML = "Artist"; headers.appendChild(artist); compendiumResults.appendChild(headers); // Add Each Card to the Table for (var index = 0; index < cards.length; ++index) { // Create the Headers Row var card = document.createElement("tr"); card.setAttribute("class", "Compendium"); // Create the Number Header var number = document.createElement("td"); number.setAttribute("class", "Compendium"); if (cards[index].childNodes[0].firstChild) { number.innerHTML = cards[index].childNodes[0].firstChild.nodeValue; } card.appendChild(number); // Create the Name Header var name = document.createElement("td"); name.setAttribute("class", "Compendium"); if (cards[index].childNodes[1].firstChild) { name.innerHTML = cards[index].childNodes[1].firstChild.nodeValue; } card.appendChild(name); // Create the Element Header var element = document.createElement("td"); element.setAttribute("class", "Compendium"); if (cards[index].childNodes[2].firstChild) { element.innerHTML = cards[index].childNodes[2].firstChild.nodeValue; } card.appendChild(element); // Create the Expansion Header var expansion = document.createElement("td"); expansion.setAttribute("class", "Compendium"); if (cards[index].childNodes[3].firstChild) { expansion.innerHTML = cards[index].childNodes[3].firstChild.nodeValue; } card.appendChild(expansion); // Create the Card Type Header var cardtype = document.createElement("td"); cardtype.setAttribute("class", "Compendium"); if (cards[index].childNodes[4].firstChild) { cardtype.innerHTML = cards[index].childNodes[4].firstChild.nodeValue; } card.appendChild(cardtype); // Create the Primary Type Header var primarytype = document.createElement("td"); primarytype.setAttribute("class", "Compendium"); if (cards[index].childNodes[5].firstChild) { primarytype.innerHTML = cards[index].childNodes[5].firstChild.nodeValue; } card.appendChild(primarytype); // Create the Secondary Type Header var secondarytype = document.createElement("td"); secondarytype.setAttribute("class", "Compendium"); if (cards[index].childNodes[6].firstChild) { secondarytype.innerHTML = cards[index].childNodes[6].firstChild.nodeValue; } card.appendChild(secondarytype); // Create the Cost Header var cost = document.createElement("td"); cost.setAttribute("class", "Compendium"); if (cards[index].childNodes[7].firstChild) { cost.innerHTML = cards[index].childNodes[7].firstChild.nodeValue; } card.appendChild(cost); // Create the Cost Header var actions = document.createElement("td"); actions.setAttribute("class", "Compendium"); if (cards[index].childNodes[8].firstChild) { actions.innerHTML = cards[index].childNodes[8].firstChild.nodeValue; } card.appendChild(actions); // Create the Attack Header var attack = document.createElement("td"); attack.setAttribute("class", "Compendium"); if (cards[index].childNodes[9].firstChild) { attack.innerHTML = cards[index].childNodes[9].firstChild.nodeValue; } card.appendChild(attack); // Create the Defense Header var defense = document.createElement("td"); defense.setAttribute("class", "Compendium"); if (cards[index].childNodes[10].firstChild) { defense.innerHTML = cards[index].childNodes[10].firstChild.nodeValue; } card.appendChild(defense); // Create the Move Header var move = document.createElement("td"); move.setAttribute("class", "Compendium"); if (cards[index].childNodes[11].firstChild) { move.innerHTML = cards[index].childNodes[11].firstChild.nodeValue; } card.appendChild(move); // Create the Game Text Header var gametext = document.createElement("td"); gametext.setAttribute("class", "Compendium"); if (cards[index].childNodes[12].firstChild) { gametext.innerHTML = cards[index].childNodes[12].firstChild.nodeValue; } card.appendChild(gametext); // Create the Story Text Header var storytext = document.createElement("td"); storytext.setAttribute("class", "Compendium"); if (cards[index].childNodes[13].firstChild) { storytext.innerHTML = cards[index].childNodes[13].firstChild.nodeValue; } card.appendChild(storytext); // Create the Rarity Header var rarity = document.createElement("td"); rarity.setAttribute("class", "Compendium"); if (cards[index].childNodes[14].firstChild) { rarity.innerHTML = cards[index].childNodes[14].firstChild.nodeValue; } card.appendChild(rarity); // Create the Artist Header var artist = document.createElement("td"); artist.setAttribute("class", "Compendium"); if (cards[index].childNodes[15].firstChild) { artist.innerHTML = cards[index].childNodes[15].firstChild.nodeValue; } card.appendChild(artist); compendiumResults.appendChild(card); }Any ideas would be appreciated.Thanks,~Viz Share this post Link to post Share on other sites
turbopowerdmaxsteel 0 Report post Posted October 31, 2007 You haven't mentioned what compendiumResults is. I am assuming it is the table. The table element contains a tbody element which in turn contains the tr elements. So, set the compendiumResults to the table's tbody. compendiumResults = documents.getElementById('myTableName').getElementsByTagName('tbody')[0]; Firefox seems to allow addition of trs to the table element itself. Whereas, Internet Explorer is a bit strict on this. Hope this helps. Max. Share this post Link to post Share on other sites
vizskywalker 0 Report post Posted November 1, 2007 Thanks, I actually figured that out before I read your post. After looking at the DOM specification, it seems that in theory, tbody is not required. Interesting tidbit, though, when running the code under Safari 2, or the original Safari 3 beta for windows, the elements are added, but do not appear to be in a table, and no class is associated with them. Any ideas as to why?Edit: I think I've determined the problem, but not the cause of the problem. No matter what tag type I pass to document.createElement(), I seem to be getting an Element as opposed to an HTML<Type>Element. This would cause display issues, but I'm not sure why this is happening.Edit: So, after further experimentation, it seems I can successfully change the class using the className properly, but only if I pick an internal style. It doesn't seem to work for external styles unless the object was always present.~Viz Share this post Link to post Share on other sites
turbopowerdmaxsteel 0 Report post Posted November 1, 2007 You are correct. Because its XHTML, any type of tag can be created and added by using the DOM functions - Document.CreateElement and <Element>.AppendChild. But, only those that are in the HTML specification will effect the Document. I don't think Internet Explorer allows creation of arbitrary tags, although Firefox certainly does.The following code for example, works properly with Opera, Firefox and Safari. But, Internet Explorer tells a different story. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" xmlns="www.w3.org/1999/xhtml/" <body> <table id="myTable" border="1"> </table> </body> <script type="text/javascript"> window.onload = function() { var tab = document.getElementById('myTable'); var tr = document.createElement('tr'); var td = document.createElement('td'); td.innerHTML = "This is a column"; tr.appendChild(td); tab.appendChild(tr); alert(tab.innerHTML); } </script></html> This will clear up the working on these browsers. Opera, Firefox and Safari will show a message box with the text: <tr><td>This is a column</td></tr>. Whereas, Internet Explorer displays <tbody></tbody><tr><td>This is a column</td></tr>. As you can see, IE adds the tbody element to the table as soon as it is created. So, our TR got appended at the end.So, what if we added a tbody manually? Lets check it out. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd xmlns="www.w3.org/1999/xhtml/ <body> <table id="myTable" border="1"> </table> </body> <script type="text/javascript"> window.onload = function() { var tab = document.getElementById('myTable'); var tbody = document.createElement('tbody'); var tr = document.createElement('tr'); var td = document.createElement('td'); td.innerHTML = "This is a column"; tr.appendChild(td); tbody.appendChild(tr); tab.appendChild(tbody); alert(tab.innerHTML); } </script></html> Now, the code displayed by IE contains two tbody tags. Yet, it works. The other browsers display the expected code <tbody><tr><td>This is a column</td></tr></tbody>.The question is, should the tbody be automatically added to a table? I don't think so. Columns are supposed to be added to Rows and Rows are meant to be added to the table. IE should follow the standards set by the others and save the developers from all the IE specific coding. Share this post Link to post Share on other sites
vizskywalker 0 Report post Posted November 1, 2007 I'd agree, except tbody isn't only a thing required by IE, it's also a well established part of the DOM for XHTML 1.1, so I see no problem with it. The sample code works fine in Safari, which is my current problem place. I even modified it so that the table was generated dynamically when the body loaded, and that worked. But I can't figure out what's wrong with my code that I showed you up above to prevent the table from appearing even as a table in Safari. All of the data just gets shown as seeming stream of text, with no proper style.Edit: I just tried another experiment, and found the cause of the issue. Since my pages are XHTML 1.1, they should be served as application/xhtml+xml, and I serve them as such to any browser that accepts it. Safari is included on that list. When the page is served as applicaton/xhtml+xml, Safari fails on your code. However, when the page is served as text/html, the code works. So the problem is somehow related to how Safari handles application/xhtml+xml. Since this code works in the new versions of Safari, is this likely to have been an issue with the old version of Safari? Or does the new version do nice error checking to display if I make a mistake and my code is wrong?~Viz Share this post Link to post Share on other sites