Knockout Drag/Drop - Simple

by teknohippy

HTML

<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.js"></script>
<div id="toppings" data-bind="foreach: sourceMotivators">
    <div class="motivationbox draggable" data-bind="text: name, drag: {value: $data}"></div>
</div>

<h2>Set 1</h2>

<div class="setbox" data-bind="drop: {value: set1dropped}">
    <div id="toppings" data-bind="foreach: set1">
        <div class="motivationbox" data-bind="text: name"></div>
    </div>
</div>

<h2>Set 2</h2>

<div class="setbox" data-bind="drop: {value: set2dropped}">
    <div id="toppings" data-bind="foreach: set2">
        <div class="motivationbox" data-bind="text: name"></div>
    </div>
</div>

CSS

.motivationbox {
    border: 1px solid black;
    padding 4px;
    margin: 4px;
    display: inline-block;    
}
.draggable
{
    cursor: pointer;
}
.setbox {
    border: 2px solid red;
    width: 400px;
    min-height: 200px;
}

JavaScript

(function () {
    var _dragged;
    ko.bindingHandlers.drag = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
            var dragElement = $(element);
            var dragOptions = {
                helper: 'clone',
                revert: true,
                revertDuration: 100,
                start: function () {
                    _dragged = ko.utils.unwrapObservable(valueAccessor().value);
                },
                cursor: 'default'
            };
            dragElement.draggable(dragOptions).disableSelection();
        }
    };

    ko.bindingHandlers.drop = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
            var dropElement = $(element);
            var dropOptions = {
                drop: function (event, ui) {
                    valueAccessor().value(_dragged);
                }
            };
            dropElement.droppable(dropOptions);
        }
    };
})();

function Motivator(name, set) {
    var self = this;
    self.name = ko.observable(name);
    self.set = set;
    self.rating = 2;
}

function UnitViewModel() {
    self.set1 = ko.observableArray();
    self.set2 = ko.observableArray();
    self.sourceMotivators = ko.observableArray([
    new Motivator("Expanding the scope of the job (job enrichment)", 1),
    new Motivator("Participation on cross company projects", 1),
    new Motivator("Involvement in external initiatives", 1),
    new Motivator("Representing the department on professional bodies", 1),
    new Motivator("Opportunities to share the best practices they are recognised for with others", 1),
    new Motivator("Attendance on relevant training programmes", 1),
    new Motivator("Career development", 1),
    new Motivator("Delegating more responsibility", 2),
    new Motivator("Increasing decision making authority", 2),
    new Motivator("Identifying them as the subject expert", 2),
    new Motivator("Involving them in team / departmental...