I’m trying to make a list item draggable in a project that is using Knockout.js.
I’m using the code below, and as you can see it is very simple:
<div id="room-view" >
<ul data-bind="foreach: rooms">
<li data-bind="text: name" class="draggable room-shape"></li>
</ul>
</div>
<script type="text/javascript">
$(function() {
$( ".draggable" ).draggable();
});
</script>
The list of ‘room’ renders just fine, but none of the items are draggable. However, if I apply the ‘draggable’ class to any other element on the page – it becomes draggable. Even if they are other list items. The only difference is that these list items are being created through the ‘foreach’ binding.
Can anyone spot what may be causing this to not function correctly?
foreachworks by saving off a copy of the elements to use as the “template” whenever it needs to render an item. So, the elements that you made draggable are not the ones that were rendered byforeach.You could try to make sure that
draggableis called afterapplyBindings, but that would only be effective if yourroomsis not an observableArray that changes. Any new items rendered would not be draggable.Another option is to use the afterRender option to call
draggableon your elements.A better way is to use a custom binding. It could be as simple as:
or you can get into something a little better where you actually update an observableArray based on where your items are dropped.
I wrote an article a while back on it here. With Knockout 2.0, I made a few changes to simplify the binding so that you can just use
sortableListon the parent.Here is a sample with just sortable: http://jsfiddle.net/rniemeyer/DVRVQ/
Here is a sample with dropping between lists: http://jsfiddle.net/rniemeyer/sBHaP/