Search code examples
javascriptjquery-ui-droppable

Array of Boolean are undefined when object dropped?


I have some array of dragged object and dropped object, here:

var elmDragObj = ["#ob01","#ob02","#ob03","#ob04","#ob05","#ob06","#ob07","#ob08","#ob09","#ob10","#ob11","#ob12","#ob13","#ob14","#ob15","#ob16","#ob17","#ob18","#ob19","#ob20"];

var elmDropObj = ["#va_kb_a","#va_ks_a","#va_kk_a","#dk_kb_a","#dk_kb_b","#dk_ks_a","#pr_kb_a","#rv_kb_a","#rv_kb_b","#rv_kb_c","#pr_ks_a","#rv_ks_a","#rv_ks_b","#rv_ks_c","#vl_kb_a","#vl_ks_a","#vl_kk_a","#vk_kb_a","#vk_ks_a","#vk_kk_a"];

and i have array of booleans to check when all object are dropped in its place, here:

var elmBool = [false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false];

when i want to check the boolean, it's undefined, script below:

for(var j=0; j<elmDragObj.length; j++){
        $(elmDragObj[j]).draggable({revert:"invalid"});

        $(elmDropObj[j]).droppable({
            accept: elmDragObj[j],
            drop: function( event, ui ) {
                alert(elmBool[j]);
            }
        });
    }

Did I do something wrong?


Solution

  • It's because by the time that...

    alert(elmBool[j]);
    

    ... runs, j is now out of range for your array (it will be equal to elmDragObj.length).

    The easiest solution is to simply use $.each():

    $.each(elmDragObj, function(j, sel) {
        $(sel).draggable({ revert: 'invalid' });
    
        $(elmDropObj[j]).droppable({
            accept: sel,
            drop: function(event, ui) {
                alert(elmBool[j]);
            }
        });
    });
    

    If you really wanted to use a for loop, it can be done, but you'll need to "lock" the value of j in a closure:

    for(var j=0; j<elmDragObj.length; j++){
        $(elmDragObj[j]).draggable({revert:"invalid"});
    
        $(elmDropObj[j]).droppable({
            accept: elmDragObj[j],
            drop: (function() {
                var index = j;
                return function(event, ui) {
                    alert(elmBool[index]);
                };
            })()
        });
    }
    

    Clearly that's not as developer friendly as the first approach, though, so my recommendation is definitely to go with $.each().