0

I'm trying to get an event when a user selects a row and drops it outside a jquery grid. This is the drop function for a drag/drop happens within the grid, which works perfectly fine -

    $(".grid-canvas")
        .on("drop", function (e, dd) {
              // somecode
                    });

I'm trying to track the drag & drop happening "ANYWHERE" outside the grid canvas div. but the inverse selection does not seem to be working. I tried this, but not working -

$(".grid-canvas")
    .not(this)
    .on("drop", function (e, dd) {
     alert("outside");
 });

I tried this, but it triggers for drag & drops within the grid as well -

$(":not(.grid-canvas)")
                               .on("drop", function (e, dd) {
                                alert("outside");
                            });

Any help appreciated. Thanks.

snakepitbean
  • 217
  • 4
  • 13

2 Answers2

0

Target the document directly to get all drops, and then just filter out anything that is nested inside .grid-canvas yourself (probably more efficient than pseudo selectors) :

$(document).on('drop', function(e, dd) {
    if ( ! $(e.target).closest('.grid-canvas').length ) {
        // dropped outside
    }
});
adeneo
  • 312,895
  • 29
  • 395
  • 388
  • I really dont know what would be a more resource friendly solution, both have a weaknesses. One solution will be resource intensive at event triggering other on the binding time. – Roger Barreto Aug 12 '13 at 22:47
0

First of all, read up on the "on" documentation so you have a better understanding. Your second example says the following:

Select all elements with the "grid-canvas" class
  ...that aren't `this`
  ...and watch for drop events on them, and do this when they happen

Which clearly isn't what you want. The second is closer:

Select all elements that don't have a grid-canvas class
  ...and watch for drop events on them, and do this when they happen

Which is closer, but a) adds event listeners to almost every single element in the page, which is a really bad idea, and b) will still fire for elements inside your grid-canvas div, which is what you're seeing, since you still attached listeners to them.

What you probably want to do is this:

Select a high-level element (e.g. `body`)
  ...listen for a drop event, and check if the drop event happened on .grid-canvas or one of its children

Which would look something like:

$('body').on('drop', function(evt) {
  //Check if the element dropped on has a .grid-canvas as a parent
  if($(evt.target).parents('.grid-canvas').length == 0) {
    alert('Outside');
  }
}

There are several ways to check if the target is within .grid-canvas, the one I used is just an example. You could also do $('.grid-canvas').has(evt.target), for instance - go at it from the other way around, which might make more sense depending on how you think about it.

But overall: jQuery isn't English, and you can't just string together commands that sound like they should do what you want. Make sure you read up on the functions you're using and understand what they do, and you'll build your jQuery skills much quicker.

cincodenada
  • 2,877
  • 25
  • 35