JSFiddle - React, Tailwind, and code Playground
by bizamajig
HTML
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
<button data-bind="click: addItem">Add item</button>
<p>2 lists of sortable items. 2 lists to show orders updates to the model</p>
<ul class="items" data-bind="foreach: items, jquerysortable: items">
<li data-bind="text: $data"></li>
</ul>
<ul class="items" data-bind="foreach: moreitems, jquerysortable: moreitems">
<li data-bind="text: $data"></li>
</ul>
<ul data-bind="foreach: items">
<li data-bind="text: $data"></li>
</ul>
<ul data-bind="foreach: moreitems">
<li data-bind="text: $data"></li>
</ul>
CSS
ul{
float:left;
width:100px;
display:block;
color:gray;
}
ul.items{ color: black; cursor: move;}
JavaScript
ko.bindingHandlers.jquerysortable = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var currentObservableArray = valueAccessor();
// Add the current observableArray to the elements data dictionary
// we will need this when moving an item from one sortable to another
$(element).data("ko.source.observablearray", currentObservableArray);
// When we recieve an item from another sortable, we have already added it
// to the new array, so we just need to remove it from the old array
$(element).on("sortreceive", function( event, ui ) {
var sourceObservableArray = ui.sender.data("ko.source.observablearray");
var item = ko.dataFor(ui.item[0]);
sourceObservableArray.remove(item);
});
// This event fires after a sort and before a recieve.
// If this is a recieve, the remove item call will not remove anything
// but we will splice the item into the current observableArray
$(element).on("sortupdate", function( event, ui ) {
var item = ko.dataFor(ui.item[0]);
var newIndex = $(element).children().index(ui.item);
// newIndex is -1 when we have moved an item out of a sortable into another
if(newIndex > -1){
currentObservableArray.remove(item);
currentObservableArray.splice(newIndex, 0, item);
ui.item.remove();
}
});
}
};
var SimpleListModel = function(items, moreitems) {
this.items = ko.observableArray(items);
this.moreitems = ko.observableArray(moreitems);
var newItemCount = 1;
this.addItem = function() {
this.items.push("NewItem " + newItemCount++);
}.bind(this);
};
ko.applyBindings(new SimpleListModel(["Alpha", "Beta", "Gamma"], ["Delta", "Echo", "Charlie"]));
$(".items").sortable({connectWith:'.items'})