How do I scroll a list when using drag and drop?

Hello

I have two lists, and I want to be able to drag and drop items from one to the other.
I used Dragula which is fine for that use.
However, moving an item vertically also scrolls the list.
I would like to disable that scroll while still being able to scroll up/down by dragging the item to the top/bottom of the screen,
much like the Google Drive app does when moving files.

How can I achieve that?

1 Like

Try to do something like this in content tag [ngClass]="{‘no-scroll’: dragEnable }".
In no-scroll class you set the css properties to avoid scroll and dragEnable is a boolean to apply the class whenever you want.

1 Like

Thanks for your reply.

I see how that would disable the scrolling while dragging.
However, I don’t see how that would help me to scroll when dragging an item to the bottom for example.

Let me explain my idea more clearly : When dragging an item, I want to put it in a part of the list that is not visible, so I would drag it to the bottom of the screen, and the list would scroll down slowly. (If I drag it to the top part of the screen, the list would scroll up.)

If I understand correctly, your idea is to set the boolean dragEnable to true whenever I want to enable scrolling again, but that will not make it scroll down the list; it will only allow the user to scroll by doing the scroll gesture again, which is not what I want.

I was thinking maybe I could detect when an item is dragged in a predefined part of the screen, and then call the content.scrollTo method, but I have no clue how to make the detection, and it seems like quite a dirty way to do it, I was hoping a better way exists

1 Like

I’ve had an absolutely horrible time with this issue. You would think that the built-in recorder function would do this properly, but it fails. If you’re trying to drag an item up, it will scroll to the very top of the list, and dragging an item down does nothing.

I went through the painstaking process of trying to install Dragula. The motto is “drag and drop so simple it hurts,” but it’s not simple at all. Once I got everything imported properly and recognized by my ion-list, I was disappointed to find out that Dragula doesn’t use automatic scrolling either!

Someone suggested using the dom-autoscroll plugin, and it didn’t work when I tried telling it that ion-content was the window we wanted to scroll.
So after 48 hours of obsessively trying to solve this problem, I hacked something together.

Dragula has a method .out() that tells you when the dragged item is off the screen, so I used that to know it’s on the edge. I determined the direction of the drag by getting getting the dragged element and determining its distance from the top of the page with element.offSet top. If it was less than half of this.content.contentHeight, I knew it was at the top, else it needed a scroll down.

Then I added 20 to the current position and used a setInterval to keep scrolling until another Dragula subscription, .over() was triggered to tell us that we’re not dragging the item past the screen anymore.

I wanted to try tears of joy when it worked perfectly and smoothly in ionic-lab.

But sadly, trying it out on my actual phone didn’t work at all! The dragging with Dragula is inoperable on touch screen. When you scroll the page without trying to drag things, it registers that as a long press and tries to drag, and I couldn’t see a way of delaying the drag. You’d think such a dead-simple drag-and-drop plugin would allow you to easily delay the time needed to initialize a drag.

So that was a real bust.

To try to modify the original reorder function, I tried going into item-reorder.js, whose address is node_modules/ionic-angular/components/item/item-reorder.js, but it seemed a little obscure. Going into the ionic repository, copying the code, and pasting this into a custom provider might be your best bet, but it’s STILL hard to determine exactly when an element is nearing the bottom edge of the screen.

One final bit of hope I have is for the plugin SortableJS, which claims to have built-in autoscrolling, but to configure it, you must modify SystemJS, and I don’t think Ionic has the same configuration so it might be completely incompatible.

So there you have it… it’s been at least a week in which all I want to do is have the screen scroll down when you’re dragging an item past the viewable content, and it’s been a horrible experience. It’s so bad that it makes me want to abandon my Ionic app completely and re-make my app with something more stable like a separate iOS and Android app, built with Swift and Java respectively.

Please let me know if any of ya’ll can think of a fix to this problem which should ideally be solvable within five minutes, but really isn’t.

5 Likes

I agree. It seems like scrolling the list when reordering an item past the visible screen should be the default behavior, but it appears there isn’t a way to do this.

Wow, insane, you avoided me some digging, I dug only 3-4 hours trying Dragula as you did. perhaps we could begin calling a function regularly that check the position of the dragged element and drags the list accordingly if items gets closer to the bottom or top of the list and the list is higher. Would this approach work?

two questions come to mind :

  • how to change the scrolling of an element?
  • how to calculate and spot the dragged item on the screen.