fancytree binding for Knockout
An experimental (incomplete) bindinghandler that integrates fancytree with knockout.
by waxwing
HTML
<script src="http://wwwendt.de/tech/fancytree/src/jquery.fancytree.js"></script>
<link rel="stylesheet" href="http://wwwendt.de/tech/fancytree/src/skin-win8/ui.fancytree.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-debug.js"></script>
<div data-bind="fancytree: tree"></div>
JavaScript
ko.bindingHandlers.fancytree = {
init: function (element, valueAccessor) {
var source = valueAccessor(),
tree;
$(element).fancytree({
source: []
});
tree = $(element).fancytree("getTree");
function processChildren(childArray, targetForNew) {
function nodeAdded(koNode) {
var node = unwrapNode(koNode),
targetNode;
if (!targetForNew) {
targetNode = tree.rootNode;
} else {
targetNode = tree.getNodeByKey(targetForNew);
}
targetNode.addChildren(node);
return node;
}
var sub = childArray.subscribe(function (changes) {
ko.utils.arrayForEach(changes, function (change) {
if (targetForNew && !tree.getNodeByKey(targetForNew)) {
console.log('disposing children ' + targetForNew);
sub.dispose();
return;
}
if (change.status === 'added') {
// TODO: Use index to add at correct position.
nodeAdded(change.value);
}
if (change.status === 'deleted') {
var id = change.value.key;
tree.getNodeByKey(id).remove();
}
});
}, null, 'arrayChange');
var result = [];
ko.utils.arrayForEach(childArray(), function (item) {
result.push(unwrapNode(item));
});
return result;
}
function unwrapNode(koNode) {
var node = {},
initial = true;
if (ko.isObservable(koNode.children)) {
node.children = processChildren(koNode.children, koNode.key);
} else {
...