0

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.

Mike-O
  • 844
  • 1
  • 11
  • 16
NDevox
  • 4,056
  • 4
  • 21
  • 36
  • how about using a jquery plugin http://ivaynberg.github.io/select2/ – arun15thmay Jan 02 '14 at 17:30
  • I doubt I'll be able to input it into the web page - work politics. - to expand and not confuse anyone. My company do a lot of, what is essentially glorified web design, but we have to use specific templates. It's only when a client asks us to go above and beyond when we can do something more extravagant. – NDevox Jan 02 '14 at 17:32

1 Answers1

2

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.

Community
  • 1
  • 1
Emissary
  • 9,954
  • 8
  • 54
  • 65
  • Thanks for helping me out a lot tonight! I had to leave work so will update when I get back but it makes a lot of sense. As for the select boxes, yes there are 30 select boxes, each being associated with 3 text boxes (which is where the autocomplete function is called) The select boxes hold the type of transport, therefore defining which database needs to be used. I'll update tomorrow as to whether it has worked. – NDevox Jan 02 '14 at 19:51
  • The change worked and now the databases are loading as they should do. Although the AutoComplete function itself seems to have broken, possible due to closures again, I'm not sure. – NDevox Jan 03 '14 at 10:37