49

I have a <ul> list that I want to make sortable (drag & drop). How can I get it to work with Bootstrap 3 in modern browsers and touch devices?

I'm trying to use jqueryui-sortable combined with http://touchpunch.furf.com/; it seems to work, but it's hacky and jQueryUI doesn't play nice with Bootstrap.

How can I avoid Bootstrap/jQueryUI conflicts while adding touch-screen support?

Shog9
  • 156,901
  • 35
  • 231
  • 235
brk
  • 631
  • 1
  • 6
  • 4
  • http://stackoverflow.com/questions/11177735/ordering-list-with-jquery-drag-and-drop –  Jan 24 '14 at 10:40
  • made this based on gridster, [link](https://github.com/gcphost/gridster-responsive) - initial release is for a dashboard but you can probably get it to work for a regular list – Will Bowman Apr 19 '14 at 16:47

2 Answers2

77

The answers posted before this one are surprisingly outdated.

is a fast, no-dependencies, small reorderable lists widget with touch support that works with the HTML5 native drag&drop API. You can use it with Bootstrap, Foundation, or any CSS library you want, and instantiating it only takes one line.

It supports reordering within a list or across lists. You can define lists that can only receive elements, or lists from which you can drag, but onto which you cannot drop. It's also very actively maintained and MIT licensed on GitHub.

new Sortable(document.getElementsByClassName('sortable')[0]);
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">

<!-- Sortable -->
<script src="https://rawgit.com/RubaXa/Sortable/master/Sortable.js"></script>

<ul class="list-group sortable">
  <li class="list-group-item">This is <a href="http://rubaxa.github.io/Sortable/">Sortable</a></li>
  <li class="list-group-item">It works with Bootstrap...</li>
  <li class="list-group-item">...out of the box.</li>
  <li class="list-group-item">It has support for touch devices.</li>
  <li class="list-group-item">Just drag some elements around.</li>
</ul>
Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
44

Just thought I'd post a supplemental answer to the one from @KyorCode. I followed his advice and went with JQuery Sortable and it worked seamlessly for me. It took me maybe 10 minutes to get this working.

I didn't have to include any JQuery UI CSS - just the JavaScript - so there were no issues with the CSS conflicting in anyway with Bootstrap.

Working Example:

Here's a working example on www.bootply.com.

HTML:

<!-- Bootstrap 3 panel list. -->
<ul id="draggablePanelList" class="list-unstyled">
    <li class="panel panel-info">
        <div class="panel-heading">You can drag this panel.</div>
        <div class="panel-body">Content ...</div>
    </li>
    <li class="panel panel-info">
        <div class="panel-heading">You can drag this panel too.</div>
        <div class="panel-body">Content ...</div>
    </li>
</ul>

JavaScript:

You can download JQuery Sortable without including the whole of JQuery UI in your page.

<!-- Assumes that JQuery is already included somewhere. Size: 22kb or 13kb minified. -->
<script src="/Scripts/jquery-ui-1.10.4.custom.js"></script>

<script type="text/javascript">
    jQuery(function($) {
        var panelList = $('#draggablePanelList');

        panelList.sortable({
            // Only make the .panel-heading child elements support dragging.
            // Omit this to make the entire <li>...</li> draggable.
            handle: '.panel-heading', 
            update: function() {
                $('.panel', panelList).each(function(index, elem) {
                     var $listItem = $(elem),
                         newIndex = $listItem.index();

                     // Persist the new indices.
                });
            }
        });
    });
</script>

CSS:

<style type="text/css">
    /* show the move cursor as the user moves the mouse over the panel header.*/
    #draggablePanelList .panel-heading {
        cursor: move;
    }
</style>

HTH

sheikhjabootie
  • 7,308
  • 2
  • 35
  • 41
  • 1
    @light24bulbs - Just tested it on my iPad, and it doesn't work, maybe by design... If I'm honest, I don't like the idea of drag-and-drop on touch devices, because it's hard (impossible?) to tell the difference between scroll actions and drag actions. I use JIRA for bug tracking, and one of my gripes about their interface is that I keep accidentally changing issue priorities when I try to scroll on my iPad because it allows issues to be dragged into priority order. It's a great feature on desktop, but a better approach for touch would be fat-finger-sized up/down arrows on each row. – sheikhjabootie Apr 12 '14 at 05:37
  • @Acentric why not use a [handle](http://api.jqueryui.com/1.10/sortable/#option-handle) and/or [delay](http://api.jqueryui.com/1.10/sortable/#option-delay) to distinguish between scroll and drag actions? – speendo Aug 29 '14 at 19:23
  • 1
    @speendo - I am using handle in my example. There's a brief discussion of [the UX concerns of drag-and-drop on touch devices](http://ux.stackexchange.com/questions/24321/drag-n-drop-on-touch-devices) - but essentially it conflicts with scroll gestures, and many devices now use the long-touch as a right-click - so delay can conflict with that. – sheikhjabootie Sep 07 '14 at 12:30
  • @Acentric fair enough. – speendo Sep 07 '14 at 13:08
  • 1
    One minor caveat -- you may encounter some namespace collisions running both jQuery UI and Bootstrap together. You can mitigate this by either performing a custom jQuery UI export and including only the features you need (as is the case here), or by using jQuery's 'bridge' function to rename the jQuery UI functions that duplicate Bootstrap functions, such as 'tooltip' and 'button.' See http://stackoverflow.com/questions/13731400/jqueryui-tooltips-are-competing-with-twitter-bootstrap for more information. – kiprainey Sep 10 '14 at 16:34
  • When I copy and paste your code to codeply, it does not work for me. – crh225 Jul 06 '16 at 22:21