JQuery sortable lists and fixed/locked items
Asked Answered
D

10

30

Is it possible to lock list items in JQuery sortable list in a way that those items will stay in that particular place in the list.

For example,

consider this pseudo list with locked items...

item A
item B(locked)
item C(locked)
item D
item E
item F
item G(locked)

So, I'd like to have the items B,C and G to be fixed in a way that if user drag and drop item D at the start of the list, the item A "jumps" over fixed/locked items B and C with following results...

item D
item B(locked)
item C(locked)
item A
item E
item F
item G(locked)

I've been searching for something like this without luck. Is it possible..?

Demean answered 28/11, 2010 at 21:39 Comment(2)
Perpaps unbind all events for the list items, and rebind events only those items which are not locked?Cannot
Can you show the jQuery code you're using to handle the sortable list, or maybe cobble together a JS Fiddle, or JS Bin, demo?Mondrian
R
27

I extended the jQuery.Ui.sortable:

Overview

jQuery.Ui.sortable widget extension with fixed feature. This feature allows user to fix elements in the list.
With the .fixedsortable() constructor you construct a .sortable() class which extended with the features. You can use the original methods and the extended as well.

Code

https://gist.github.com/3758329#file_fixedsortable.js > fixedsortable.js

Example

http://jsfiddle.net/omnosis/jQkdb/

Usage

General:

To use, add the fixed property to the sortable list optios:

$("#list").fixedsortable({
   fixed: (value)
})

the value can be:

  • integer example: 3
  • array of integers example : [1,2,5]
  • a html element or a list of html elements
  • a css selector
  • jquery object

HTML:

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script> //the jquery 
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script> //the original jquery-ui   
<script type="text/javascript" src="https://raw.github.com/gist/3758329/91749ff63cbc5056264389588a8ab64238484d74/fixedsortable.js"></script> //the extended sortable
...
<ul id="sortable1">
    <li>oranges</li>
    <li class="static">apples</li>
    <li>bananas</li>
    <li>pineapples</li>
    <li>grapes</li>
    <li class="static">pears</li>
    <li>mango</li>
</ul>

<ul id="sortable2">
    <li>bananas</li>
    <li foo="asd">oranges</li>
    <li foo="dsa">apples</li>
    <li>pineapples</li>
    <li>grapes</li>
    <li>pears</li>
    <li>mango</li>
</ul>

<ul id="sortable3">
    <li>bananas</li>
    <li>oranges</li>
    <li>apples</li>
    <li>pineapples</li>
    <li>grapes</li>
    <li>pears</li>
    <li>mango</li>
</ul>

Javascript

$(function() {
    $("#sortable1").fixedsortable({
        fixed: "> .static"
    });

    $("#sortable2").fixedsortable({
        fixed: $("li[foo]").css("background","red")
    });

    $("#sortable3").fixedsortable({
        fixed: 2
    })
});

Notes:

If you insist to use the .sortable instead of .fixedsortable you can use this https://gist.github.com/3758329#file_sortable.js instead of the jquery.ui library. This is a complete replacement of the jQuery.ui, but i don't recommend to use this because of later updates.

