ng2-dragula
ng2-dragula copied to clipboard
If container is larger than viewport, and drag an item passed viewport top/bottom, window should scroll automatically?
When grabbing a scrollable item and going past the bottom of the viewport or past the top of the viewport, the browser window doesn't scroll. (the dragula container is larger than the browser viewport.) Is there a way to do this? It's super annoying to drag, drop, scroll, drag, drop, scroll, drag, drop, scroll, etc. (because my draggable items are large bootstrap panels.)
I tried dom-autoscroller which was recommend in this dragula issue (#121) but could only get it to work for a draggable items that are in a container with a height + overflow scrollbar.
I want the same functionality but within a container that is larger than the viewport. (So that the window automatically starts scrolling up or down & no extra scroll bar, just the windows scrollbar.) This seems like something that should just work out of the box?
I also tried @Naztar's answer in (#402) with no luck. Maybe I didn't implement his solution correctly, but all I did is copy and paste his javascript changes in dragula.js and still didn't work. (First I tried copying the raw .js file he modified into dragula.js but started getting 'require is not defined' errors, so I tried just pulling the individual changes he made and pasting them in, still no luck)
@quiringk Did you find any fixes for this issue?
The problem seems to be solved on the JS librairie https://github.com/bevacqua/dragula/tree/22f4e03d1303616fc58fb096698f760fefac8fc3
You maybe can include this 3rd party librairie to your project.
Hi @PierreDugue,
Is there any option, which I need to pass to enable scrolling while dragging. Because I check it in demo page and it's not working.
Right, it seems that this branch is not merged yet, so you will not be able to see it on demo page.
I'd really like to get this merged. And is there a way to increase the scroll speed to something like 200? 20 is way too slow. Thanks!!
Need this.
I built a demo that does this, among other things:
https://github.com/cormacrelf/dragula-touch-demo
Also curious to know if this will be incorporated in ng2-dragula, or if we should roll our own.
Cheers!
UPDATE: @cormacrelf's dragula-touch-demo above seems to be easy to adapt to our use.
https://plnkr.co/edit/IWywxumqZHJLw8bZEEWl?p=preview https://plnkr.co/edit/mDNw7pDDp5oHFeHZApB5?p=preview
This may be useful for you guys.
This is what I came up with and thought I should share.
dragulaService.drag.subscribe(value => {
document.onmousemove = (e) => {
let event = e || window.event;
let mouseY = event['pageY'];
let scrollTop = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop; // document.documentElement.scrollTop is undefined on the Edge browser
let scrollBottom = scrollTop + window.innerHeight;
let elementHeight = value[1].offsetHeight; // this is to get the height of the dragged element
if (mouseY - elementHeight / 2 < scrollTop) {
window.scrollBy(0, -15);
} else if (mouseY + elementHeight > scrollBottom) {
window.scrollBy(0, 15);
}
};
});
// detach the mouse move event when the drag ends
dragulaService.dragend.subscribe(value => {
document.onmousemove = null;
});
@ht89 I assume it works great for elements in body tag. I cannot seem to get it working for a parent container which has a certain max-width
and overflow: auto
setup for it. Any clues?
@ht89 @hassanasad this is what I used to make it work inside a parent container:
const container = document.querySelector('myParentContainer');
this.dragulaService.drag.subscribe(value => {
document.onmousemove = e => {
const event = e || window.event;
const mouseY = event['pageY'] - container.offsetTop;
const scrollTop = container.scrollTop;
const scrollBottom = container.offsetHeight - scrollTop;
const elementHeight = value[1].getBoundingClientRect().height;
if (mouseY - elementHeight / 2 < scrollTop) {
container.scrollBy(0, -15);
} else if (mouseY + elementHeight > scrollBottom) {
container.scrollBy(0, 15);
}
};
});
// detach the mouse move event when the drag ends
this.dragulaService.dragend.subscribe(value => {
document.onmousemove = null;
});
Hi @Nexxado , thanks for sharing! I was too busy and forgot @hassanasad question.
if anyone getting error for container.offsetTop
as [ts] Property 'offsetTop' does not exist on type 'Element'.
from typescript , make following change to @Nexxado answer -
const container = <HTMLElement>document.querySelector('myParentContainer');
I was looking for a solution that keeps on scrolling up/down slowly when a dragged element is moved to the top/bottom of the page and came up with this:
const DRAG_SCROLL_INTERVAL = 100;
const DRAG_SCROLL_DISTANCE = 50;
// ...
ngOnInit() {
// ...
this.dragulaService
.drag(this.DRAG_GROUP_ID)
.pipe(takeUntil(this.destroy$))
.subscribe(({ name, el, source }) => {
// add an event listener
document.onmousemove = e => {
let event = e || this.window.event;
let mouseY = event['pageY'];
let scrollTop = this.document.documentElement?.scrollTop || this.document.body.scrollTop;
let scrollBottom = scrollTop + this.window.innerHeight;
let elementHeight = el.clientHeight;
// and check if the event is on top or bottom of the page
if (mouseY - elementHeight / 2 < scrollTop) {
this.startScrollingUp();
} else if (mouseY + elementHeight / 2 > scrollBottom) {
this.startScrollingDown();
} else {
this.stopScrolling();
}
};
});
// detach the mouse move event when the drag ends
this.dragulaService.dragend(this.DRAG_GROUP_ID).subscribe(_ => {
document.onmousemove = null;
this.stopScrolling();
});
}
private startScrollingUp() {
if (this.scrollInterval) return; // don't set it multiple times
this.scrollInterval = this.window.setInterval(() => window.scrollBy({ top: -DRAG_SCROLL_DISTANCE }), DRAG_SCROLL_INTERVAL);
}
private startScrollingDown() {
if (this.scrollInterval) return;
this.scrollInterval = this.window.setInterval(() => window.scrollBy({ top: DRAG_SCROLL_DISTANCE }), DRAG_SCROLL_INTERVAL);
}
private stopScrolling() {
this.window.clearInterval(this.scrollInterval);
this.scrollInterval = null;
}
Thanks to @ndraiman and the others! 👍
PS: I think you missed / 2
in the else
branch.