Reputation: 6810
I'm having difficulty disabling sorting on a specific li
in my ul
.
I'm using SortableJS.
<ul id="items">
<li class="static">
<div class="image"><img src="image.jpg" /></div>
<div class="text">Static</div>
<div class="clearboth"></div>
</li>
<li>
<div class="image"><img src="image.jpg" /></div>
<div class="text">Dynamic</div>
<div class="clearboth"></div>
</li>
<li>
<div class="image"><img src="image.jpg" /></div>
<div class="text">Dynamic</div>
<div class="clearboth"></div>
</li>
</ul>
One li
with class static
should NOT be sortable. The others should be sortable.
var el = document.getElementById('items');
var sortable = new Sortable(el, {
onUpdate: function (evt) {
var itemEl = evt.item;
// here happens some stuff
},
filter: '.js-remove',
onFilter: function (evt) {
// here happens some stuff
}
});
I know you can do it in jQuery UI sortable like this:
$( ".sortable" ).sortable({
cancel: ".static"
});
How can I do this in SortableJS?
Upvotes: 6
Views: 11766
Reputation: 513
You need to add two options when creating the sortable instance:
var container = document.getElementById('my-list');
var sortable = Sortable.create(container, {
// 1.) Exclude all elements having class '.static' from being draggable.
draggable: 'li:not(.static)',
// 2.) Prevent all elements having class '.static' from being moved.
onMove(e) {
return e.related.className.indexOf('static') === -1;
}
});
Why should I not use filter
option?
Looking at the accepted answer, it seems like the filter
option would do the job. But whenever you use multiple instances with interchangeable elements, it becomes problematic if one of the lists get empty. Suddenly you won't be able to add elements to that list again. This is due to Sortable's internal logic, which still treats the .static
element as a draggable element. Even setting the emptyInsertThreshold
option to be really high won't fix that, because for Sortable, the list is not empty.
Example 1 using filter
option: (Try to add 'Apple' to COMPANIES - it won't work!)
var el = document.getElementById('items');
var sortable = Sortable.create(el, {
draggable: 'li:not(.static)',
group: {
name: 'list'
},
onMove(e) {
return e.related.className.indexOf('static') === -1;
}
});
var items2 = document.getElementById('items2');
var sortable = Sortable.create(items2, {
filter: '.static',
group: {
name: 'list'
},
onMove(e) {
return e.related.className.indexOf('static') === -1;
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/Sortable/1.14.0/Sortable.min.js"></script>
<ul id="items">
<li class="static">FRUITS</li>
<li>Strawberry</li>
<li>Banana</li>
<li>Peach</li>
<li>Apple</li>
</ul><ul id="items2">
<li class="static">COMPANIES</li>
</ul>
Example 2 using draggable
option: (Try to add 'Apple' to COMPANIES - it works!)
var el = document.getElementById('items');
var sortable = Sortable.create(el, {
draggable: 'li:not(.static)',
group: {
name: 'list'
},
onMove(e) {
return e.related.className.indexOf('static') === -1;
}
});
var items2 = document.getElementById('items2');
var sortable = Sortable.create(items2, {
draggable: 'li:not(.static)',
group: {
name: 'list'
},
onMove(e) {
return e.related.className.indexOf('static') === -1;
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/Sortable/1.14.0/Sortable.min.js"></script>
<ul id="items">
<li class="static">FRUITS</li>
<li>Strawberry</li>
<li>Banana</li>
<li>Peach</li>
<li>Apple</li>
</ul><ul id="items2">
<li class="static">COMPANIES</li>
</ul>
Upvotes: 2
Reputation: 29277
Further to @BenG comment, you need to use filter
instead of cancel
.
var el = document.getElementById('items');
var sortable = Sortable.create(el, {
filter: ".static"
});
<script src="//cdnjs.cloudflare.com/ajax/libs/Sortable/1.4.2/Sortable.min.js"></script>
<link href="http://rubaxa.github.io/Sortable/st/app.css" rel="stylesheet" />
<ul id="items" class="block__list block__list_words">
<li>item 1</li>
<li class="static">item 2</li>
<li>item 3</li>
</ul>
Upvotes: 11