Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have the screen scroll when dragging items from a scrollable/sortable to another, outside the screen?

I'm trying to achieve a Trello like functionality for dragging items from one list (phase) to another. When there are too many lists/phases, I'd like the screen to scroll automatically when dragging from the leftmost list to the right most one, which would probably be "off screen".

Currently, I have two levels of sortables which are both scrollable (see jsFiddle);

The first level scrolls horizontally and the second vertically. That is, I can move the lists around horizontally and each element in the list vertically only.

On the second level, I have:

$('.phase-block').sortable({
    scroll: true,
    connectWith: '.phase-block',
    appendTo: '.phase-scroll',
    helper: 'clone'
});

which puts the helper in the container and allows me to drag onto the list on the far right, but doesn't allow vertical scrolling within the list.

Is there a way to keep both kinds of scrollability without sacrificing one for the other?

like image 365
Zahymaka Avatar asked Dec 20 '14 03:12

Zahymaka


1 Answers

Update

I modified the on scroll function so that it will behave more like a traditional scroll (before I had it so that any time your moved up or down it would attempt to scroll). It was also primarily built to work with the given example and not with a broader range of box sizes etc..

Now I am attempting to only have it scroll up or down when the box you are dragging reaches the top or bottom of the scroll bar. The only tricky part is depending on the size of box you are dragging the offset of the box where you would want to start scrolling is different depending on size.

I am sure there is a way to figure out when the box you are dragging is more than halfway below or above the bottom/top of the scroll box and then scroll accordingly, but the solution is not something I have been able to come up with at this point.

Another thought that would make this easier, is if you knew all the possible sizes of the boxes that were going to be draggable via this scenario. You could set up an object with a reference to all the box sizes linked to individual values which you could use to modify when the scroll starts for that particular size of box. If this is something viable for you I can show you how I would do it.

But Here is an updated example with your latest fiddle that has the different block heights. I kind of worked with the code a little bit to make it so that no matter what size of block (of the ones you have specified) the scrolling will start around the same time.

$('.phase-block').sortable({
        scroll: true,
        connectWith: '.phase-block',
        appendTo: '.phase-scroll',
        helper: 'clone',
        sort: function(event, ui){
            if(ui.offset.top >= activePhaseBlock.height()+(90 -ui.item.height() > 0 ? 65-ui.item.height() : 10))
                activePhaseBlock.scrollTop(activePhaseBlock.scrollTop()+ui.item.height());     
            else if(ui.offset.top <= 0+(ui.item.height() > 25 ? 20 : 40))
                activePhaseBlock.scrollTop(activePhaseBlock.scrollTop()-ui.item.height());
        },
        over: function(event, ui){
            activePhaseBlock = $(this);
        }  
    });

If you are planning to have random heights of blocks then this method probably won't be the most viable and you'll have to find a universal way to determine when the offset is high enough or low enough to start scroll regardless of block size.

Let me know if you need any clarification.

Fiddle Example

like image 152
Trevor Avatar answered Sep 29 '22 19:09

Trevor