jneander jneander - 2 months ago 40
jQuery Question

Disable drag bubbling for nested sortable items in jQueryUI

Given a set of sortable/draggable containers, each of which contains draggable/sortable list items, how can list items be optionally non-sortable without allowing the drag event(s) to bubble up to the parent container?

In the example below, if you drag on 'Item 3 (Disabled)', the parent container becomes the drag target. It should still be draggable, but only outside of the inner items.

<script>
$(function () {
$('.sortable').sortable({
items: '.draggable'
});
$('.sortable').disableSelection();
});
</script>

<ul class="sortable outer">
<li class="outer-item draggable">
<ul class="sortable">
<li class="inner-item draggable"></span>Item 1</li>
<li class="inner-item draggable"></span>Item 2</li>
<li class="inner-item"></span>Item 3 (Disabled)</li>
</ul>
</li>
<li class="outer-item draggable">
<ul class="sortable">
<li class="inner-item draggable"></span>Item 4</li>
<li class="inner-item draggable"></span>Item 5</li>
<li class="inner-item draggable"></span>Item 6</li>
</ul>
</li>
</ul>


https://codepen.io/jneander/full/NRNZqL/

Answer

In order to stop the dragging event for non-sortable element you may disable the items not included:

$(function () {
  $('.sortable').sortable({
    items: '.draggable'
  });
  $('li:not(".draggable")').on('mousedown', function(e) {
    e.stopPropagation();
  });
});
body {
  font-family: Helvetica, sans-serif;
  color: #222;
}

.sortable {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

.outer {
  padding: 1em;
  width: 200px;
}

.outer-item {
  background: #f9f3f3;
  border: 1px solid #e1c5c5;
  padding: 1em;
}

.outer-item:not(:last-child) {
  margin-bottom: 1em;
}

.inner-item {
  background: #f6f6f6;
  border: 1px solid #c5c5c5;
  padding: 0.5em;
}

.inner-item:not(:last-child) {
  margin-bottom: 0.5em;
}
#sortable { list-style-type: none; margin: 0; padding: 0; width: 60%; }
#sortable li { margin: 0 3px 3px 3px; padding: 0.4em; padding-left: 1.5em; font-size: 1.4em; height: 18px; }
#sortable li span { position: absolute; margin-left: -1.3em; }
<link href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>

<ul class="sortable outer">
    <li class="outer-item draggable">
        <ul class="sortable">
            <li class="inner-item draggable"></span>Item 1</li>
            <li class="inner-item draggable"></span>Item 2</li>
            <li class="inner-item"></span>Item 3 (Disabled)</li>
        </ul>
    </li>
    <li class="outer-item draggable">
        <ul class="sortable">
            <li class="inner-item draggable"></span>Item 4</li>
            <li class="inner-item draggable"></span>Item 5</li>
            <li class="inner-item draggable"></span>Item 6</li>
        </ul>
    </li>
</ul>