JSFiddle - React, Tailwind, and code Playground
by daniel_white
HTML
<script src="http://github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.js"></script>
<div>
<ul data-bind="foreach: items, uiSortableList: items">
<li data-bind="text: name"></li>
</ul>
</div>
<textarea data-bind="text: data" />
CSS
ul {
list-style: none;
margin: 0;
padding: 0;
overflow-y: scroll;
overflow-x: hidden;
height: 300px;
width: 400px;
cursor: default;
border: 1px solid #255882;
background: #f6f6f6;
}
ul li{
width: 350px;
padding: 3px 6px;
margin: 3px;
border: 1px #aaa solid;
cursor: ns-resize;
height: 24px;
background-color: #fff;
}
ul li.placeholder {
background-color: #FBF9EE;
border-color: #FCEFA1;
}
JavaScript
ko.bindingHandlers.uiSortableList = {
init: function (element, valueAccessor, allBindingsAccesor, context) {
var $element = $(element),
list = valueAccessor();
$element.sortable({
containment: 'parent',
placeholder: 'placeholder',
update: function (event, ui) {
var actualArray = list(),
item = ko.dataFor(ui.item[0]),
newIndex = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]);
if (newIndex >= list().length) newIndex = list().length - 1;
if (newIndex < 0) newIndex = 0;
ko.utils.arrayRemoveItem(actualArray, item);
actualArray.splice(newIndex, 0, item);
list(actualArray);
}
});
}
};
var ViewModel = function (items) {
this.items = ko.observableArray(items);
this.data = ko.computed(function() {
return ko.toJSON(this.items());
}, this);
};
var vm = new ViewModel([ { name : 'foo' }, { name : 'bar' }, { name : 'baz' }]);
ko.applyBindings(vm);