davej Posted March 31, 2013 Share Posted March 31, 2013 The following code seems to work, but is it correct? Thanks. <!DOCTYPE html><html><head><meta charset="utf-8"><title>add child</title><script>window.onload = function() {assignfn();}var states = new Array('Alabama','Alaska','Arizona','Arkansas','California','Colorado','Connecticut','Utah','Wyoming');function assignfn() {var statesel = document.getElementById('statesel');for (var i=0 ; i<states.length ; i++){var newnode=document.createElement("option");var textnode=document.createTextNode(states[i]);newnode.appendChild(textnode);statesel.appendChild(newnode);newnode.value = states[i];}}//end of assign</script></head><body><p>Data entry:</p><form action="http://localhost" method="get"><select id="statesel" name="state"></select><button type="submit">Submit</button></form></body></html> http://www.w3schools.com/tags/tag_option.asp Link to comment Share on other sites More sharing options...
davej Posted March 31, 2013 Author Share Posted March 31, 2013 Or what if you just do the same thing this way? function assignfn() {var statesel = document.getElementById('statesel');for (var i=0 ; i<states.length ; i++){var newnode=document.createElement("option");statesel.appendChild(newnode);newnode.value = states[i];newnode.innerHTML = states[i];}}//end of assign</script> Link to comment Share on other sites More sharing options...
jeffman Posted March 31, 2013 Share Posted March 31, 2013 Creating the text node (your first technique) is probably more "correct," but I usually use innerHTML to add text to an element. Curiously, I rarely use it to add HTML to an element. Options are weird, though. There have been methods for adding options dynamically before all the DOM methods were standardized. I think all the browsers support both of your techniques, but I'd check it out anyway. And don't worry about which technique benchmarks faster. Either way should work with no noticeable latency. Link to comment Share on other sites More sharing options...
davej Posted March 31, 2013 Author Share Posted March 31, 2013 Well, I'm confused when there are always two or three or more ways to do the same thing. For example if I can simply say... newnode.id = 'id123';newnode.className = 'myclass'; ...to set valid attributes by name then why would I ever need createAttribute() ? http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_document_createattribute Link to comment Share on other sites More sharing options...
dsonesuk Posted March 31, 2013 Share Posted March 31, 2013 To add text for option element you should use .text, you should not use .innerHTML for ANY form element, especially not for textarea, where .value can be used. Link to comment Share on other sites More sharing options...
jeffman Posted March 31, 2013 Share Posted March 31, 2013 ...to set valid attributes by name then why would I ever need createAttribute() ?Creating and setting an attribute actually causes an HTML tag to contain an attribute. You can read it if you examine the innerHTML or use the inspect tool in your browser. Setting a property just using dot notation doesn't do that. Likewise, if you write a non-standard attribute in your HTML document, you probably can't read it using dot notation, but you should be able to read it using getAttribute. Link to comment Share on other sites More sharing options...
davej Posted March 31, 2013 Author Share Posted March 31, 2013 (edited) Well, just to have a clear example and avoid confusion, if I start with... <select name="state" id="statesel"></select> ...and I'm looking at creating the option tags here... <select name="state" id="statesel"> <option value="AL">Alabama</option> <option value="AK">Alaska</option> <option value="AZ">Arizona</option></select> I seem to be able to successfully add class, id, value for any of these option tags once the option node has been created by simply setting them with .id .className and .value. The textname is added with .innerHTML. Of course I'm not testing this with all browsers. Mostly I'm just looking at Firebug in Firefox. Maybe this simple approach could fail in some other browsers? Thanks Edited March 31, 2013 by davej Link to comment Share on other sites More sharing options...
davej Posted March 31, 2013 Author Share Posted March 31, 2013 (edited) To add text for option element you should use .text, you should not use .innerHTML for ANY form element, especially not for textarea, where .value can be used. You are right -- they show .text in the property list for the <option> tag...http://www.w3schools..._obj_option.asp ... but wait... the W3Schools page then says: "The Option object also supports the standard properties and events." Why do these property and method lists seem to get broken up? Edited March 31, 2013 by davej Link to comment Share on other sites More sharing options...
thescientist Posted April 1, 2013 Share Posted April 1, 2013 (edited) because properties and events are two different things. the events list is essentially methods that the element supports for doing event handling. Edited April 1, 2013 by thescientist Link to comment Share on other sites More sharing options...
davej Posted April 8, 2013 Author Share Posted April 8, 2013 because properties and events are two different things. the events list is essentially methods that the element supports for doing event handling. Ok, but what I meant is this... as an example... I go here... http://www.w3schools.com/jsref/dom_obj_core_document.asp ...and there is no listing for a method document.getElementsByName() But then I go here... http://www.w3schools.com/jsref/dom_obj_document.asp ...and there is an entry for the method document.getElementsByName() So where should I go to find the ultimate list of all methods that can be appended to a particular element? Thanks Link to comment Share on other sites More sharing options...
justsomeguy Posted April 8, 2013 Share Posted April 8, 2013 MDN has a decent reference: https://developer.mozilla.org/en-US/docs/DOM/document Link to comment Share on other sites More sharing options...
davej Posted May 5, 2013 Author Share Posted May 5, 2013 (edited) Since I'm back on this same topic I guess I'll resurrect this old thread. If I am adding a table to a form can I or should I -- build the entire table object -- and then add it as a child of the form? It seems strange to create an element and add children to it when it is not yet part of the document but is instead floating around in La-la land. Or should I add the table to the form and then add children to build it? Or is one way better than the other? Thanks. Edited May 5, 2013 by davej Link to comment Share on other sites More sharing options...
jeffman Posted May 5, 2013 Share Posted May 5, 2013 In the old days, when computers and browsers were slower, the accepted wisdom was to create the entire object, with all its children, before adding it to the DOM. This eliminated flicker as the bits and pieces popped into existence. Latency of this kind is no longer a problem (unless your table has thousands of elements, I guess) but I still do stuff like that old-school. La-la land has never been anything to worry about. It can even be a handy resource at times. Link to comment Share on other sites More sharing options...
davej Posted May 6, 2013 Author Share Posted May 6, 2013 (edited) My first iteration is simply a crude version of what I want using innerHTML. It does not seem to correctly create the table or correctly create the links/anchors. window.onload = function(){var out = document.getElementById('out');out.innerHTML = '';var tot = Number(filenames.length);var i = 0;while( i<(tot-7) ){ //print another table if there are eight more photos remainingout.innerHTML += '<table border="1"><tr>';for (var col=0 ; col<4 ; col++){out.innerHTML += '<td><a href="photos_t/'+ filenames[i] +'">';out.innerHTML += '<img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a></td>';i++;}out.innerHTML += '</tr><tr>';for (var col=0 ; col<4 ; col++){out.innerHTML += '<td><a href="photos_t/'+ filenames[i] +'">';out.innerHTML += '<img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a></td>';i++;}out.innerHTML += '</tr></table><br/>';}//end while}//end onload My next iteration is a little better. It actually works... window.onload = function(){var out = document.getElementById('out');out.innerHTML = '';var tot = Number(filenames.length);var i = 0;while( i<(tot-7) ){ //print another table if there are eight more photos remainingvar newTable = document.createElement("table");var row0 = newTable.insertRow(0);var cell00 = row0.insertCell(0);var cell01 = row0.insertCell(1);var cell02 = row0.insertCell(2);var cell03 = row0.insertCell(3);cell00.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;cell01.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;cell02.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;cell03.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;var row1 = newTable.insertRow(1);var cell10 = row1.insertCell(0);var cell11 = row1.insertCell(1);var cell12 = row1.insertCell(2);var cell13 = row1.insertCell(3);cell10.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;cell11.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;cell12.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;cell13.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;out.appendChild(newTable); //append the table to the out divvar br = document.createElement("br");out.appendChild(br); //append <br/> to the out div}//end while}//end onload Edited May 6, 2013 by davej Link to comment Share on other sites More sharing options...
justsomeguy Posted May 6, 2013 Share Posted May 6, 2013 If you're using innerHTML then you need to write the entire string at once. Build the HTML string in another variable and once you have all the HTML, then write to innerHTML. The browser will automatically "fix" innerHTML, so if you write an incomplete string to it it's going to add any missing things like closing tags to compete the elements. DD was talking about creating and appending nodes using the DOM methods, not using innerHTML. You're not creating new DOM nodes, you're creating a string of HTML and then writing it to the element. Link to comment Share on other sites More sharing options...
davej Posted May 6, 2013 Author Share Posted May 6, 2013 Ok, I will go back and try creating the entire string before using innerHTML. I'm trying to proceed from the simple-minded approach to the more proper child-node approach. Currently I'm at this point... window.onload = function(){var out = document.getElementById('out');out.innerHTML = '';var tot = Number(filenames.length);var i = 0;while( i<(tot-7) ){ //print another table if there are eight more photos remainingvar newTable = document.createElement("table");var newAttrib = document.createAttribute("border");newAttrib.value = "1";newTable.setAttributeNode(newAttrib); //append border="1" to the tablevar row0 = newTable.insertRow(0);var cell00 = row0.insertCell(0);var cell01 = row0.insertCell(1);var cell02 = row0.insertCell(2);var cell03 = row0.insertCell(3);cell00.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;cell01.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;cell02.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;cell03.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;var row1 = newTable.insertRow(1);var cell10 = row1.insertCell(0);var cell11 = row1.insertCell(1);var cell12 = row1.insertCell(2);var cell13 = row1.insertCell(3);cell10.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;cell11.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;cell12.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;cell13.innerHTML = '<a href="photos_t/'+ filenames[i] +'"><img alt="'+ filenames[i] +'" src="photos_t/'+ filenames[i] +'" width="200"/></a>';i++;out.appendChild(newTable); //append the table to the out divvar br = document.createElement("br");out.appendChild(br); //append <br/> to the out div}//end while}//end onload Link to comment Share on other sites More sharing options...
jeffman Posted May 6, 2013 Share Posted May 6, 2013 What you have here ^^ is more correct. My only concern is that it repeats a lot of the same code. Some of the steps could be modularized, especially the construction of the innerHTML strings. Link to comment Share on other sites More sharing options...
davej Posted May 6, 2013 Author Share Posted May 6, 2013 Yes, I'm sure I can compress that down quite a bit, but will I then be able to abandon the innerHTML portions? Link to comment Share on other sites More sharing options...
jeffman Posted May 6, 2013 Share Posted May 6, 2013 Sure. Just use createElement to make the <a> and <img> elements. Then set their attributes. The only thing that varies is the value of i, so build a little function that accepts i as an argument and returns the populated <a> as an element object. Link to comment Share on other sites More sharing options...
davej Posted May 6, 2013 Author Share Posted May 6, 2013 Here is my compressed version that still uses innerHTML... window.onload = function(){var out = document.getElementById('out');out.innerHTML = '';var tot = Number(filenames.length);var i = 0;while( i<(tot-7) ){ //print another table if there are eight more photos remainingvar newTable = document.createElement("table");var newAttrib = document.createAttribute("border");newAttrib.value = "1";newTable.setAttributeNode(newAttrib); //append border="1" to the tablevar row = [newTable.insertRow(0), newTable.insertRow(1)];var cell = [];for (var j=0 ; j<4 ; j++){cell[j] = row[0].insertCell(j);}var strs = ['<a href="photos_t/','"><img alt="','" src="photos_t/','" width="200"/></a>'];for (var j=0 ; j<4 ; j++){cell[j].innerHTML = strs[0]+ filenames[i] +strs[1]+ filenames[i] +strs[2]+ filenames[i] +strs[3];i++;}for (var j=0 ; j<4 ; j++){cell[j] = row[1].insertCell(j);}for (var j=0 ; j<4 ; j++){cell[j].innerHTML = strs[0]+ filenames[i] +strs[1]+ filenames[i] +strs[2]+ filenames[i] +strs[3];i++;}out.appendChild(newTable); //append the table to the out divvar br = document.createElement("br");out.appendChild(br); //append <br/> to the out div}//end while}//end onload Link to comment Share on other sites More sharing options...
davej Posted May 6, 2013 Author Share Posted May 6, 2013 This isn't working... Is the anchor a child of the cell and the image a child of the anchor? window.onload = function(){var out = document.getElementById('out');out.innerHTML = '';var tot = filenames.length;var i = 0;while( i<(tot-7) ){ //print another table if there are eight more photos remainingvar newTable = document.createElement("table");var newAttrib = document.createAttribute("border");newAttrib.value = "1";newTable.setAttributeNode(newAttrib); //append border="1" to the tablevar row = [newTable.insertRow(0), newTable.insertRow(1)];var cell = [row[0].insertCell(0),row[0].insertCell(1),row[0].insertCell(2),row[0].insertCell(3)];var strs = ['<a href="photos_t/','"><img alt="','" src="photos_t/','" width="200"/></a>'];for (var j=0 ; j<4 ; j++){//cell[j].innerHTML = strs[0]+ filenames[i] +strs[1]+ filenames[i] +strs[2]+ filenames[i] +strs[3];cell[j].appendChild(cellGuts(i));i++;}for (var j=0 ; j<4 ; j++){cell[j] = row[1].insertCell(j);}for (var j=0 ; j<4 ; j++){//cell[j].innerHTML = strs[0]+ filenames[i] +strs[1]+ filenames[i] +strs[2]+ filenames[i] +strs[3];cell[j].appendChild(cellGuts(i));i++;}out.appendChild(newTable); //append the table to the out divvar br = document.createElement("br");out.appendChild(br); //append <br/> to the out div}//end while}//end onloadfunction cellGuts(i){var newImg = document.createElement("image");var newAnchor = document.createElement("anchor");var newAttrib = document.createAttribute("alt");newAttrib.value = filenames[i];newImg.setAttributeNode(newAttrib);newAttrib = document.createAttribute("src");newAttrib.value = 'photos_t/' + filenames[i];newImg.setAttributeNode(newAttrib);newAttrib = document.createAttribute("width");newAttrib.value = '200';newImg.setAttributeNode(newAttrib);newAttrib = document.createAttribute("href");newAttrib.value = 'photos_t/' + filenames[i];newAnchor.setAttributeNode(newAttrib);newAnchor.appendChild(newImg);return newAnchor;} Link to comment Share on other sites More sharing options...
davej Posted May 6, 2013 Author Share Posted May 6, 2013 This doesn't work either... window.onload = function(){var out = document.getElementById('out');out.innerHTML = '';var tot = filenames.length;var i = 0;var child1;while( i<(tot-7) ){ //print another table if there are eight more photos remainingvar newTable = document.createElement("table");var newAttrib = document.createAttribute("border");newAttrib.value = "1";newTable.setAttributeNode(newAttrib); //append border="1" to the tablevar row = [newTable.insertRow(0), newTable.insertRow(1)];var cell = [row[0].insertCell(0),row[0].insertCell(1),row[0].insertCell(2),row[0].insertCell(3)];//var strs = ['<a href="photos_t/','"><img alt="','" src="photos_t/','" width="200"/></a>'];for (var j=0 ; j<4 ; j++){//cell[j].innerHTML = strs[0]+ filenames[i] +strs[1]+ filenames[i] +strs[2]+ filenames[i] +strs[3];child1 = cellGuts(i);cell[j].appendChild(child1);i++;}for (var j=0 ; j<4 ; j++){cell[j] = row[1].insertCell(j);}for (var j=0 ; j<4 ; j++){//cell[j].innerHTML = strs[0]+ filenames[i] +strs[1]+ filenames[i] +strs[2]+ filenames[i] +strs[3];child1 = cellGuts(i);cell[j].appendChild(child1);i++;}out.appendChild(newTable); //append the table to the out divvar br = document.createElement("br");out.appendChild(br); //append <br/> to the out div}//end while}//end onloadfunction cellGuts(i){var newImg = document.createElement("image");var newAnchor = document.createElement("anchor");var newAttrib = document.createAttribute("alt");newAttrib.value = filenames[i];newImg.setAttributeNode(newAttrib);newAttrib = document.createAttribute("src");newAttrib.value = 'photos_t/' + filenames[i];newImg.setAttributeNode(newAttrib);newAttrib = document.createAttribute("width");newAttrib.value = '200';newImg.setAttributeNode(newAttrib);newAttrib = document.createAttribute("href");newAttrib.value = 'photos_t/' + filenames[i];newAnchor.setAttributeNode(newAttrib);newAnchor.appendChild(newImg);return newAnchor;} Link to comment Share on other sites More sharing options...
justsomeguy Posted May 6, 2013 Share Posted May 6, 2013 What happens when you run it? Are you checking for Javascript errors? Link to comment Share on other sites More sharing options...
jeffman Posted May 6, 2013 Share Posted May 6, 2013 Could you post the filenames array so I can run this? Also, I think you went overboard with all those attribute nodes. Have you tried simple dot notation? Link to comment Share on other sites More sharing options...
davej Posted May 6, 2013 Author Share Posted May 6, 2013 (edited) My goal was to write some JS that would make it much quicker and easier for me to post a new page of trip photos. Here is my original manually-constructed page: http://www.stlnetwor...013/photos.html Here is my JS-driven page: http://www.stlnetwor...est/photos.html Here is the latest non-working version: http://www.stlnetwork.net/kayak/whitewater/test/photos4.html Edited May 6, 2013 by davej Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now