NDevox
NDevox

Reputation: 4086

Activating a function on selecting an option from a DropDownList

I have designed an auto-complete function which, when a person inputs at least 3 letters into a textbox, will run through one of several databases of train stations to find all of the possible stations which have those three (or more) letters.

The function works perfectly and on opening the webpage the auto-complete list does come up with the correct stations.

However the choice of database used to generate the auto-complete suggestions is based on the users input into a droplist on the page.

At the moment the database used is based on the option selected when the page loads (so the top option) and I can't seem to get this to change as the users input changes.

Here is the problem section of the code:

$(function () {

    for(i=0;i<30;i++){
        $("#_Q6_Q" + i + "_Q3_C").change(function(){
            transportChange($("#_Q6_Q" + i +"_Q3_C").val(), i)
        });
    };
}

and here is a rough example of how the transportChange function uses the arguments:

function transportChange(lst, i) {
    /* lst = input into Mode of Transport question.
       i correlates to the row number - these are auto generated when
       the respondent changes their answer.
    */

    //Blank auto complete box
    //Use for loops to generate numbers correlating to input boxes
    for(var q=5; q<7; q++){
        for(var u=0; u<3; u++){
            $("#_Q6_Q".concat(String(i),"_Q", String(q), "_Q0_Q", String(u))).val('');
        };
    };

    // disable drop down and auto complete boxes whilst loading data;
    $("#_Q6_Q".concat(String(i),"_Q4_Q0_Q0")).prop('disabled', true);
}

I can tell you the 'lst' argument is concatenated into a link which then defines which database will be used.

The auto-complete function is from JQuery.

Upvotes: 0

Views: 69

Answers (1)

Emissary
Emissary

Reputation: 10148

Ignoring the missing var in the first for-loop (which technically puts i in the global scope), and the fact that you are applying a callback function to the change event on 30 select boxes (is that correct?!)...

It looks as though the issue - with the first part at least - is that the callbacks are sharing the same execution scope. This means that in all the function i will always equal the last value assigned (30).

This behaviour is far better explained than I can do here: How do Javascript closures work?

So... can you please update your first code-block as follows:

$(function(){

    for(var i=0; i<30; i++){
        $("#_Q6_Q"+ i +"_Q3_C").change(callbackFactory(i));
    }

    function callbackFactory(i){
        return function(){
            transportChange($("#_Q6_Q"+ i +"_Q3_C").val(), i);
        };
    }
    // ...
});

This will ensure every function generated is encapsulated in it's own scope (and i will be what you think it is) - This is the only logical flaw I've spotted so far, if it doesn't work then we need more info.

Upvotes: 2

Related Questions