I am having problems with the following HTML code. The code works for FF but not IE. The code below does two things. It create a SELECT statically in HTML and then dynamically via JavaScript. The dynamically created SELECT is ill-behaved. It's size is not what was requested and it's onchange callback is never fired. The static SELECT works without a hitch. Any help with this will be greatly appreciated. Code: <html> <head> <script type="text/javascript" language="JavaScript"> <!-- Hide code from older browsers function writeTime() { document.write("<p align='right'><i>"+Date()+"<\/i><\/p>"); } function writeBrowserVersion() { document.write("<p align='center'><b>You are using "+navigator.appName+" "+navigator.appVersion+"<\/b><\/p>"); } function previewMediaChange(strValue) { alert('select onchange callback fired with parameter: ' + strValue); } function loadSelect() { var nodeDiv; var nodeSelect; var iSelectSize; var nodeOptGroup; var nodeOption; var nodeText; document.write("<DIV id='eipEditContainer'>"); nodeDiv = document.getElementById('eipEditContainer'); if ( nodeDiv != null ) { //alert('eipEditContainer DIV created!!!'); nodeSelect = document.createElement('select'); nodeSelect.setAttribute('onchange', 'previewMediaChange(value)'); iSelectSize = 5; nodeSelect.setAttribute('size', '' + iSelectSize); nodeOptGroup = document.createElement('optgroup'); nodeOptGroup.setAttribute('label', 'In this workspace:'); nodeOption = document.createElement('option'); nodeOption.setAttribute('value', 'ws/MickeyMouse.jpg'); nodeText = document.createTextNode('MickeyMouse.jpg'); nodeOption.appendChild(nodeText); nodeOptGroup.appendChild(nodeOption); nodeOption = document.createElement('option'); nodeOption.setAttribute('value', 'ws/DonaldAndDaisyDuck.gif'); nodeText = document.createTextNode('DonaldAndDaisyDuck.gif'); nodeOption.appendChild(nodeText); nodeOptGroup.appendChild(nodeOption); nodeSelect.appendChild(nodeOptGroup); nodeOptGroup = null; nodeOptGroup = document.createElement('optgroup'); nodeOptGroup.setAttribute('label', 'In this module:'); nodeOption = document.createElement('option'); nodeOption.setAttribute('value', 'ws/goofy.gif'); nodeText = document.createTextNode('goofy.gif'); nodeOption.appendChild(nodeText); nodeOptGroup.appendChild(nodeOption); nodeOption = document.createElement('option'); nodeOption.setAttribute('value', 'ws/minnie-mouse.jpg'); nodeText = document.createTextNode('minnie-mouse.jpg'); nodeOption.appendChild(nodeText); nodeOptGroup.appendChild(nodeOption); nodeSelect.appendChild(nodeOptGroup); nodeDiv.appendChild(nodeSelect); } } // Stop hiding code --> </script> </head> <body> Hi and welcome to my select callback test. <script type="text/javascript" language="JavaScript"> <!-- Hide code from older browsers writeTime(); writeBrowserVersion(); // Stop hiding code --> </script> <DIV> A statically created select: </DIV> <select onchange="previewMediaChange(value)" id="eipFigureSelect" size="5"> <optgroup label="In this module:"> <option value="ws/MickeyMouse.jpg">MickeyMouse.jpg</option> <option value="ws/DonaldAndDaisyDuck.gif">DonaldAndDaisyDuck.gif</option> </optgroup> <optgroup label="In the workarea:"> <option value="ws/goofy.gif">goofy.gif</option> <option value="ws/minnie-mouse.jpg">minnie-mouse.jpg</option> <option value="ws/minnie-mouse.psd">minnie-mouse.psd</option> </optgroup> </select> <DIV> A dynamically created select: </DIV> <script type="text/javascript" language="JavaScript"> <!-- Hide code from older browsers loadSelect(); // Stop hiding code --> </script> </body> </html>
It seems the setAttribute doesn't allow you to add the onChange in IE. You can make a new function for it though. Discussion about onChange I'm not sure why adding options didn't work the way you have it but I was able to add them a different way which seems to work ok. I tested this on IE 5 and FireFox 1.5 Code: if ( nodeDiv != null ) { //alert('eipEditContainer DIV created!!!'); nodeSelect = document.createElement('select'); nodeSelect.onchange = new Function("previewMediaChange(this.value);"); nodeSelect.setAttribute('onChange', 'previewMediaChange(value)'); nodeSelect.setAttribute('name', 'dynamicSelect'); nodeSelect.setAttribute('id', 'dynamicSelect'); iSelectSize = 5; nodeSelect.setAttribute('size', '' + iSelectSize); nodeDiv.appendChild(nodeSelect); } selectObject = document.getElementById("dynamicSelect"); selectObject.options[selectObject.length] = new Option("MickeyMouse.jpg", "ws/MickeyMouse.jpg", false, false); selectObject.options[selectObject.length] = new Option("DonaldAndDaisyDuck.gif", "ws/DonaldAndDaisyDuck.gif", false, false); selectObject.options[selectObject.length] = new Option("goofy.gif", "ws/goofy.gif", false, false); selectObject.options[selectObject.length] = new Option("minnie-mouse.jpg", "ws/minnie-mouse.jpg", false, false); selectObject.options[selectObject.length] = new Option("minnie-mouse.psd", "ws/minnie-mouse.psd", false, false);
Just use innerHTML: Code: <html> <head> <script type="text/javascript" language="JavaScript"> <!-- Hide code from older browsers function writeTime() { document.write("<p align='right'><i>"+Date()+"<\/i><\/p>"); } function writeBrowserVersion() { document.write("<p align='center'><b>You are using "+navigator.appName+" "+navigator.appVersion+"<\/b><\/p>"); } function previewMediaChange(strValue) { alert('select onchange callback fired with parameter: ' + strValue); } function loadSelect() { var nodeDiv; var nodeSelect; var iSelectSize; var nodeOptGroup; var nodeOption; var nodeText; document.write("<DIV id='eipEditContainer'>"); var divtext = "<select onchange='previewMediaChange(value)' size='5'>"; var divtext = divtext + "<optgroup label='In this module:'>"; var divtext = divtext + "<option value='ws/MickeyMouse.jpg'>MickeyMouse.jpg</option>"; var divtext = divtext + "<option value='ws/DonaldAndDaisyDuck.gif'>DonaldAndDaisyDuck.gif</option>"; var divtext = divtext + "</optgroup>"; var divtext = divtext + "<optgroup label='In the workarea:'>"; var divtext = divtext + "<option value='ws/goofy.gif'>goofy.gif</option>"; var divtext = divtext + "<option value='ws/minnie-mouse.jpg'>minnie-mouse.jpg</option>"; var divtext = divtext + "<option value='ws/minnie-mouse.psd'>minnie-mouse.psd</option>"; var divtext = divtext + "</optgroup>"; document.getElementById('eipEditContainer').innerHTML = divtext; } // Stop hiding code --> </script> </head> <body> Hi and welcome to my select callback test. <script type="text/javascript" language="JavaScript"> <!-- Hide code from older browsers writeTime(); writeBrowserVersion(); // Stop hiding code --> </script> <DIV> A statically created select: </DIV> <select onchange="previewMediaChange(value)" id="eipFigureSelect" size="5"> <optgroup label="In this module:"> <option value="ws/MickeyMouse.jpg">MickeyMouse.jpg</option> <option value="ws/DonaldAndDaisyDuck.gif">DonaldAndDaisyDuck.gif</option> </optgroup> <optgroup label="In the workarea:"> <option value="ws/goofy.gif">goofy.gif</option> <option value="ws/minnie-mouse.jpg">minnie-mouse.jpg</option> <option value="ws/minnie-mouse.psd">minnie-mouse.psd</option> </optgroup> </select> <DIV> A dynamically created select: </DIV> <DIV id='eipEditContainer'> <script type="text/javascript" language="JavaScript"> <!-- Hide code from older browsers loadSelect(); // Stop hiding code --> </script> </body> </html>
I'd go with innerHTML. It's the text-changing property that doesn't make you load the page again and it rocks for <DIV>s. Dang it, droxford, why you take all the good ones?
Worked the first time on both IE and FF. Thanks!!! I am maintaining a base of JavaScript code that contains a whole lotta of calls to createElement() and appendChild() like you saw above: Code: nodeOption = document.createElement('option'); nodeOption.setAttribute('value', 'ws/MickeyMouse.jpg'); nodeText = document.createTextNode('MickeyMouse.jpg'); nodeOption.appendChild(nodeText); nodeOptGroup.appendChild(nodeOption); and this is the first I had to resort to using innerHTML My best guess is that there is likely an IE bug here, something along the lines of "freezing attribute values for SELECT elements at creation time". Thanks again.
No sweat. Here's a cute one I've been toying with in my spare time recently. It could use some cleaning up a little and it currently only works in IE (needs some simple tweaking to work in FF). But it's cute. HTML: <html> <head> <title>Untitled</title> <script language="javascript"> // this script will need to be adjusted if it is to be compatible with non-IE browsers totalrows=0; function adjustrow(dir){ var rowtext = ""; if (dir==0) { totalrows++; for (i=1;i<=4;i++){ rowtext = rowtext + "<input type=\"text\" name=\"txt" + totalrows + "_" + i + "\">"; } rowtext = rowtext + "<br>"; document.getElementById('textboxes').innerHTML = document.getElementById('textboxes').innerHTML + rowtext; } else { if (totalrows > 1){ var m = document.getElementById('textboxes').innerHTML.indexOf(totalrows+'_1'); m = m - 15; document.getElementById('textboxes').innerHTML = document.getElementById('textboxes').innerHTML.substring(0,m); totalrows--; } } } </script> </head> <body onLoad="addrow(0);"> <div id="textboxes"></div> <br> <input type="button" value=" + " onClick="adjustrow(0);"> <input type="button" value=" - " onClick="adjustrow(1);"> </body> </html>
droxford, what's the script s'posed to do? I tried it in IE and zilch. Nada. All, use the FireFox Web Developer extension. It will save you troubles. Also use FireFox's JavaScript console. AWESOME things.
On FF, I use Venkman JavaScript Debugger and like it. On IE, I installed a MS script debugger which was OK, but then auto-update .Net-ed it so it is now less than OK. I really want to hurt someone @ MS.
Oops. At the last second, I changed the primary function name and didn't get the changes applied throughout the page. try this: HTML: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Untitled</title> <script language="javascript"> // this script will need to be adjusted if it is to be compatible with non-IE browsers totalrows=0; function adjustrow(dir){ var rowtext = ""; if (dir==0) { totalrows++; for (i=1;i<=4;i++){ rowtext = rowtext + "<input type=\"text\" name=\"txt" + totalrows + "_" + i + "\">"; } rowtext = rowtext + "<br>"; document.getElementById('textboxes').innerHTML = document.getElementById('textboxes').innerHTML + rowtext; } else { if (totalrows > 1){ var m = document.getElementById('textboxes').innerHTML.indexOf(totalrows+'_1'); m = m - 15; document.getElementById('textboxes').innerHTML = document.getElementById('textboxes').innerHTML.substring(0,m); totalrows--; } } } </script> </head> <body onLoad="adjustrow(0);"> <div id="textboxes"></div> <br> <input type="button" value=" + " onClick="adjustrow(0);"> <input type="button" value=" - " onClick="adjustrow(1);"> </body> </html>
I foun jur problem, seeƱor droxford. This here code: Code: innerHTML.indexOf(total rows+'_1'); Should be Code: innerHTML.indexOf([b]totalrows[/b]+'_1'); Do you have some GIGs on the side or local contract stuff you need help with? I could use some extra dee-neh-roh.
i'm not sure if this applies since i didn't test your code. without using innerHTML or outerHTML, IE will not append new html code to an existing page in a function call, after the page has been loaded. instead, it will load it up in a new page. what you can do is write the html code outside of a function (execute it on load time) and use the css properties inside a function to change it's visibilty (ex. "document.getElementById("idname").style.visibility="visible" ). remember IE 5.0 Mac will crash if you use innerHTML.
actually, the only reason why you wouldn't use innerHTML is if you cared about backward compatiblity. i work for a state university so my pages had to support at least netscape 4.5 and both mac and windows until recently.