My basic drag and drop

by cuhuak

HTML

<script src="https://raw.github.com/SteveSanderson/knockout/master/build/output/knockout-latest.js"></script>
<div data-bind="text: itemA, drag: itemA"></div>
<div data-bind="text: itemB, drag: itemB"></div>

<ul data-bind="foreach: items, sortableList: items">
    <li data-bind="text: $data, drag: $data"></li>
</ul>
<hr/>

<div data-bind="text: ko.toJSON($root)"></div>

CSS

ul { height: 100px; width: 50px; background-color: #ccc; }

JavaScript

ko.bindingHandlers.drag = {
    init: function(element, valueAccessor, allBindingsAccessor) {
        //combine options passed into binding (in dragOptions binding) with global options (in ko.bindingHandlers.drag.options)
        var options = ko.utils.extend(ko.bindingHandlers.drag.options, allBindingsAccessor().dragOptions);
        
        //initialize draggable
        $(element).data("ko_drag_data", valueAccessor()).draggable(options);
    },
    options: {}   
};

ko.bindingHandlers.drop = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        //grab method
        var action = ko.utils.unwrapObservable(valueAccessor());
        
        //combine options passed into binding (in dropOptions binding) with global options (in ko.bindingHandlers.drop.options)
        var options = ko.utils.extend(ko.bindingHandlers.drop.options, allBindingsAccessor().dropOptions);
        
        options.drop = function(event, ui) {
            //read meta-data off of dropped item 
            var data = $(ui.draggable[0]).data("ko_drag_data");
            //execute our action
            action.call(viewModel, data);
        };
        
        //initialize droppable
        $(element).droppable(options);            
    },
    options: {}    
};


//connect items with observableArrays
ko.bindingHandlers.sortableList = {
    init: function(element, valueAccessor) {
        var list = valueAccessor();
        $(element).sortable({
            update: function(event, ui) {
                //retrieve our actual data item
                var item = $(ui.item).data("ko_drag_data");
                //figure out its new position
                var position = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]);
                //remove the item and add it back in the right spot
                if (position >= 0) {
                    list.remove(item);
                    list.splice(position, 0, item);
                }
               ...