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);