JS Tree and Knockout

Example of JS Tree and Knockout

by db_dev

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.0.9/jstree.min.js"></script>
<link rel="stylesheet" href="http://static.jstree.com/3.0.9/assets/dist/themes/default/style.min.css">
<link rel="stylesheet" href="http://static.jstree.com/3.0.9/assets/bootstrap/css/bootstrap.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<div class="wrapper">
    <div class="button-wrapper">
        <button type="button" class="btn btn-success btn-sm" data-bind="click: createFolderNode">Create Folder</button>
        <button type="button" class="btn btn-success btn-sm" data-bind="click: createFileNode">Create File</button>
        <button type="button" class="btn btn-warning btn-sm" data-bind="click: renameNode">Rename</button>
        <button type="button" class="btn btn-danger btn-sm" data-bind="click: deleteNode">Delete</button>
        <button type="button" class="btn btn-danger btn-sm" data-bind="click: clearConsoleLog">Clear Log</button>
        <button type="button" class="btn btn-danger btn-sm" data-bind="click: deselectAllNodes">Deselect All</button>

        <div id="jstree_demo_div" data-bind="jstree: { data: treeData }"></div>
        <div>--js tree log below--</div>
        <div id="console-log"></div>
        <!-- <div id="jstree_demo_dev_attributes">
        <ul>
          <li>Attribute Reporting Group
            <ul>
              <li>Invoice Dates</li>
            </ul>
          </li>
        </ul>
    </div> --></div>

SCSS

.wrapper {
    padding: 15px;
    
    .button-wrapper {
        margin-bottom: 10px;   
    }
}
.console-line
{
    font-family: monospace;
    margin: 2px;

JavaScript

function tree() {
    var self = this;

    //display actions in fiddle
    self.consoleLine = "<p class=\"console-line\"></p>";
    self.consoleLog = function(text) {
        $("#console-log").append($(self.consoleLine).html(text));
    };
    self.clearConsoleLog = function() {
        $("#console-log").html('');
    };


    self.tree = $('#jstree_demo_div'); //get jstree div
    self.isNodeSelected = ko.observable(false);
    self.selectedNode = ko.observable({});

    //deselect all nodes
    self.deselectAllNodes = function() {
        self.tree.jstree('deselect_all');
    }

    //keep track of selected node
    self.tree.on("changed.jstree", function(e, data) {
        var node = self.tree.jstree().get_selected(true)[0]; //get current selected node
        if (typeof node !== 'undefined') {
            self.isNodeSelected(true);
            self.selectedNode(node);
            self.consoleLog('selected node id: ' + node.id + ', type: ' + node.type);
        } else {
            self.isNodeSelected(false);
        }
    });

    self.createFolderNode = function(data) {
        //node can be created on a preselected node or pass # to create a root node
        var node;
        var data;
        if (self.isNodeSelected()) {
            node = self.selectedNode();
            data = {
                'id': Math.floor((Math.random() * 10000) + 1),
                'text': 'iPhone',
                'type': 'folder'
            };
        } else {
            node = '#';
            data = {
                'id': Math.floor((Math.random() * 100000) + 1),
                'parent': '#',
                'text': 'New Root Node',
                'type': 'root'
            };
        }
        //create node
        var id = self.tree.jstree("create_node", node, data, 'last');
        self.tree.jstree('open_node', node);
        self.tree.jstree('edit', id);

    };

    self.createFileNode = function(data) {
        //Below code only allows files to be created within...