Created
January 12, 2014 19:19
-
-
Save bringking/8389136 to your computer and use it in GitHub Desktop.
Knockout TreeView- A nice binding handler that accepts a dynamic tree of data, and displays a searchable and selectable tree-type list.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* { | |
-webkit-touch-callout: none; | |
-webkit-user-select: none; | |
-khtml-user-select: none; | |
-moz-user-select: -moz-none; | |
-ms-user-select: none; | |
user-select: none; | |
font-family: "Segoe UI", "Helvetica", Arial, sans-serif; | |
} | |
.navbar{ | |
margin-bottom:10px; | |
} | |
.ko-treeview-container { | |
max-height: 300px; | |
overflow-y: auto; | |
overflow-x: hidden; | |
border: 1px solid #eee; | |
background-color: white; | |
border-radius: 3px; | |
padding-right: 7px; | |
padding-top: 5px; | |
} | |
.ko-treeview-container .navbar { | |
margin-right: 0px; | |
} | |
.ko-treeview-container > .ko-treeview-list { | |
padding: 0; | |
margin-left:0px; | |
} | |
.ko-treeview-list { | |
list-style: none; | |
} | |
.ko-treeview-listitem { | |
line-height: 2em; | |
margin-top: 0px; | |
} | |
.ko-treeview-label { | |
-webkit-transition: all 250ms; | |
-moz-transition: all 250ms; | |
-ms-transition: all 250ms; | |
-o-transition: all 250ms; | |
cursor: pointer; | |
display: block; | |
margin-left: 5px; | |
width: 100%; | |
background-color: white; | |
color: #2980b9; | |
border-bottom: 1px solid #bdc3c7; | |
} | |
.ko-treeview-label:hover { | |
border-bottom-color: #2980b9; | |
} | |
.ko-treeview-cb { | |
-webkit-transition: all 250ms; | |
-moz-transition: all 250ms; | |
-ms-transition: all 250ms; | |
-o-transition: all 250ms; | |
float: right; | |
clear: both; | |
margin-top: 1em; | |
margin-left: 5px; | |
} | |
.ko-treeview-cb:checked { | |
margin-top: 1.5em; | |
} | |
.ko-treeview-cb:checked + label { | |
line-height: 50px; | |
font-weight: bold; | |
border-bottom-color: #27ae60; | |
font-size: 1.1em; | |
color: #27ae60; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<link href="http://getbootstrap.com/2.3.2/assets/css/bootstrap.css" rel="stylesheet" type="text/css" /> | |
<link href="http://getbootstrap.com/2.3.2/assets/css/bootstrap-responsive.css" rel="stylesheet" type="text/css" /> | |
<link href="treeview.css" rel="stylesheet" type="text/css" /> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script> | |
<script src="treeview.js"></script> | |
<meta charset=utf-8 /> | |
<title>Knockout TreeView</title> | |
</head> | |
<body> | |
<div data-bind="treeView:{title:'Some Title',selected:selectedNodes, data:data}"> | |
</div> | |
<h4>Selected Nodes</h4> | |
<ul data-bind="foreach: selectedNodes"> | |
<li data-bind="text: $data"></li> | |
</ul> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ko.bindingHandlers.treeView = { | |
createNodes: function(rootElement, options){ | |
var rootTmpl = '<script id="ko-treeview-root-tmpl"><div class="navbar"><p class="brand" data-bind="text:$data.title">Title</p><div class="container"><form class="navbar-form pull-right col-sm-4"><div class="input-append"><input class="span4" type="text" placeholder="Search" data-bind="value:$data.search, valueUpdate: \'afterkeydown\'"/><span class="add-on"><i class="icon-search"></i></span></div></form></div></div><ul class="ko-treeview-list" data-bind="template:{foreach:$data.data,name:\'ko-treeview-node-tmpl\'}"></ul></script>'; | |
var nodeTmpl = '<script id="ko-treeview-node-tmpl"><li class="ko-treeview-listitem"><div data-bind="template:{name:\'ko-treeview-item-tmpl\',data:$data}"></div><ul class="ko-treeview-list" data-bind="template:{name:\'ko-treeview-node-tmpl\',foreach:$data[$root.childNode]}"></div></li></script>'; | |
var itemTmpl ='<script id="ko-treeview-item-tmpl"><div data-bind="visible:$data[$root.label].indexOf($root.search()) > -1"><input type="checkbox" class="ko-treeview-cb" data-bind="checked: $root.selected, attr:{value:$data[$root.label], id:$data[$root.label]}" /><label class="ko-treeview-label" data-bind="text:$data[$root.label], attr:{for:$data[$root.label]}"></label></div></script>' | |
//append templates | |
document.body.insertAdjacentHTML('beforeend', rootTmpl); | |
document.body.insertAdjacentHTML('beforeend', nodeTmpl); | |
document.body.insertAdjacentHTML('beforeend', itemTmpl); | |
//apply first binding | |
ko.applyBindingsToNode(rootElement, {template:{name:"ko-treeview-root-tmpl"}},options); | |
}, | |
init: function(element, valueAccessor) { | |
//style element | |
element.className = "ko-treeview-container"; | |
//extend options with search | |
var options = valueAccessor(); | |
options.search = ko.observable(""); | |
//set default data values | |
if(!options.label) options.label = 'id'; | |
if(!options.childNode) options.childNode = 'children'; | |
//create the tree | |
ko.bindingHandlers.treeView.createNodes(element,options); | |
valueAccessor().data.subscribe(function(){ | |
ko.bindingHandlers.treeView.createNodes(element,options); | |
}); | |
//let this handler control its descendants. | |
return { controlsDescendantBindings: true }; | |
} | |
}; | |
function vm(){ | |
this.selectedNodes = ko.observableArray([]); | |
this.data = ko.observableArray([ | |
{ | |
id:"Level 1", | |
children:[ | |
{id:"Level 1-1",children:[ | |
{id:"Level 1-1-1",children:[ | |
{id:"Level 1-1-1-1"} | |
]} | |
]}, | |
{id:"Level 1-2"}, | |
] | |
}, | |
{ | |
id:"Level 2", | |
children:[ | |
{id:"Level 2-1",children:[ | |
{id:"Level 2-1-1"} | |
]}, | |
{id:"Level 2-2"}, | |
] | |
}, | |
]); | |
} | |
var myVM = new vm(); | |
ko.applyBindings(myVM); | |
@bringking Very nice! Is it possible to give the data a more friendly title attribute along with the id?
Very nice one. Still useable on 2020 ;)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Demo