This is a follow up to a question: KnockoutJS Sortable group observableArray by field and conditionally sort
There are two further things I am battling to achieve. First when a nested list item is dragged to another list leaving the parent empty I would like to remove the parent. I have done this by creating an afterMove function and checking if the sourceParent length is 0. Then I look through the routes to see if any have an empty tasks array and remove accordingly. I would like to know if this is an efficient solution. I also have to remove the tasks otherwise the tasks subscription adds duplicates when removing scheduled tasks.
Second and most importantly the base object (Task) has an order property. I would like to bind this to the sortable order so that when the tasks are dragged around the Scheduled list the order property is updated. How do I access the order of other list items from the sortable callback?
Please see the following this Fiddle.
Any assistance would be greatly appreciated.
For the first issue, there is a slightly optimized way that you could do it. arg.sourceParent
is contained in the tasksByRoute
item that you want to remove. The remove
function can take a function to run against the items. So, you could write it like:
self.afterMoveCallback = function(arg) {
if (arg.sourceParent().length === 0) {
self.tasksByRoute.remove(function(route) {
return route.tasks === arg.sourceParent;
});
}
};
For the second issue, I really like to use an extension that will automatically track the order in an observableArray. It would look something like:
//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); //add 1 here if you don't want it to be zero based
}
}
});
//initialize the index
this.valueHasMutated();
return this;
};
in your case, you would use it like:
self.scheduledTasks = ko.observableArray([
new Task(8, 4, "Route 4", "Cust 8", 1),
new Task(9, 4, "Route 4", "Cust 9", 2),
new Task(10, 5, "Route 5", "Cust 10")
]).indexed("order");
Here is a sample updated with both of these changes: http://jsfiddle.net/rniemeyer/usVKQ/