7

Scrolling a div that is within a .sortable() container will start dragging the div when you release the scrollbar

In the fiddle, there are 3 different sortables, 1 of them is a scrolling one

http://jsfiddle.net/wnHWH/1/

Bug: click on the scrollbar and drag it up or down to scroll through the content, when you release the mouse, the div starts to drag, which makes it follow your mouse around and there is no way to unstick it without refreshing the page.

4
  • 1
    A possible answer could be setting a title element that serves as the part you click to drag while keeping the scrollable content separate
    – dansch
    Commented Nov 8, 2012 at 16:28
  • I am trying to figure out the same problem. I have noticed that this behavior exists in Chrome. You can get the div to release from the mouse without refreshing by right-clicking and then clicking somewhere else. In Firefox, trying to scroll only succeeds in dragging the div, no scrolling happens, but it does not stick to the mouse when you release it. I haven't checked IE yet.
    – jonhopkins
    Commented Nov 26, 2012 at 17:23
  • I can't repo in Chrome or Safari on OS X 10.7. What browser/OS combos does this occur in? Commented Dec 1, 2012 at 4:53
  • The fault occurs for me in Chrome 23.0.1271.95 m and IE 9. Both running on Windows 7.
    – Lee Taylor
    Commented Dec 1, 2012 at 13:00

3 Answers 3

5
+150

You can use .mousemove event of jquery like this:

$('#sortable div').mousemove(function(e) {
    width = $(this).width();
    limit = width - 20;
    if(e.offsetX < width && e.offsetX > limit)
        $('#sortable').sortable("disable");
    else
        $('#sortable').sortable("enable");
});

I have create fiddle that works here http://jsfiddle.net/aanred/FNzEF/. Hope it meets your need.

6
  • This looks like it's close. However, if I add an outer DIV to the whole lot, with a padding of say 50px, the calculations are offset. Can this be fixed?
    – Lee Taylor
    Commented Dec 1, 2012 at 13:03
  • @LeeTaylor see my updated fiddle you need to change the pageX with offsetX.
    – SubRed
    Commented Dec 1, 2012 at 13:45
  • Many thanks. I'll have a look at testing this with my project later. Thanks for your time.
    – Lee Taylor
    Commented Dec 1, 2012 at 13:47
  • while I ended up just using a title element and setting the handle to be it(non scrollable), this works.
    – dansch
    Commented Dec 12, 2012 at 19:35
  • This isn't actually that good of a solution, because if you move your mouse out of the scrollbar's width while dragging, you'll trigger the sortable event and it will get stuck anyway. Commented Mar 10, 2013 at 16:12
4

sortable() can specify a selector for a handle much like draggable() does. Then only the matched elements get the click events. You specify the handle selector like this:

$('#sortable').sortable( {handle : '.handle'});

You already have most of what you need for the rest. The inner div on your overflowing element makes a suitable handle, like this:

<div style="height: 200px;overflow:auto">
    <div class="handle" style="height: 300;">
        blah
        blah
        blah

Then you need to restore the sortability of everything else. You'd think you could just give those divs the handle class, but it's looking for children, so you need to wrap all of them like so:

<div><div class="handle">asadf</div></div>

Modified fiddle

2
  • this answer is working perfect. it doesnt break if we click on the scroller
    – Rafee
    Commented Dec 1, 2012 at 14:08
  • This is the best answer. chosen answer is a hack and fails when you drag the mouse out of the scrollbar width boundary while scrolling. Sure, the hack prevents the issue if you keep the mouse within the width range of the scrollbar you specify, but users don't do that when they scroll. They move the mouse far to the left/right of the scrollbar quite often. Commented Mar 10, 2013 at 16:18
3

Supplement to SubRed's answer:


This worked perfectly for my needs. However, rather than rely on the width of the scrollbar being 20 pixels (as above), I used the code from:

How can I get the browser's scrollbar sizes?

This allows the code to handle different scrollbar widths on different setups. The code is pasted here for convenience:

function getScrollBarWidth () 
{
    var inner = document.createElement('p');
    inner.style.width = "100%";
    inner.style.height = "200px";

    var outer = document.createElement('div');
    outer.style.position = "absolute";
    outer.style.top = "0px";
    outer.style.left = "0px";
    outer.style.visibility = "hidden";
    outer.style.width = "200px";
    outer.style.height = "150px";
    outer.style.overflow = "hidden";
    outer.appendChild (inner);

    document.body.appendChild (outer);
    var w1 = inner.offsetWidth;
    outer.style.overflow = 'scroll';
    var w2 = inner.offsetWidth;
    if (w1 == w2) w2 = outer.clientWidth;

    document.body.removeChild (outer);

    return (w1 - w2);
}

I've also used the width value for the height of the scrollbar and modified SubRed's code to suit. This now works with one or both scrollbars.

I also used code from:

Detecting presence of a scroll bar in a DIV using jQuery?

To determine the presence of either scroll bar and adapted the turning on/off of the sortable code accordingly.

Many thanks.

Not the answer you're looking for? Browse other questions tagged or ask your own question.