Tim Tisdall
Tim Tisdall

Reputation: 10392

jQuery UI draggable into a scrollable div

I've found a solution for what I'm looking for, but it's using a library that's no longer maintained and may not be up-to-date with the latest jQuery UI. Here's the example: http://jsfiddle.net/crowjonah/Fr7u8/2/ (that solution is from a similar question from nearly 5 yrs ago)

Essentially, I want to be able to drag a jQuery UI draggable into a div that is scrollable (has overflow-y:scroll set on it). As well, the div should scroll when the user hovers over the top or bottom of the div to find the droppable the user wants to place the item into.

Here's a screenshot of the fiddle:

fiddle screen shot

The dark gray areas at the top and bottom are hover-able divs that cause scrolling up or down. Each "drop here" is a droppable.

Has anyone seen something like this?

Additionally, so readers are aware, there's an issue if you drop an item below or above the scrollable area if items are down there. Basically, you can drop into droppables that are in the overflow area.

Upvotes: 2

Views: 1639

Answers (1)

Twisty
Twisty

Reputation: 30903

This can be done a few ways. Here is one that will not need any external libraries and setup with jQuery 3.2.1 and jQuery UI 1.12.1.

JavaScript

$(function() {
  $('.drag_me').draggable({
    helper: 'clone',
    scroll: 'true',
    refreshPositions: true
  });
  $('.drop_on_me').droppable({
    accept: '.drag_me',
    activeClass: 'active',
    hoverClass: 'hover',
    tolerance: 'pointer',
    over: function(e, ui) {
      var buffer = 16;
      var step = 30;
      var speed = 250;
      var upper = $('.drop_area').position().top + buffer;
      var lower = $('.drop_area').position().top + $('.drop_area').height() - buffer;
      var current = $('.drop_area').scrollTop();
      switch (true) {
        case (ui.position.top <= upper):
          console.log("Direction: Up");
          $('.drop_area').animate({
            scrollTop: current - step
          }, speed);
          break;
        case ((ui.position.top + ui.helper.height()) >= lower):
          console.log("Direction: Down");
          $('.drop_area').animate({
            scrollTop: current + step
          }, speed);
          break;
      }
    }
  });
});

Working Example: http://jsfiddle.net/Twisty/rmq15a0w/7/

The library you mentioned may be smoother and I suspect this could could be improved, but it functionally does the same sorts of things. I used switch() in case you wanted to cover extra "speed" settings. For example if you had a list of 500 items. You may want upper-1 and upper-2, where if the user drags to upper-1, it moves the scroll at step * 2 and upper-2 only moves it at step. You could also make use of left in over if you wanted to also scroll left or right.

Lots of options. Hope this helps.

Upvotes: 1

Related Questions