dansch
dansch

Reputation: 6267

jquery ui sortable - clicking scrollbar breaks it

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.

Upvotes: 7

Views: 1784

Answers (3)

Lee Taylor
Lee Taylor

Reputation: 7994

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.

Upvotes: 3

SubRed
SubRed

Reputation: 3187

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.

Upvotes: 5

FoolishSeth
FoolishSeth

Reputation: 4031

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

Upvotes: 4

Related Questions