JSFiddle - React, Tailwind, and code Playground
by rniemeyer
HTML
<script src="https://github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.debug.js"></script>
<script src="https://github.com/downloads/rniemeyer/knockout-sortable/knockout-sortable.js"></script>
<div class="grid_6">
<h2>Unscheduled</h2>
<hr/>
<ul id="routes" data-bind="sortable: { data: tasksByRoute, allowDrop: false }">
<li>
<h2 data-bind="text: name"></h2>
<ul class="routeTasks" data-bind="sortable: { data: tasks, allowDrop: false }">
<li><div data-bind="text: customerName"></div></li>
</ul>
</li>
</ul>
</div>
<hr/>
<h2>Scheduled</h2>
<hr/>
<div class="grid_6">
<ul id="scheduledtasks" data-bind="sortable:{data: scheduledTasks, beforeMove: myDropCallback, afterMove: afterMoveCallback}">
<li>
<span data-bind="text: customerName"></span> (<span class="order" data-bind="text: order"></span>)<span class="koLink" data-bind="click: $root.removeScheduledTask">x</span>
</li>
</ul>
</div>
CSS
h2{
font-weight: bold;
font-size: 20px;
}
li{
cursor: move;
}
li ul li{
margin-left: 20px;
}
div ul >li:hover{
background-color: #EFEFFF
}
li ul li:hover{
background-color: #EFFFEF
}
.koLink {
margin-left:20px;
color: blue;
cursor: default;
}
.order{
color: green;
}
JavaScript
//track an index on items in an observableArray
ko.observableArray.fn.indexed = function(prop) {
prop = prop || 'index';
//whenever the array changes, make one loop to update the index on each
this.subscribe(function(newValue) {
if (newValue) {
var item;
for (var i = 0, j = newValue.length; i < j; i++) {
item = newValue[i];
if (!ko.isObservable(item[prop])) {
item[prop] = ko.observable();
}
item[prop](i);
}
}
});
//initialize the index
this.valueHasMutated();
return this;
};
var Task = function(id, routeId, routeName, customerName, order) {
this.id = ko.observable(id);
this.routeId = ko.observable(routeId);
this.routeName = ko.observable(routeName);
this.customerName = ko.observable(customerName);
this.order = ko.observable(order || undefined);
this.isLocked = ko.observable(false);
};
var ViewModel = function() {
var self = this;
self.tasks = ko.observableArray();
self.tasksByRoute = ko.observableArray();
//self.tasksByRoute.id = "hey";
self.tasks.subscribe(function(tasks) {
var routes = [],
routeIndex = {};
ko.utils.arrayForEach(tasks || [], function(task) {
var routeId = task.routeId(),
routeTasks = routeIndex[routeId];
//first time that we have seen this routeID
if (!routeTasks) {
//add it to the index, so we can find it without looping next time
routeIndex[routeId] = routeTasks = {
id: routeId,
name: task.routeName,
tasks: ko.observableArray()
};
//add it to the array that we will eventually return
routes.push(routeTasks);
}
routeTasks.tasks.push(task);
});
//return an array of routes that each contain...