views:

155

answers:

1

I'm having some issues with this - some reason updateCurrentItem is always called with the same parameter regardless.

function updatePromoList(query) {
query = query.toUpperCase();
clearCurrentList();
var numItems = 0;
currentItem = 0;

result_set = cached[query.charAt(0)][query.charAt(1)][query.charAt(2)];

for(i in result_set){
    if(numItems >= NUMBER_MATCHES){
        $("<li/>").html("<span style='color: #aaa'>Please try to limit your search results</span>").appendTo("#possibilities").mouseover(function(event){ updateCurrentItem(numItems+1); });
        break;
    }

    promo = result_set[i];
    found_number = false;
    if (!promo.client)
        found_number = (promo.prj_number.toString().substr(0,query.length) == query) ? true : false;

    if (query.length >= MATCH_NAME) {
        if(promo.prj_name && typeof promo.prj_name == 'string'){
            found_name = promo.prj_name.toUpperCase().indexOf(query);
        } else {
            found_name = -1;
        }  
        if (promo.client)
            found_client = promo.client_name.toString().indexOf(query);
        else
            found_client = -1;
    } else {
        found_name = -1;
        found_client = -1;
    }

    if(found_client >= 0) {
        var thisIndex = numItems+1;
        console.log("setting", thisIndex);
        $("<li/>").text(promo.client_name).bind('click',function(e){ updatePromoChoice(e,promo); }).appendTo("#possibilities").mouseover(function(event){ updateCurrentItem(thisIndex); });        } else if(found_name >= 0 || found_number) {            var thisIndex = numItems+1;
        console.log("setting", thisIndex);
        $("<li/>").text(promo.prj_number+": "+promo.prj_name).bind('click',function(e){ updatePromoChoice(e,promo); }).appendTo("#possibilities").mouseover(function(event){ updateCurrentItem(thisIndex); });
    }

    if(found_number || found_client >= 0 || found_name >= 0){
        numItems++;
    }
}

}

function updateCurrentItem(i){ currentItem = i; console.log("updating to", i); }

The results of running this are:

setting 0 setting 1 setting 2 setting 3 setting 4 setting 5 setting 6 setting 7 setting 8 setting 9 setting 10 setting 11 setting 12 setting 13

then when I move my mouse over the content area containing these <li>s with the mouseOver events, all I ever see is:

updating to 4

ALWAYS 4. Any ideas?

+1  A: 

You're creating a closure but it's still bound to the numItems variable:

function(event){ updateCurrentItem(numItems+1); }

What you should do is something like this:

(function(numItems){return function(event){ updateCurrentItem(numItems+1); }})(numItems)

Edit: I think I might have the wrong function but the same principle applies:

function(event){ updateCurrentItem(thisIndex); }

should be

(function(thisIndex)
{
    return function(event){ updateCurrentItem(thisIndex); }
})(thisIndex)
Greg
Your code seems to work but I'm still confused. I thought that if I used a closure, it would get the value of the variable when the closure is created, not a reference to that variable?
ashgromnies
No, JavaScript is a late-binding language. Discussion: http://stackoverflow.com/questions/422784/-/423073#423073.
bobince