Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SortableJS - can't exclude item from being draggable and sortable

I've already submitted an issue here but just wanted to check if you can solve this faster here.

Trying to exclude an item from being draggable works but not from being sortable -- the problem is that other elements can be placed behind it.

SortableJS Docs don't seem to have exclude.

Here's the expected behavior using jQuery UI:

//jQuery UI
$("#demo .sortable").sortable({
    items: "li:not(.exclude)",
    cancel: "li.exclude"
});
$("#demo .sortable").disableSelection();

$('.add-new').click(function(){
    $(this).prev().clone().insertBefore(this);
});
h1{ font-size: 1em; margin:1em}
.sortable { list-style-type: none; margin: 0; padding: 0; width: 260px; overflow:auto; }
.sortable li { background:lightgray; text-align:center; float:left; width:50px; height:50px; margin:0.2em; padding: 0.2em; cursor:move; }
.sortable li.add-new{cursor:default; color:#959595; opacity:0.8; background: white; outline:2px dotted gray}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>

<h1>jQuery UI</h1>
<div id="demo">
    <ul class="sortable">
        <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 1</li>
        <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 2</li>
        <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 3</li>
        <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 4</li>
        <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 5</li>
        <li class="ui-state-default add-new exclude"><span class="ui-icon ui-icon-plus"></span>Add New Item</li>
    </ul>
    
</div><!-- End demo -->

Notice that you can never place an item after the last "Add New Item". This is another example using jQuery UI that makes distinction between sortable and drop target and can disable it either one.

What I've tried so far with SortableJS:

// SortableJS

let mySortable = $("#demo2 .sortable").sortable({
  draggable: "li:not(.exclude)",
  animation: 250,
  forceFallback: true,
  removeCloneOnHide: true,
  touchStartThreshold: 10,

  onMove: function(evt) {
    //doesn't work
    //console.log ($(evt.dragged).index(),$('.exclude').index());
    //return $(evt.dragged).is(':last-child') ? false : true; 
  },

  onEnd: function(evt) {
    var itemEl = evt.item; // dragged HTMLElement
    if (!$('.exclude').is(':last-child')) {
      // Somewhat works but is super hacky and visually bad.
      //$('.exclude').appendTo($('.exclude').parent());  
    }
  }
});


$('.add-new').click(function(){
    $(this).prev().clone().insertBefore(this);
});
h1{ font-size: 1em; margin:1em}
.sortable { list-style-type: none; margin: 0; padding: 0; width: 260px; overflow:auto; }
.sortable li { background:lightgray; text-align:center; float:left; width:50px; height:50px; margin:0.2em; padding: 0.2em; cursor:move; }
.sortable li.add-new{cursor:default; color:#959595; opacity:0.8; background: white; outline:2px dotted gray}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-sortablejs@latest/jquery-sortable.js"></script>



<h1>SortableJS</h1>
<div id="demo2">
  <ul class="sortable">
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 1</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 2</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 3</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 4</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 5</li>
    <li draggable="false" droppable="false" class="ui-state-default add-new exclude"><span class="ui-icon ui-icon-plus"></span>Add New Item</li>
  </ul>

</div>
<!-- End demo -->

I don't want to take the "Add New Item" out of the sortable div or position:absolute it Any idea how to accomplish this?

Thanks!

like image 207
Miro Avatar asked Mar 25 '26 15:03

Miro


1 Answers

If you check documentation there is one option filter: ".ignore-elements" you can use this to ignore elements which you do not want to be draggable . Then , check if the related target element doesn't have exclude class depending on this return true or false to cancel event.

Demo Code :

let mySortable = $("#demo2 .sortable").sortable({
  animation: 250,
  forceFallback: true,
  removeCloneOnHide: true,
  touchStartThreshold: 10,
  filter: ".exclude", //use this
  onMove: function(evt) {
    return evt.related.className.indexOf('exclude') === -1; //and this
  }
});


$('.add-new').click(function() {
  $(this).prev().clone().insertBefore(this);
});
h1 {
  font-size: 1em;
  margin: 1em
}

.sortable {
  list-style-type: none;
  margin: 0;
  padding: 0;
  width: 260px;
  overflow: auto;
}

.sortable li {
  background: lightgray;
  text-align: center;
  float: left;
  width: 50px;
  height: 50px;
  margin: 0.2em;
  padding: 0.2em;
  cursor: move;
}

.sortable li.add-new {
  cursor: default;
  color: #959595;
  opacity: 0.8;
  background: white;
  outline: 2px dotted gray
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-sortablejs@latest/jquery-sortable.js"></script>



<h1>SortableJS</h1>
<div id="demo2">
  <ul class="sortable">
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 1</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 2</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 3</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 4</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 5</li>
    <li draggable="false" droppable="false" class="ui-state-default add-new exclude"><span class="ui-icon ui-icon-plus"></span>Add New Item</li>
  </ul>

</div>
like image 165
Swati Avatar answered Mar 27 '26 03:03

Swati



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!