1

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.

Tim Tisdall
  • 9,914
  • 3
  • 52
  • 82

1 Answers1

1

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.

Twisty
  • 30,304
  • 2
  • 26
  • 45
  • Your example works pretty good, but `over` is only called repeatedly if the cursor moves, so holding very steady over the scroll area means no movement. (that may be sufficient, though, as I imagine users will jiggle the cursor if they don't see movement) – Tim Tisdall Jun 01 '17 at 14:09
  • I see what you're saying. As I said, it can be improved. You could potentially move it to `drag` in draggable, it may be more active. – Twisty Jun 01 '17 at 15:38