Stephen Belanger
Stephen Belanger

Reputation: 6361

jquery ui sortable('refresh') not working!

I have a sortable list I'm working with that can have elements added and removed by another script through jquery and am having an odd problem. These newly generated items appear to be draggable, but they don't actually sort unless I have them already there at page load. I've tried using sortable('refresh'), but it seems to have no effect.

Upvotes: 7

Views: 9644

Answers (4)

Ramesh
Ramesh

Reputation: 1555

When you uncheck checkbox, you will not drag and drop item otherwise you will need to check checkbox after you can drag and drop checkbox. when will uncheck checkbox at that time we need to refresh position of sortable item.

$(function() {
	    $(document).find("#sortable").sortable({
	    	cancel: ".unsortable"
	    });

	    $(document).find("#sortable").disableSelection();
	    
	    $( "#sortable" ).on( "sortstart", function( event, ui ) {
			$("#response").empty();
			$(document).find( "#sortable").sortable("refresh");

			jQuery(this).sortable("refreshPositions").children();
			$("#sortable").sortable("toArray").map(function(item,index){
				
				var text="Position:"+index+"- "+item+"<br/>";
				$("#response").append(text);
				
			})
			
		});

	    $(document).on("change","input[type='checkbox']",function(event) {

			var id=$(this).closest('li').attr('id');

			if($(this).is(":checked"))
			{
				console.log("console log  ",id);
				$(document).find("#"+id).removeClass('unsortable');
				$(document).find( "#sortable" ).trigger( "sortstart");
			}
			else
			{
				var clone = $(document).find('li#'+id).html();
				$(document).find("li#"+id).remove();
				var li=$("<li/>");
				li.attr("class","ui-state-default");
				li.attr("id",id);
				li.append(clone);
				$("#sortable").append(li);
				$(document).find("#"+id).addClass('unsortable');
				$(document).find("input[name='"+id+"']").prop('checked',false);
				$(document).find( "#sortable" ).trigger( "sortstart");
				$(document).find("#sortable").sortable({
			    	cancel: ".unsortable"
			    });
			}			
		});
 	});
.ui-draggable, .ui-droppable {
	background-position: top;
}
li{
cursor: move;
}
.unsortable{
cursor: no-drop;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
 <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
 <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">

<ul id="sortable" class="list-group">
<li class="ui-state-default" id="item-1"><input type="checkbox" name="item-1" checked><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 1</li>
<li class="ui-state-default" id="item-2"><input type="checkbox" name="item-2" checked><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 2</li>
<li class="ui-state-default" id="item-3"><input type="checkbox" name="item-3" checked><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 3</li>
<li class="ui-state-default" id="item-4"><input type="checkbox" name="item-4" checked><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 4</li>
<li class="ui-state-default" id="item-5"><input type="checkbox" name="item-5" checked><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 5</li>
<li class="ui-state-default" id="item-6"><input type="checkbox" name="item-6" checked><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 6</li>
<li class="ui-state-default" id="item-7"><input type="checkbox" name="item-7" checked><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 7</li>
</ul>

Upvotes: 0

MrMesees
MrMesees

Reputation: 1613

I had to call destroy before adding the elements, and then re-initialize (by moving into a function the setup). It seems this is a jQuery issue and could probably be worked around with a try catch in jQuery UI.

This was with

Which are the latest jQuery and jQuery UI available on CodePen. This is high-ish level code.

$('.list-items').sortable("destroy"); // note the destroy before adding
$('.list-all:last-of-type').after( newItemDOM() );
$('.board').width( (300*(numLists()+1))+20 );
$('.board').sortable("refresh");
setupItemSort(jQuery); // where I initialize my item sorting with options.

Note that I have sortable lists, as well as list items. It was only the list-items which proved a problem to call refresh on, generating an error saying sortable had to be added to the items.

I suppose another way of working around, although YMMV would be to pass in a selector to the sortable init and try with just the new DOM before binding. Assuming jQuery UI evaluates the connectWith option any time you initiate dragStart this would be acceptable, but I really just wanted a quick solution, and destroy, then init on all items works.

Upvotes: 0

bounty
bounty

Reputation: 31

I had a similar problem. Once I added a new element to the sortable list nothing was draggable anymore. My solution was to call the destroy method:

$( ".selector" ).sortable( "destroy" ); 

first and then make it sortable again.

Upvotes: 3

PriorityMark
PriorityMark

Reputation: 3247

To give you the opportunity to close this question, and just for reference sake in case anyone else stumbles across this, this seems to work fine in the latest jquery-ui. Here is a jsfiddle: http://jsfiddle.net/fordlover49/mVrGA/

Upvotes: 2

Related Questions