1

I'm having some issues with this. For 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?

Jason Plank
  • 2,336
  • 5
  • 31
  • 40
ashgromnies
  • 3,266
  • 4
  • 27
  • 43

1 Answers1

2

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
  • 316,276
  • 54
  • 369
  • 333
  • 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 Mar 25 '09 at 16:31
  • No, JavaScript is a late-binding language. Discussion: http://stackoverflow.com/questions/422784/-/423073#423073. – bobince Mar 25 '09 at 16:42