I'm trying to find out the correct way to remove items from a JQuery UI Sortable list. I've created a JSfiddle illustrating my problem.
Basically, I have a couple of callbacks around a JQuery UI sortable widget, and I want these callbacks to be executed as soon as I remove an element from the widget. What's the correct way to do so? Because "$.remove" nor "$.detach" seems to work.
EDIT 1: I'm not looking for a hotfix on my problem but more of an explanation of how the JQuery UI Sortable list works, while the answers below clearly solve the problem. I don't think it's a clean way of doing it. I think that JQuery UI Sortable should be aware that when you remove an element from the list that's between two elements you should be needing a re-sort
If you take note below the function does not gets executed when I call remove on an element.
$(document).ready(function(){
$('ul').sortable({
stop: function(event, ui) {
updatePosition();
}
});
$('.remove').on('click', function(e){
$(".delete").remove();
});
});
function updatePosition(){
$('ul li').each(function(i){
$(this).html(i + 1);
});
}
http://jsfiddle.net/72RTz/2/
In your remove event handler, simply include a call to updatePosition
after $(".delete").remove();
This won't cover any-and-all times elements are removed from your list: if that's truly your intent then you'll have to go with something like @pmich35's answer (though it does mean updatePosition
will be called for every $.remove
call, to any element in your list or not, from then on - a bit overkill)
Your updated fiddle.
EDIT: There is currently no "remove" event in $.sortable
that suits your purpose - the remove event that is there only covers the specific case of your user dragging a list item from your list to another sortable list. Sortable
doesn't actually keep track of your list items at all times - it doesn't care if you programmaticly add or remove items - it only facilitates user drag events. It doesn't actually perform any "sorting" as it were, and all appearances of sorting are just the way jQuery pulls DOM elements to form it's objects (if you cache the list items in a jQuery object, then drag-sort the items, the cache'd list items' order will be the same as before). Since the 'sorting' is just an illusion of the function, it "can't" actively track appends/removes.
There is another possible workaround: attach updatePosition
to the ul
element itself:
$( 'ul' ).on( 'remove', 'li', updatePosition );
Which also accomplish your goal, but still isn't the "clean" way you're desiring. The 'remove' event on general elements was added in jQuery UI 1.10.3 (so jsfiddle won't cover it, they only go up to 1.9.2), and will call updatePosition
whenever any current or future list item is removed (from the DOM - dragged removals are still caught by $.sortable
's remove event).
you can override the remove function, althougth it is not very optimized:
(function(){
oldRemove = jQuery.fn.remove;
jQuery.fn.remove=function(){
oldRemove.apply(this, arguments);
updatePosition();
}
})();
$(document).ready(function(){
$('ul').sortable({
stop: function(event, ui) {
updatePosition();
}
});
$('.remove').on('click', function(e){
$(".delete").remove();
});
});
function updatePosition(){
$('ul li').each(function(i){
$(this).html(i + 1);
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With