Menu

Maslosoft Balin Logo Maslosoft Balin Documentation
Knockout binding handlers

Edit

Tree Grid

Tree Grid is a complex component, featuring HTMl table as it's base. But it uses one of table columns to display nested structure along with folding controls. The result is a tree like display, but with optional properties. Tree Grid also supports Drag and Drop of nodes to arrange them as You like.

Setting up Tree Grid is no different than configuring table to be fed with foreach binding. Each column can have it's own rendering logic. The difference is that treegrid binding must be used instead of said foreach.

It is recommended to place treegrid binding on tbody tag, so that table headers can be added too. To display nested structer with folding controls, add span with treegridnode binding to choosen column. It does not have to be first one, any will do.

This design approach gives great freedom of arranging Tree Grid. It looks like it require a lot of HTML markup, but it is old plain table with extra data-bind attributes.


Nodes Description Misc Remove Debug
Static value Remove

Relevant code used in examples:

<div>
	<table id="gridView" style="font-size: 18px;" class="table table-condensed">
		<thead>
			<tr>
				<th style="width:.1%;"><input type="checkbox" /></th>
				<th>Nodes</th>
				<th>Description</th>
				<th>Misc</th>
				<th>Remove</th>
				<th>Debug</th>
			</tr>
		</thead>
		<tbody 
		data-bind="
			treegrid: {
				data: balin.model.Tree, 
				childrenField: 'children',
				nodeIcon: '../images/pdf.png',
				folderIcon: '../images/zip.png',
				autoExpand: true,
				dnd: true,
				activeClass: 'active success'
				}">
			<tr>
				<td><input type="checkbox" /></td>
				<td>
					<span data-bind="treegridnode: $data"></span>
					<span data-bind="html: title"></span>
				</td>
				<td data-bind="html: description, tooltip: title"></td>
				<td>Static value</td>
				<td><a href="#" class="remove">Remove</a></td>
				<td class="debug"></td>
			</tr>
		</tbody>
	</table>
</div>
<script type="text/javascript">
	window.onload = (function () {
		var nodeId = 0;
		window.addNode = function (data, e) {
			nodeId++;
			var model = new Maslosoft.Ko.BalinDev.Models.TreeItem;
			model.title = 'New node #' + nodeId;
			model.description = 'Description #' + nodeId;
			balin.model.Tree.children.push(model);
			if (e) {
				e.stopPropagation();
				e.preventDefault();
			}
		};
		window.addSubNode = function (data, e) {
			nodeId++;
			var model = new Maslosoft.Ko.BalinDev.Models.TreeItem;
			model.title = 'New sub-node #' + nodeId;
			model.description = 'Description sub-node #' + nodeId;
			balin.model.Tree.children[0].children.push(model);
			if (e) {
				e.stopPropagation();
				e.preventDefault();
			}
		};
		window.addSubSubNode = function (data, e) {
			nodeId++;
			var model = new Maslosoft.Ko.BalinDev.Models.TreeItem;
			model.title = 'New sub-sub-node #' + nodeId;
			model.description = 'Description sub-sub-node #' + nodeId;
			balin.model.Tree.children[0].children[0].children.push(model);
			if (e) {
				e.stopPropagation();
				e.preventDefault();
			}
		};
		window.addSubSubNodeLast = function (data, e) {
			nodeId++;
			var model = new Maslosoft.Ko.BalinDev.Models.TreeItem;
			model.title = 'New sub-sub-node #' + nodeId;
			model.description = 'Description sub-sub-node #' + nodeId;
			var idx = 0;
			if (balin.model.Tree.children[0].children.length) {
				idx = balin.model.Tree.children[0].children.length - 1;
			}
			balin.model.Tree.children[0].children[idx].children.push(model);
			if (e) {
				e.stopPropagation();
				e.preventDefault();
			}
		};
		window.remSubSubNode = function (data, e) {
			nodeId++;
			var model = new Maslosoft.Ko.BalinDev.Models.TreeItem;
			model.title = 'New sub-sub-node #' + nodeId;
			model.description = 'Description sub-sub-node #' + nodeId;
			balin.model.Tree.children[0].children[0].children = [];
			if (e) {
				e.stopPropagation();
				e.preventDefault();
			}
		};

		var deferAdd = function () {
			window.addNode();
			window.addSubNode();
			window.addSubNode();
			window.addSubSubNodeLast();
			window.addSubSubNodeLast();
			window.addSubSubNodeLast();
			window.addSubNode();
			window.addSubSubNodeLast();
			window.addSubSubNodeLast();
			window.addSubNode();
			window.addSubSubNodeLast();
			window.addSubSubNodeLast();
			window.addSubSubNodeLast();
			window.addSubSubNodeLast();
		};

		setTimeout(deferAdd, 100);
		var grid = jQuery('#gridView');
		var gm = new Maslosoft.Ko.Balin.Widgets.TreeGrid.TreeGridView(grid.find('tbody'));
		grid.on('click', '.remove', function(e){
			e.stopPropagation();
			e.preventDefault();
			var model = ko.dataFor(this);
			console.log(model.title);
			gm.remove(model);
		});

		data = {
			_class: 'Maslosoft.Ko.BalinDev.Models.TreeItem',
			title: "Some container",
			children: [
				{
					_class: 'Maslosoft.Ko.BalinDev.Models.TreeItem',
					title: "Zero",
					description: "This can be also rendered via custom renderer"
				},
				{
					_class: 'Maslosoft.Ko.BalinDev.Models.TreeItem',
					title: "One",
					description: "Another one with description",
					children: [
						{
							_class: 'Maslosoft.Ko.BalinDev.Models.TreeItem',
							title: "Two",
							description: "Hover for node tooltip - also added by node renderer"
						},
						{
							_class: 'Maslosoft.Ko.BalinDev.Models.TreeItem',
							title: "Three",
							children: [
								{
									_class: 'Maslosoft.Ko.BalinDev.Models.TreeItem',
									title: "Three-Two"
								},
								{
									_class: 'Maslosoft.Ko.BalinDev.Models.TreeItem',
									title: "Three-Three"
								}
							]

						},
						{
							_class: 'Maslosoft.Ko.BalinDev.Models.TreeItem',
							title: "Four"
						}
					]
				}
			]
		};
		balin.model.Tree = new Maslosoft.Ko.BalinDev.Models.TreeItem(data);
		balin.model.Tree2 = new Maslosoft.Ko.BalinDev.Models.TreeItem(data);
		ko.applyBindings({model: balin.model}, document.getElementById('ko-balin'));
		});
</script>
  • Projects