Javascript - can't createElement Correctly

potatobean

n00b
Joined
Feb 23, 2005
Messages
19
Hey, can anyone help solve my problem? I'm creating a select dropdown with createElement('select') and then using appendChild to the form. I need to do this a couple of times for a hierarchy of questions but i can't seem to get the users selected options which were created by the createElement()....

heres my code. Do a select on "online banking" and then select anything from the generated menu...
i always get "document.forms.advancedSearch.myselect1.options' is null or not an object."
(note: the big blob of text is an array data storage)
 
Online banking built by an amateur? Sounds a little phishy to me.

No help without background information.
 
HeThatKnows said:
Online banking built by an amateur? Sounds a little phishy to me.

No help without background information.

Hey, I'm trying to write up an advance search feature for a client i'm working for which happens to be an investment bank. Basically its a call center knowledge base search engine which tries to narrow someone's search to a paticular branch of the business.

I'm having problems assigning options to a select which is created with createElement(). It seems to work but once its drawn and I try to select an option, the select options array seems to be null..

heres where it breaks :

function addDropDown(thisform) {

var thisSelect = document.createElement('SELECT');
var selectname = "myselect" + selectedOptionArray.length;
thisSelect.name = selectname;
thisSelect.value = selectname;


var thisOption = document.createElement('option');
thisOption.name = getName(myTraverse[0]);
thisOption.value = getURL(myTraverse[0]);
thisSelect.appendChild(thisOption);
for(var i=0; i < myTraverse.length; i++){
thisOption = document.createElement('option');
thisSelect.options[i+1] = new Option(getName(myTraverse),getURL(myTraverse));
thisSelect.appendChild(thisOption);
}

thisSelect.onchange = "registerSelection('" + selectname + "'," + thisform.name + ",document.forms.advancedSearch."+ selectname +".options[document.forms.advancedSearch."+ selectname +".selectedIndex ].text, document.forms.advancedSearch."+ selectname +".options[document.forms.advancedSearch."+ selectname +".selectedIndex ].value )";

var onChangeHandler = new Function(thisSelect.onchange);

if(thisSelect.addEventListener){
thisSelect.addEeventListener('onchange', onChangeHandler, false);
} else if(thisSelect.attachEvent) {
thisSelect.attachEvent('onchange', onChangeHandler);
}

thisform.appendChild(thisSelect);

}
 
Here's what Opera reports for errors in the js

Code:
[url]http://s89235729.onlinehome.us/problem.html[/url]
Event thread: change
Error:
name: SyntaxError
message: Statement on line 138: Parse error in function body: 
function (event)
{
  registerSelection("myselect1", advancedSearch, document.forms.advancedSearch.myselect1.options[document.forms.advancedSearch.myselect1.selectedIndex].text, document.forms.advancedSearch.myselect1.options[document.forms.advancedSearch.myselect1.selectedIndex].value);
}

Backtrace:
  Line 138 of inline#1 script in [url]http://s89235729.onlinehome.us/problem.html[/url]
    var onChangeHandler = Function(thisSelect.onchange);
  Line 113 of inline#1 script in [url]http://s89235729.onlinehome.us/problem.html[/url]
    addDropDown(myform, selectedOptionArray.length, myTraverse);
  Line 1 of  script 
    registerSelection(0, document.forms["advancedSearch"], document.forms.advancedSearch.productTypes.options[document.forms.advancedSearch.productTypes.selectedIndex].text, document.forms.advancedSearch.productTypes.options[document.forms.advancedSearch.productTypes.selectedIndex].value);
  At unknown location
    [statement source code not available]

Here's a testcase with document.createElement that seems to work O.K.

Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-us" xml:lang="en-us">
    <head>
        <title>document.createElement and select.options</title>
        <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
        <meta http-equiv="content-style-type" content="text/css"/>
        <meta http-equiv="content-script-type" content="application/x-javascript"/>
        <meta http-equiv="content-language" content="en-us"/>
    </head>
    <body>
        <form id="myform" method="get" action="">
        </form>
        <script type="application/x-javascript">
            function x() {
                alert(document.forms.myform.test.options[0].childNodes[0].nodeValue);
                alert(document.forms.myform.test.options[1].childNodes[0].nodeValue);
            }

            var o1 = document.createElement("option");
                o1.appendChild(document.createTextNode("option1"));

            var o2 = document.createElement("option");
                o2.appendChild(document.createTextNode("option2"));

            var s = document.createElement("select");
                s.setAttribute("name","test");
                s.setAttribute("onchange","x()");
                s.appendChild(o1);
                s.appendChild(o2);

            var d = document.createElement("div");
                d.appendChild(s);

            var f = document.getElementById("myform");
                f.appendChild(d);
        </script>
    </body>
</html>

Use type="text/javascript" instead if you need to support IE.
 
Call center knowledge base search engine? Okay, I can buy that.

The big problem is the way you've use your arrays -- 'myTraverse' is a mess. When you add the second select, you chop out portions of the array, but what if the first selection needs to be changed? You've no longer have info needed...

The gigantic productTypes array is fine, though I don't see the point of the first nesting level or the two undefined element it starts with. The over-used myTraverse has got to go. Have an array assigned to the first select, have a different array for second, another for the third, etc.

Instead of embedding those monstrous links as the option values, use the array index -- you can then get the value directly from the select (none of that document.forms.advancedSearch.productTypes.options[document.forms.advancedSearch.productTypes.selectedIndex ].value nonsense), you'll be able to pull the link out of the array just as easily as out of the option, and you can simplify that ugly getSelectedArray function (no name comparisons or recursion needed).
 
Back
Top