i have been working on this more than 12 hours :( i am insane..

Robinson answered 26/5, 2011 at 4:16 Comment(3)
Nice work! great answer, nicely laid out, fiddle link, explanation! Well done.Selfliquidating
Nice work! I've noticed that if the list items I'm sorting contain links (e.g., <li><a href="foo">fruit</a></li>) that behavior is not as expected. Moving a non-fixed list item works find, but the "fixed" item can be moved into a new position within the sortable. The original position of the fixed item retains the behavior of not having new items sorted into it. See this fork of your jsfiddle: jsfiddle.net/jbru/wphPG/1Pennyworth
is this script still available somewhere ? The link doesn't lead anywhere anymore. Thanks.Ardellearden
K
58

Here's a hopefully bug-free version, updating as you drag. It's generating the current desired positions of the items when sorting starts, which means you should be able to change the classes whenever you need, refresh the widget's list items and you're good to go.

It also uses the sortable's built-in items property to prevent dragging the fixed items and to sort out any sorting problems at the top and the bottom of the list.

I tried to move the fixed items around, but that resulted in horribly buggy behaviour, especially when there are multiple fixed items in groups. The final solution detaches all fixed items from the list, adds a helper element to the front, then re-inserts the fixed elements to their desired position, which seems to fix all bugs.

Try the demo here: http://jsfiddle.net/PQrqS/1/

HTML:

<ul id="sortable">
    <li>oranges</li>
    <li class="static">apples</li>
    <li>bananas</li>
    <li>pineapples</li>
    <li>grapes</li>
    <li class="static">pears</li>
    <li>mango</li>
</ul>

CSS:

.static { color:red; }

li { background-color:whitesmoke; border:1px solid silver; width:100px; padding:2px; margin:2px; }

Javascript:

$('#sortable').sortable({
    items: ':not(.static)',
    start: function(){
        $('.static', this).each(function(){
            var $this = $(this);
            $this.data('pos', $this.index());
        });
    },
    change: function(){
        $sortable = $(this);
        $statics = $('.static', this).detach();
        $helper = $('<li></li>').prependTo(this);
        $statics.each(function(){
            var $this = $(this);
            var target = $this.data('pos');

            $this.insertAfter($('li', $sortable).eq(target));
        });
        $helper.remove();
    }
});
Kanarese answered 25/5, 2011 at 22:10 Comment(9)
@Thomas Shields: No joy, it's horribly buggy, bounty is still up for grabs. :)Kanarese
Hopefully I've got it this time.Kanarese
Nice. The "feel" and operation is better than other methods, too.Pluck
@Alex: Thank YOU for the generous bounty.Kanarese
@alex did you checked my answer?Vezza
@omnosis hey I did and its a nice solution but I prefer this one as it's a cleaner implementation and doesn't involve extending the widget or altering jQuery UI.Mcneal
The helper object is only there to insert at position 0. In fact, this is never necessary, because if the item at position 0 is not sortable, Sortable will never move it. So you can just check for position 0 (or perforce check that the desired position is different from the current) and skip it. Then you can remove the helper.Folderol
@Kanarese - I'm trying to solve this same problem, and your solution isn't working for me - I think it's because my list items contain HTML rather than plain text. Would you be able to point me in the right direction in modifying your code? Here's an example of my list items: <li class="ui-state-default"><input type="hidden" name="id_1" id="id_1" value="1" /><p>Stuff<a href="#" onClick="remove($(this));">Close</a></p></li><li class="static">AND</li> Thanks.Chillon
I modified his script and managed to make work with tables and lists here is the link: plnkr.co/edit/hMeIiRFT97e9FGk7hmbsCralg
R
27

I extended the jQuery.Ui.sortable:

Overview

jQuery.Ui.sortable widget extension with fixed feature. This feature allows user to fix elements in the list.
With the .fixedsortable() constructor you construct a .sortable() class which extended with the features. You can use the original methods and the extended as well.

Code

https://gist.github.com/3758329#file_fixedsortable.js > fixedsortable.js

Example

http://jsfiddle.net/omnosis/jQkdb/

Usage

General:

To use, add the fixed property to the sortable list optios:

$("#list").fixedsortable({
   fixed: (value)
})

the value can be:

  • integer example: 3
  • array of integers example : [1,2,5]
  • a html element or a list of html elements
  • a css selector
  • jquery object

HTML:

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script> //the jquery 
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script> //the original jquery-ui   
<script type="text/javascript" src="https://raw.github.com/gist/3758329/91749ff63cbc5056264389588a8ab64238484d74/fixedsortable.js"></script> //the extended sortable
...
<ul id="sortable1">
    <li>oranges</li>
    <li class="static">apples</li>
    <li>bananas</li>
    <li>pineapples</li>
    <li>grapes</li>
    <li class="static">pears</li>
    <li>mango</li>
</ul>

<ul id="sortable2">
    <li>bananas</li>
    <li foo="asd">oranges</li>
    <li foo="dsa">apples</li>
    <li>pineapples</li>
    <li>grapes</li>
    <li>pears</li>
    <li>mango</li>
</ul>

<ul id="sortable3">
    <li>bananas</li>
    <li>oranges</li>
    <li>apples</li>
    <li>pineapples</li>
    <li>grapes</li>
    <li>pears</li>
    <li>mango</li>
</ul>

Javascript

$(function() {
    $("#sortable1").fixedsortable({
        fixed: "> .static"
    });

    $("#sortable2").fixedsortable({
        fixed: $("li[foo]").css("background","red")
    });

    $("#sortable3").fixedsortable({
        fixed: 2
    })
});

Notes:

If you insist to use the .sortable instead of .fixedsortable you can use this https://gist.github.com/3758329#file_sortable.js instead of the jquery.ui library. This is a complete replacement of the jQuery.ui, but i don't recommend to use this because of later updates.

i have been working on this more than 12 hours :( i am insane..

Robinson answered 26/5, 2011 at 4:16 Comment(3)
Nice work! great answer, nicely laid out, fiddle link, explanation! Well done.Selfliquidating
Nice work! I've noticed that if the list items I'm sorting contain links (e.g., <li><a href="foo">fruit</a></li>) that behavior is not as expected. Moving a non-fixed list item works find, but the "fixed" item can be moved into a new position within the sortable. The original position of the fixed item retains the behavior of not having new items sorted into it. See this fork of your jsfiddle: jsfiddle.net/jbru/wphPG/1Pennyworth
is this script still available somewhere ? The link doesn't lead anywhere anymore. Thanks.Ardellearden
S
9

Check this out: Forcing an item to remain in place in a jQuery UI Sortable list

Also, I've implemented the above solution with multiple fixed elements here: http://jsfiddle.net/enBnH/12/ (obsolete, see below) It's rather self-explanatory, i think.

EDIT:

I've automated the process for generating the lockto values as well as adding ID's to those lis with the class "fixed" (note that i have to add an ID so we can reference it)

See the COMPLETE solution HERE: http://jsfiddle.net/enBnH/44/

EDIT

Okay, after a gazillion errors with the above, i just rewrote the dang thing myself: http://jsfiddle.net/thomas4g/GPMZZ/15/

NOTE: The above does work, but @DarthJDG's answer seems a lot nicer to me. I'm leaving mine up on the offchance someone might prefer how mine behaves (i've learned not to delete stuff just beceause there's a better version :P )

Subarid answered 24/5, 2011 at 1:40 Comment(18)
Thanks for the answer, will check it out and report backMcneal
I think this is a different problem.Vezza
@omnosis how so? looks the same to me.Subarid
@omnosis the lockto variable has to match the id of the fixed element. See this working demo: jsfiddle.net/enBnH/8Subarid
this works only with one lockto at the same time. also the #static-1 id is polluting the id-s. btw nice demo.Vezza
@omnosis you can easily duplicate the code with another lockto, as shown here: jsfiddle.net/enBnH/10 of course, it'd also be easy to put several locktos in an array and loop through. i will do so momentarily.Subarid
yes this is working but not so nice solution for the problem. you have to recreate the change function every time depending on the id-s and the fixed valuesVezza
@omnosis, okay, i getcha. gimme a sec and i'll write a wrapper to generate the lockto values based one all lis with the class "static"Subarid
@omnosis finished! for the longest time i was stupid and was trying to grab the fixed li with .eq(locktos[i]) which of course doesn't work as the position changes. I had to generate an id. see updated answer :)Subarid
is bounty reawardable? within the active interval?Vezza
@omnosis, @Alex has to award it.Subarid
@omnosis what do you mean? it hasn't been awarded at all yet.Subarid
just asked. i know it hasn't benn awardedVezza
@Thomas Shields: I spotted a bug in your demo. Grab bananas, move it one down, then move it to the top. Whoosh, apples have just moved down, although they should be fixed. I have set a different style to the static ones to visualize it: jsfiddle.net/enBnH/45Kanarese
@Kanarese thanks, trying to fix it. if you find out what's wrong please let me know.Subarid
@Thomas Shields: Sorry for being a pain, but if there are two static items on the bottom, it's possible to move an item to the end of the list.Kanarese
@Kanarese i'm getting a feeling copying this code from the other answer wasn't a good idea, lol.Subarid
@Thomas Shield: update only fires when the sorting has finished, they still move around while dragging.Kanarese
M
4

Using the items parameter you can achieve what you want like this:

$("#mytable tbody").sortable({items: 'tr.sortable'});

Only rows with a .sortable CSS class can be sorted now.

If you want to lock only the 1st row you can do this:

$("#mytable tbody").sortable({items: 'tr:not(:first)'});

The possibilities are endless...

Mccurdy answered 23/1, 2014 at 21:48 Comment(1)
This doesn't work. Here's why. Grab "One" and drag it down. Note that "Two" moves above "One", when it should remain as the second item in the list.Coinstantaneous
C
4

This is based on @DarthJDG code. However it wasn't retrieving all the id's and the sorting wasn't working with the table. So I managed to update his solution which works with both list and tables and keeps the id in the array.

Javascript:

var fixed = '.static'; //class which will be locked
var items = 'li'; //tags that will be sorted

$('ul').sortable({
  cancel: fixed,
  items: items,
  start: function () {
    $(fixed, this).each(function () {
      var $this = $(this);
      $this.data('pos', $this.index());
    });
  },
  change: function () {
    var $sortable = $(this);
    var $statics = $(fixed, this).detach();
    var tagName = $statics.prop('tagName');
    var $helper = $('<'+tagName+'/>').prependTo(this);
    $statics.each(function () {
      var $this = $(this);
      var target = $this.data('pos');
      $this.insertAfter($(items, $sortable).eq(target));
    });
    $helper.remove();
  }
});

Demo: http://plnkr.co/edit/hMeIiRFT97e9FGk7hmbs

Cralg answered 27/6, 2014 at 16:15 Comment(0)
J
1

Connected sortables and fixed items

I ran into the problem when we have several connected sortables. The code suggested by @sarunast and @DarthJDG has erroneous behavior when dragging items from one list to another. Therefore, I have modified it a little, and now you can drag items from different lists with saving positions in both of them.

javascript:

let connected = '.soratble';
let fixed = '.static';
let newParentContainer;

//wrap the code suggested by @sarunast and @DarthJDG into the function
//code was modified a little
function sortingAroundFixedPositions(container) {
  let sortable = $(container);
  let statics = $(fixed, container).detach();
  let tagName = statics.prop('tagName');
  let helper = $('<' + tagName + '/>').prependTo(container);
  statics.each(function() {
    let target = this.dataset.pos;
    let targetPosition = $(tagName, sortable).eq(target);
    if (targetPosition.length === 0) {
      targetPosition = $(tagName, sortable).eq(target - 1)
    }
    $(this).insertAfter(targetPosition);
  });
  helper.remove();
}

$('ul').sortable({
  connectWith: connected,
  cancel: fixed,
  start: function() {
    $(fixed, connected).each(function() {
      this.dataset.pos = $(this).index();
    });
  },
  change: function(e, ui) {
    sortingAroundFixedPositions(this);
    if (ui.sender) {
      newParentContainer = this;
    }
    if (newParentContainer) {
      sortingAroundFixedPositions(newParentContainer);
    }
  },
  update: function(e, ui) {
    newParentContainer = undefined;
  }
});

demo: http://plnkr.co/edit/blmv4ZjaWJFcjvO2zQH0

Julian answered 13/3, 2018 at 18:17 Comment(0)
M
1

Just use the "Include/Exclude" items selectors. Here is the link: https://jqueryui.com/sortable/#items

Museology answered 13/8, 2020 at 19:15 Comment(0)
R
0

oh no! gist link is broken. here is code dump from https://gist.github.com/peterh-capella/4234752

code accessed Jan 6, 2016

//this code is created to fix this problem: http://stackoverflow.com/questions/4299241/

(function( $, undefined ) {

$.widget("ui.fixedsortable", $.ui.sortable, {

    options: $.extend({},$.ui.sortable.prototype.options,{fixed:[]}),

    _create: function() {
      var o = this.options;
      this.containerCache = {};
      this.element.addClass("ui-sortable");

      //Get the items
      $.ui.sortable.prototype.refresh.apply(this,arguments);

      if( typeof this.options.fixed == "number") {
        var num = this.options.fixed
        this.options.fixed = [num];
      }
      else if( typeof this.options.fixed == "string" || typeof this.options.fixed == "object") {
        if(this.options.fixed.constructor != Array) {
          var selec = this.options.fixed;
          var temparr = [];
          var temp = $(this.element[0]).find(selec);
          var x = this;


          temp.each(function() {
            var i;
            for(i=0;i<x.items.length && x.items[i].item.get(0) != this;++i) {}
            if(i<x.items.length) temparr.push(i);
          });
          this.options.fixed = temparr;
        }
      }   


      //Let's determine if the items are being displayed horizontally
      this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;

      //Let's determine the parent's offset
      this.offset = this.element.offset();

      //Initialize mouse events for interaction
      $.ui.sortable.prototype._mouseInit.apply(this,arguments);
    },

    _mouseCapture: function( event ) { 

      this._fixPrev = this._returnItems();
      return $.ui.sortable.prototype._mouseCapture.apply(this,arguments);
    },

    _mouseStart: function( event ) { 

      for(var i=0;i<this.options.fixed.length;++i) {
        var num = this.options.fixed[i];
        var elem = this.items[num];
        if(event.target == elem.item.get(0)) return false;
      }

      return $.ui.sortable.prototype._mouseStart.apply(this,arguments);
    },

    _rearrange: function(event, i, a, hardRefresh) {

      a ? a[0].appendChild(this.placeholder[0]) : 
      i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));

      this._refix(i);



      //Various things done here to improve the performance:
      // 1. we create a setTimeout, that calls refreshPositions
      // 2. on the instance, we have a counter variable, that get's higher after every append
      // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
      // 4. this lets only the last addition to the timeout stack through



      this.counter = this.counter ? ++this.counter : 1;
      var self = this, counter = this.counter;


      window.setTimeout(function() {
        if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
      },0);

    },

    _refix: function(a) {
      var prev = this._fixPrev;
      var curr = this._returnItems();

      var Fixcodes = this.options.fixed;

      var NoFixed = [];
      var Fixed = [];
      var Mixed = []
      var post = [];


      for(var i=0;i<Fixcodes.length;++i) {
        var fix_index = Fixcodes[i];
        var fix_item  = prev[fix_index];
        var j = 0;

        for(j=0;j<curr.length && curr[j].item.get(0) != fix_item.item.get(0);++j) {}

        curr.splice(j,1);

        Fixed.push(fix_item);
      }

      for(var i=0;i<curr.length;++i) {
        if(curr[i].item.get(0) != this.currentItem.get(0)) {
          NoFixed.push(curr[i]);
        }
      }

      var fix_count = 0;
      var nofix_count = 0;

      for(var i=0;i<Fixed.length + NoFixed.length;++i) {
        if(Fixcodes.indexOf(i) >= 0) {
          Mixed.push(Fixed[fix_count++]);
        }
        else {
          Mixed.push(NoFixed[nofix_count++]);
        }
      }

      var parent = this.currentItem.get(0).parentNode;    
      var allchild = parent.children;

      for(var i=0;i<Mixed.length;++i) {
        parent.removeChild(Mixed[i].item.get(0));
        parent.appendChild(Mixed[i].item.get(0));
      }
    },

    _returnItems: function(event) {

      this.containers = [this];
      var items = [];
      var self = this;
      var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
      var connectWith = $.ui.sortable.prototype._connectWith.apply;

      if(connectWith) {
        for (var i = connectWith.length - 1; i >= 0; i--){
          var cur = $(connectWith[i]);
          for (var j = cur.length - 1; j >= 0; j--){
            var inst = $.data(cur[j], 'sortable');
            if(inst && inst != this && !inst.options.disabled) {
              queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
              this.containers.push(inst);
            }
          };
        };
      }

      for (var i = queries.length - 1; i >= 0; i--) {
        var targetData = queries[i][1];
        var _queries = queries[i][0];

        for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
          var item = $(_queries[j]);

          item.data('sortable-item', targetData); // Data for target checking (mouse manager)

          items.push({
            item: item,
            instance: targetData,
            width: 0, height: 0,
            left: 0, top: 0
          });
        };
      };

      return items;
    },


    value: function(input) {
        //console.log("test");
        $.ui.sortable.prototype.value.apply(this,arguments);
    }
});

})(jQuery);

