In a Web app I'm writing, users can add their own customized buttons to a control panel and then change the order of those buttons via drag-and-drop. I’m using jQuery UI's Sortable Widget to make the magic happen.
The buttons are arranged in a single row, left to right. I’m using flexbox to style them, and I've set the sortable
method to allow movement only along the X axis. Everything is working well for the most part, BUT…
At first, I couldn’t figure out why the buttons at the far left and right sometimes behaved as desired and sometimes didn’t. Eventually I realized it all depended on where I grabbed the button I was dragging. The JSFiddle I’ve set up illustrates the problem:
https://jsfiddle.net/DanRobinson/8nap51Lg/78/
In the Fiddle, if you grab the middle button close to its left edge, you can successfully drag it to the beginning of the row, but not to the end of the row. Conversely, if you grab that same button close to its right edge, you can drag it to the end of the row, but not to the beginning.
I want the buttons to behave consistently no matter where the user happens to grab them. Is there a setting in the Sortable Widget that will solve this problem? (Changing the “tolerance” setting to “pointer” doesn’t seem to help.)
<div id="container">
<div>Custom Button 1</div>
<div>Custom Button 2 is wider than the others</div>
<div>Custom Button 3</div>
</div>
#container {
display: flex;
flex-direction: row;
padding: 10px;
border: 1px solid black;
margin-top: 20px;
width: 600px;
}
#container > div {
flex: 0 1 auto;
padding: 2px 8px;
margin: 0 5px;
border: 1px solid #777;
border-radius: 3px;
background-color: #E1E1E1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
cursor: default;
}
$(document).ready(function () {
$("#container").sortable({
axis: "x",
containment: "parent",
});
});
I hate to see people waste their time on a question I'm no longer interested in the answer to, so I'm going to close the loop by answering my own question.
For the product I was working on when I asked this question (nearly five years ago), I ended up solving the problem by switching to SortableJS:
https://github.com/SortableJS/Sortable
Obviously, SortableJS is not nearly as well-known or widely used as jQuery UI, but for managing a drag-and-drop interface, I found it superior in every way. For instance: (1) SortableJS supports touch events without requiring an extension or patch; (2) its event handlers actually provide all the data you need to respond to each event; and (3) it can handle the situation I've documented here (arguably an edge case) without glitches, whereas jQuery UI cannot.