jQuery UI: Draggable Scroll Issue

19,825

Heres a code from a fiddle: http://jsfiddle.net/crowjonah/Fr7u8/3/

HTML:

<table>
<tr class="drag_me">
    <td>drag me</td>
</tr>
<tr class="drag_me">
    <td>drag me</td>
</tr>
<tr class="drag_me">
    <td>drag me</td>
</tr>
<tr class="drag_me">
    <td>drag me</td>
</tr>
</table>

<div class="upper"></div>
<div class="drop_area">
<ul>
    <li class="drop_on_me">drop here</li>
    <li class="drop_on_me">drop here</li>
    <li class="drop_on_me">drop here</li>
    <li class="drop_on_me">drop here</li>
    <li class="drop_on_me">drop here</li>
    <li class="drop_on_me">drop here</li>
    <li class="drop_on_me">drop here</li>
    <li class="drop_on_me">drop here</li>
    <li class="drop_on_me">drop here</li>
    <li class="drop_on_me">drop here</li>
</ul>
</div>
<div class="lower"></div>

jQuery:

$('.drag_me').draggable({
    helper: 'clone',
    scroll: 'true',
    refreshPositions: true
});

$('.drop_on_me').droppable({
    accept: '.drag_me',
    activeClass: 'active',
    hoverClass: 'hover',
    tolerance: 'pointer'
});
$('.upper').droppable({
            over: function(event, ui){
                $('.drop_area').autoscroll({
                    direction: 'up',
                    step: 150,
                    scroll: true
                });
            },
            out: function(event, ui){
                $('.drop_area').autoscroll('destroy');
            }
        });

        $('.lower').droppable({
            over: function(event, ui){
                $('.drop_area').autoscroll({
                    direction: 'down',
                    step: 150,
                    scroll: true
                });
            },
            out: function(event, ui){
                $('.drop_area').autoscroll('destroy');
            }
        });

Related to this question: jQuery UI: Draggable Scroll Issue

Its a working example of a dragable element inside a container with overflow: scroll

Share:
19,825
incutonez
Author by

incutonez

Web developer that enjoys building web applications full of pizzazz. I'm a reformed Ext JS developer that's currently loving Vue.js.

Updated on June 04, 2022

Comments

  • incutonez
    incutonez almost 2 years

    I'm trying to build a draggable/droppable folder-file view with jQuery UI, but I'm running into a problem with, what I believe is attributed to the helper. Here is my code:

    The HTML

    <body>
      <div id="topContainer">
        <span>Parent Directory 1</span>
      </div>
      <span id="topFolder" class="folder">
        <div class="drop">
        </div>
      </span>
      <hr />
      <div id="container" class="container">
        <div class="dropzone">
          <span>Parent Directory 2</span>
        </div>
        <div id="cont1" class="container">
          <div class="dropzone">
            <span>Folder 1</span>
          </div>
          <span id="folder1" class="folder">
            <div class="drop">
              <div class="drag">&nbsp;</div>
              <div class="drag">&nbsp;</div>
              <div class="drag">&nbsp;</div>
              <div class="drag">&nbsp;</div>
              <div class="drag">&nbsp;</div>
              <div class="drag">&nbsp;</div>
              <div class="drag">&nbsp;</div>
              <div class="drag">&nbsp;</div>
              <div class="drag">&nbsp;</div>
              <div class="drag">&nbsp;</div>
              <div class="drag">&nbsp;</div>
              <div class="drag">&nbsp;</div>
            </div>
          </span>
        </div>
        <div id="cont2" class="container">
          <div class="dropzone">
            <span>Folder 2</span>
          </div>
          <span id="folder2" class="folder">
            <div class="drop">
            </div>
          </span>
        </div>
        <div id="cont3" class="container">
          <div class="dropzone">
            <span>Folder 3</span>
          </div>
          <span id="folder3" class="folder">
            <div class="drop">
            </div>
          </span>
        </div>
        <span id="mainFolder" class="folder">
          <div class="drop">
            <div class="drag">&nbsp;</div>
          </div>
        </span>
      </div>
    </body>
    

    The jQuery

    $(document).ready(function () {
      var opts = {
        helper: 'clone',
        appendTo: 'body'
        //appendTo: '#container'
      };
    
      $('div.drag').each(function () {
        $(this).draggable(opts);
      });
    
      $('.dropzone, #topContainer').droppable({
        drop: function (e, ui) {
          var clone = $(ui.draggable).clone();
          clone.draggable(opts);
          $(this).siblings('.folder').children('.drop').append(clone);
          $(this).removeClass('over');
        },
        over: function (e, ui) {
          $(this).addClass('over');
        },
        out: function (e, ui) {
          $(this).removeClass('over');
        }
      });
    });
    

    The CSS

    .dropzone {
        height: 300px;
        width: 100px;
        border: 1px solid black;
    }
    .drag {
        clear: both;
        height: 50px;
        width: 80px;
        background-color: black;
        position: relative;
        cursor: pointer;
    }
    #topContainer, .dropzone {
        height: 50px;
        width: 300px;
        border: 2px solid black;
        text-align: center;
    }
    .folder .drag {
        margin: 5px;
    }
    .container {
        border: 2px solid blue;
        margin: 10px;
    }
    .over {
        background-color: yellow;
    }    
    #container {
        width: 800px;
        height: 600px;
        overflow-y: scroll;
        border-color: red;
        position: relative;
    }
    

    The Fiddle: jsFiddle

    So the idea is... you drag one of the black blocks to the desired folder (Parent Directory 1, Parent Directory 2, Folder 1, etc.). That all seems to work fine.

    What doesn't work fine is when the parent (#container) or body have an overflow. If you click on a block to drag and try to mousewheel scroll, you can't... or if you keep trying, you sometimes can. (It's not obvious with my screen resolution, but in the Fiddle code, there is a scrollbar for the #container element) I'm assuming this has something to do with the focus of where I'm appending the helper to.

    Because I started thinking the latter, I started appending the helper to different locations. With #container being the area I'm most interested in, I can append the helper there and get the scroll to work just fine (uncomment //appendTo: '#container' and comment out the appendTo: 'body').

    However, this introduces another problem. Now that I'm appending to the #container element, my block cannot be seen when it is dragged to the Parent Directory 1 folder, which lead me to believe that there is just something wrong with helper.

    Sure enough, if you don't user helper: 'clone', you can scroll just beautifully. This is not an option because I like having my clone there. So I turn to y'all. How can I fix my problem, and what exactly is going on? Does anyone have any advice? I'd love to hear it.

    It's also good to note that I've tried setting the zIndex and stack options for the draggable, but no go. I'm assuming I'll have to make a custom helper function, and make it aware of what it's currently being dragged over... but I'm hoping there's an easier fix.

    If anyone has any insight, I'd love to hear it. Thanks!