And dumping rest of his answer, just in case

dependencies

https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js

Script

function randomColor() { //for a little fun ;)
   var r = (Math.floor(Math.random()*256));
   var g = (Math.floor(Math.random()*256));
   var b = (Math.floor(Math.random()*256));

   return "#" + r.toString(16) + g.toString(16) + b.toString(16)
}

$(function() {
    $("#sortable1").fixedsortable({
        fixed: "> .static", //you can use css selector
        sort: function() {  //you can add events as well, without getting confused. for example:
            $(".static").css("background",randomColor())  //change the fixed items background
        },
        change: function(event,ui) {
            $(ui.item[0]).css("border","2px solid "+randomColor())  //change the captured border color
        },
        stop: function(event,ui) {
            $(ui.item[0]).css("border","2px solid #777"); //change the back the css modifications
            $("#sortable1 > li.static").css("background","#aaa");
        }
    });

    $("#sortable2").fixedsortable({  //you can use jQuery object as selector
        fixed: $("li[foo]").css("background","red")
    });

    $("#sortable3").fixedsortable({
        fixed: [2,4], //you can use array of zero base indexes as selector
        update: function(event, ui) {
            alert($(this).fixedsortable('toArray'))   //the fixedsortable('toArray') also works
        }
    })

    $("#sortable4").fixedsortable({
        fixed: 5  //you can fix a single item with a simple integer
    })
});

