Skip to main content Skip to footer

How to edit multiple input nodes in a JavaScript TreeView

The TreeView control is an excellent control to display a hierarchical list of Node objects. It manages data through nodes that can be selected, used to display simple text, images, and other elements such as check boxes. A great feature provided in the Wijmo TreeView control is the ability to edit nodes on the fly. It allows the end users to edit nodes at runtime (for eg. for renaming files and folders).

Now let’s consider a scenario where you have a requirement to display content from two or more fields in your datasource, in the same node, and even edit them separately at runtime. Events like nodeEditStarting and nodeEditEnding will help us achieve our purpose without too much complexity.

Get the JavaScript TreeView sample

Display multiple fields in a TreeView node

For this blog, we're going to use data where a few nodes have two fields instead of one.

{
    header: 'Phones', img: 'resources/phones.png', items: [
        { header: 'Apple', id: "ID00001" },
        { header: 'Motorola', id: "ID00002" },
        { header: 'Nokia', id: "ID00003" },
        { header: 'Samsung', id: "ID00004" }
    ]
}

First, let’s set up the TreeView to display data from two fields in a single node. For this, we can handle the very useful formatItem event of TreeView and add another span to display the second field.

formatItem(treeView: wjcNav.TreeView, e: wjcNav.FormatNodeEventArgs) {
        if (e.dataItem.id != undefined) {
            e.element.innerHTML += " <span class='wj-node-text' contenteditable='false' autocomplete='off' autocorrect='off' style=''>" + e.dataItem.id + "</span>";
        }
}

Once this is done, the TreeView looks like this:

Display data from two fields in a single node in JavaScript TreeView

Editing multiple fields in the same TreeView node

Now the TreeView control provides you with the functionality to edit a node by simply setting the isReadOnly property to false. You can double-click or press F2 on a node to edit it. However, when you do that, you’ll be able to edit only the first field, which is set as the header of the node.

Here's where nodeEditStarting and nodeEditEnding become valuable. With these events, we're going to hide the default labels from the node, add multiple input boxes for editing the field values, and then re-display the default labels with the updated values:

<wj-tree-view #tvEdit
              [itemsSource]="editableItems"
              [displayMemberPath]="'header'"
              [childItemsPath]="'items'"
              [imageMemberPath]="'img'"
              [showCheckboxes]="true"
              [isReadOnly]="false"
              (nodeEditStarting)="nodeEditStarting(tvEdit, $event)"
              (nodeEditEnding)="nodeEditEnding(tvEdit, $event)"
              (selectedItemChanged)="selectedItemChanged(tvEdit, $event)"
              (formatItem)="formatItem(tvEdit, $event)">
</wj-tree-view>
nodeEditStarting(sender: wjcNav.TreeView, e: wjcNav.TreeNodeEventArgs) {
        if (e.node.hasChildren) {
            e.cancel = true;
        }
        else if (e.node.dataItem.id != undefined) {
            e.node.element.children[1].style.display = "none";
            e.node.element.children[2].style.display = "none";

            var input1 = document.createElement("input");
            input1.value = e.node.dataItem.header;
            input1.ondblclick = function () { "return false" };
            e.node.element.appendChild(input1);

            var input2 = document.createElement("input");
            input2.value = e.node.dataItem.id
            input2.ondblclick = function () { "return false" };
            e.node.element.appendChild(input2);

            this.isEditing = true;
        }
    }

nodeEditEnding(sender: wjcNav.TreeView, e: wjcNav.TreeNodeEventArgs) {
        if (e.node.dataItem.id != undefined) {
            if (!this.isEditing) {
                var element = e.node.element;
                var input1 = element.children[3];
                var input2 = element.children[4];
                e.node.dataItem.header = input1.value;
                e.node.dataItem.id = input2.value;

                element.children[1].style.display = "inline";
                element.children[2].style.display = "inline";
                element.children[2].innerHTML = input2.value;
                element.removeChild(input1);
                element.removeChild(input2);
            }
            else
                e.cancel = true;
        }
    }

Here’s the final output when a node is edited:

Edit multiple fields in the same JavaScript TreeView node

You can display as many fields as you’d like in a single node of the TreeView and even edit them on the fly. It’s as simple as that!

Get the JavaScript TreeView sample

Try Wijmo 30-day trial

Abdias Michael

Senior Software Engineer
comments powered by Disqus