0

Ok I dunno why this isn't working. The alert outside the droppable says 0 but the alert inside the droppable says undefined. Anybody have an idea as to why? I want to start keeping a running count to when a person drops an object into the match div. I dont want to define play inside droppable cause it'll reset to 0 every time someone drops the object. Anybody have any idea as to what I'm not doing right?

var play = [];
for (var i = 0; i < 10; i++) {
    play[i] = 0;
    alert(play[i]);
        $('.match').droppable({
            greedy: true,
            drop: function(event, ui) {
            alert(play[i]);
            } 
        });
}

Heres the fiddle Click Here

Edited by RazorRamon: added link to fiddle

2
Contributors
3
Replies
7
Views
4 Years
Discussion Span
Last Post by Airshow
0

Razor, it's not clear why you might want to define .droppable() in a loop and maintain an array of counters. Each .droppable() statement will override the previous one so only the last .droppable() will be in effect when the loop terminates.

The simple answer to your question is that alert(play[i]); gives undefined because, by the time the drop handler fires, the for(){...} loop has exited and i is one greater than the maximum loop value.

I expect you want to alert the value associated with i at the time the .droppable() is put in place, in which case you can trap i in a closure as follows:

$(function () {

  var play = [];

  //This function exists solely to trap `i` in a closure
  function make_drop_fn(i) {
    return function (event, ui) {
      alert(play[i]);
    }
  }

  $('.drag').draggable();

  for (var i = 0; i < 3; i++) {
    play[i] = i;
    alert(play[i]);
    $('.match').droppable({
      greedy: true,
      drop: make_drop_fn(i)
    });
  }
});

DEMO

As you will see, I initialized the counters with play[i] = i rather than 0, so you can see which counter is alerted. You will also see that this value is always the highest value of i prior to meeting the loop's exit condition.

If you want to maintain counters for several droppable elements, then you can do so as follows :

$(function () {
  var play = [];

  function make_drop_fn(i) {
    return function (event, ui) {
      play[i]++;
      $(this).text(play[i]);
    }
  }

  $('.drag').draggable();

  $('.match').each(function (i, m) {
    play[i] = 0;
    $(m).droppable({
      greedy: true,
      drop: make_drop_fn(i)
    });
  });
});

DEMO

Other possibilities exist to meet thne same end.

Edited by Airshow: Further code example

0

Wow Thanks so much Airshow, big help for sure. One question, say if you didn't want the draggable div to keep counting once it was already over the droppable div.... how would you adjust the fiddle to stop counting.

Edited by RazorRamon: typos

0

Razor, aha I wondered if you might ask that.

The simplest approach is to inhibit the counts incrementing when a drop is made on the same target as the previous drop. So you need to track which .match element was last dropped on, and test accordingly.

$(function(){
    var play = [];
    var lastDropTarget;

    function make_drop_fn(i) {
      return function (event, ui) {
        if(this != lastDropTarget) {
          play[i]++;
          $(this).text(play[i]);
          lastDropTarget = this;
        }
      }
    }

    $('.drag').draggable();

    $('.match').each(function (i, m) {
      play[i] = 0;
      $(m).droppable({
        greedy: true,
        drop: make_drop_fn(i)
      });
    });
});

DEMO

Edited by Airshow

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.