HTML

 <body>
    <div style="width:120px;float:left;">
    <ul id="sortable1">
        <li><a href="#">oranges</a></li>
        <li class="static"><a href="#">apples</a></li>
        <li><a href="#">bananas</a></li>
        <li><a href="#">pineapples</a></li>
        <li><a href="#">grapes</a></li>
        <li class="static"><a href="#">pears</a></li>
        <li><a href="#">mango</a></li>
    </ul>

    <ul id="sortable2">
        <li>bananas</li>
        <li foo="asd">oranges</li>
        <li foo="dsa">apples</li>
        <li>pineapples</li>
        <li>grapes</li>
        <li>pears</li>
        <li>mango</li>
    </ul>
    </div>
    <div style="width:120px;float:left;">
    <ul id="sortable3">
        <li id="fru_1">bananas</li>
        <li id="fru_2">oranges</li>
        <li id="fru_3" style="background:#f4f">apples</li>
        <li id="fru_4">pineapples</li>
        <li id="fru_5" style="background:#faaba9">grapes</li>
        <li id="fru_6">pears</li>
        <li id="fru_7">mango</li>
    </ul>


    <ul id="sortable4">
        <li>bananas</li>
        <li>oranges</li>
        <li>apples</li>
        <li>pineapples</li>
        <li>grapes</li>
        <li style="background:#dada00">pears</li>
        <li>mango</li>
    </ul>
   </div>
