Question

            gameDesign = {          

                          makeSeats: function( num ) {  //num = number of seats 


                                    var seats = [];
                                    var seat;

                                    var seatWidth = 20;
                                    var seatHeight = 20;
                                    var total = 100;

                                    for( var i=1; i<= num; i++ ) {

                                        seat = $('<div id="seat_'+i+'" class="seats"><div id="index_'+i+'" style="height:100%; width:100%;"><div style="height:100%; width:100%;">Sit Here</div></div></div>');

                                        seat.children(":first").children(":first").click( function(event, i){ 
                                                                                                                var tim = i;
                                                                                                                gameDesign.sitOnIndexNo( tim ); });

                            },

                           sitOnIndexNo: function( seatIndex ) {

                                   tableFunc.makePlayerSit( RummyGlobal.myInfo.get_jid(), seatIndex );
                           }

                    }

Problem: On clicking "Sit Here" index value is being passed as undefined .. I know this is something related to closures .. but, i need further explanation and solution ..

Thanx in advance

Was it helpful?

Solution

function(event, i){ ...

expects i as it's second argument and any i inside its body is unrelated to any i outside its body.

jQuery passes only one argument to an event handler it calls - the event. Additionaly, it passes the target element as this. This means that the second argument is always undefined.

If you do this:

for(var i=0; i<num; i++){
   var seat = $("...");
   seat.find("...").click(function(e){
     gameDesign.sitOnIndexNo(i)
   )
}

you access the variable i after its value has changed. You can create a self-invoking function to capture the value of i:

for(var i=0; i<num; i++){
   var seat = $("...");
   var handler = (function(i){
     return function(event){
       gameDesign.sitOnIndexNo(i)
     )
   })(i);
   seat.find("...").click(handler);
}

... or use seat.data, as suggested by @ClarkPan.

OTHER TIPS

Firstly, you've declared the 'click' eventHandler to accept a parameter of 'i' as the second parameter. However, jquery parameter only passes through a single event object as the first parameter to the eventHandler. This means, when you assign 'tim' to be 'i', it'll come up with undefined.

Secondly, after changing this, if you were to run your code again, you'd get 'tim' to be equal to 'num' + 1, because the 'i' that's being referenced belongs in the 'makeSeats' function scope, and isn't stored as part of the function.

What you want is something like this:

for(var i = 0; i <= num; i++){
    $('.foo').click({i:i}, function(e){
        gameDesign.sitOnIndexNo(e.data.i);
    });
}

More info on the 'data' property thats past to the eventHandler can be found here.

You mention "clicking", so I assume you're plannning to generate all these divs saying "Sit Here". When the user clicked "Sit Here", the function sitOnIndexNo is called. Based on this assumption, here's my suggestion:

gameDesign = {          
    makeSeats: function( num ) {  //num = number of seats 
        for( var i=1; i<= num; i++ ) {
            $("#id_of_element_where_you_want_to_put_the_div").
            append('<div id="'+i+'" class="seats" style="height:100%; width:100%;">Sit Here</div></div></div>');
        }
    },
    sitOnIndexNo: function( seatIndex ) {
        tableFunc.makePlayerSit( RummyGlobal.myInfo.get_jid(), seatIndex );
    }
}

// Event handler:
$(".seats").live("click", (function(e) {
    var tim = $(this).attr("id");
    gameDesign.sitOnIndexNo(tim);
});

So basically, the makeSeats function generates the "Sit Here" divs and their click events are handled by the new event handler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top