1

I have to create a few "select" elements in a html file dynamically. And I also intend to create the same amount "select" elements according to the value of the former created "select" elements.

Thus I will have a set of "select" elements pair. When the first "select" element's selected value is changed, the second "select" elements will refresh its options using the according records in a database.

My problem is I can't receive the correct value of the first "select" element. Everytime when the onchange event is called, the value passed on to onchange function( in my case, it's called "fillSource()" is the value before the change happened instead of the changed selected value.

Do anyone know how to solve this problem?

The following is my javascript code:

<script>

    var selectCount = 1;
    var cats = #{dropCatsJson};
    var subcats = #{dropSourceJson};
    function addNewSource() {

        var inputchange = document.createElement('select');
        inputchange.options[0] = new Option("pls Select", "0");
        inputchange.id="schange";

        var input1 = document.createElement('select');
        for( var i=0;i< cats.length;i++ ) {
            var s = cats[i];                        
            input1.options.add( new Option(s.Name, s.Id) );            
        }

        input1.id = 's' + selectCount;

        //input1.onchange = new Function("alert(\"input1 changed\")");       
        input1.onchange = new Function("fillSource(" + input1.value + ")");

        document.getElementById('newSource').appendChild(input1);
        document.getElementById('newSource').appendChild(inputchange);
        selectCount = selectCount + 1;
    } 

    function fillSource(input1)
    {

        var dropsub = document.getElementById("schange");
        dropsub.options.length = 0;//clear all the options.
        for( var i=0;i< subcats.length;i++ ) {
            var s = subcats[i];
            if( s.ParentId == input1.value ) 
            {               
                dropsub.options.add( new Option(s.Name, s.Id) );
            }
        }
    }


</script>

=============================================================================== final code that works. Please notice that you should add onchange event for newly created select elements like this:

input1.onchange = function(){fillsource(input1.value)};

here is my test.html code:

<html> 

<script type="text/javascript"> 
var selectCount = 1;
function addNewSearch() 
{ 
     //alert("add");
     var input1 = document.createElement('select');
     input1.options[0] = new Option("s1","1");
     input1.options[1] = new Option("s2","2");
     input1.name = 's' + selectCount;
     input1.id = 's' + selectCount;
     input1.onchange = function(){fillsource(input1.value)};
     document.body.appendChild(input1);

     selectCount = selectCount +1;
     //alert(selectCount);
     var selcount = document.getElementById('selCount');
     selcount.textContent = selectCount;
} 

function fillsource(ivalue)
{
     alert(ivalue);
} 

</script> 

<form name= "Search" id= "SearchForm"  method= "post"> 

<select name= "SearchWhat" onchange = "setSearchField()"> 
<option value = "both"> Both Event and Task </option> 
<option value = "event"> Event </option> 
<option value = "task" > Task </option> 
</select> 

<label id="selCount"></label>

<input type="submit" value= "submit" name = "btn_submit"/> 
<input type="button" name= "newsearch" value= "New Search" onClick= "addNewSearch()"> 
</html> 
2
  • can you provide some test data for dropCatsJson and dropSourceJson? Commented May 18, 2013 at 16:07
  • @Barmar has solved my problem. Thanks anyway. Commented May 18, 2013 at 16:26

1 Answer 1

3

You're capturing the value at the time you create the select element, and hard-coding it into the onchange function. You need to use a closure:

input1.onchange = (function(input1) {fillsource(input1.value)})(input1);
Sign up to request clarification or add additional context in comments.

4 Comments

Your answer inspires me that there's anthor way to solve this problem. first, I pass the id attribute of the first select elements; then I caputer the value in my function fillsource() by using document.getElementById(), and in the end when I use input1.value, it works. code input1.onchange = new Function("fillSource(\"s1\")"); var inputselect = document.getElementById(input1); code
You could do that, but why call getElementById() when you don't need to?
thanks for your advice. I changed to input1.onchange = function() {fillsource(input1.value)};
That should work as well. I was mistakenly thinking that input1 was a for-loop variable, in which case another level of closure would be necessary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.