</body>

CSS

ul {margin:10px;}
ul#sortable1 > li, ul#sortable2 > li, ul#sortable3 > li, ul#sortable4 > li {
    display:block;
    width:100px;
    height:15px;
    padding: 3px;
    background: #aaa;
    border: 2px solid #777;
    margin: 1px;
}
ul#sortable1 > li.static {
    opacity:0.5;
}
Rm answered 28/11, 2010 at 21:39 Comment(0)
D
0

Maybe this will help to someone: use methods "disable" and "enable". Example HTML:

<ul class="sortable">
  <li>You can move me</li>
  <li data-state="lifeless">You can't move me.</li>
</ul>

Script:

$('#sortable').sortable();
$('#sortable').mousedown(function() {
  if($(this).data('state')=='lifeless') $('#sortable').sortable('disable');
  else $('#sortable').sortable('enable');
});

Live example here: https://jsfiddle.net/ozsvar/0ggqtva5/2/

Dianoetic answered 27/6, 2016 at 10:59 Comment(1)
almost but not really a usable answer as reordering can still occur using a non disabled item...Housewifely
H
0

There is a slightly better way to solve this. You need to use a grid instead of a list and then you can fix the position of an element by declaring where the element should be arranged with css:

.fixed-element {
   grid-column-start: 1;
   grid-column-end: 1;
   grid-row-start: 1;
   grid-row-end: 1;
}
Halfwit answered 4/11, 2021 at 8:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.