Ember - Tree View
POC WIP V1
by Nirvanachain
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.0-rc.3/handlebars.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/ember.js/1.0.0-rc.1/ember.js"></script>
<script type="text/x-handlebars" data-template-name="application">
<h1>Tree view with Emberjs</h1>
<p><a href="https://github.com/bobey/ember-treeview" target="_blank">Github project</a></p>
{{view Ember.Tree.TreeContainer controllerBinding="treeController"}}
</script>
<script type="text/x-handlebars" data-template-name="tree-node">
{{view view.treeNodeHeader}} <span class="node-content"><span {{bindAttr class=":icon view.node.isLeaf view.node.isBranch"}}></span>{{view.nodeContent}}</span>
</script>
CSS
body {
font: 14px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #777;
font-weight: 300;
}
.sortable-placeholder {
border: 1px solid #A3BAE9;
background-color: #DFE8F6;
}
.tree-container {
margin: 20px;
float: left;
padding: 20px;
padding-left: 40px;
padding-right: 40px;
border: 1px dotted #ccc;
}
.tree-node {
display: block;
/*height: 20px;*/
}
.tree-node.drag-over {
background-color: #A3BAE9;
}
.tree-node.drag-over.drag-forbidden {
background-color: #F2DEDE;
}
.tree-node.is-active {
background-color: #f3f3f3;
}
.tree-node.is-selected {
background-color: #227ECB;
color: white;
}
.tree-node-sorting {
border: 1px solid;
height: 12px;
width: 50px;
display: block;
}
.tree-node-header {
display: inline-block;
height: 16px;
width: 16px;
}
.is-branch.is-closed .tree-node-header {
background-image: url(http://cdn2.iconfinder.com/data/icons/picol-vector/32/arrow_sans_right-16.png);
}
.is-branch.is-opened .tree-node-header {
background-image: url(http://cdn2.iconfinder.com/data/icons/picol-vector/32/arrow_sans_down-16.png);
}
.drop-after-node {
height: 3px;
/*background-color: black;*/
}
.drop-after-node.drag-over {
background-color: #A3BAE9;
}
.drop-after-node.drag-over.drag-forbidden {
background-color: #F2DEDE;
}
/* Custom styles */
.icon {
width: 16px;
height: 16px;
margin-right: 5px;
display: inline-block;
}
.icon.is-leaf {
width: 12px;
height: 12px;
background-image: url(https://raw.github.com/bobey/ember-treeview/master/img/table.png)
}
.icon.is-branch {
background-image: url(https://raw.github.com/bobey/ember-treeview/master/img/folder_closed.png)
}
.is-opened .icon.is-branch {
background-image: url(https://raw.github.com/bobey/ember-treeview/master/img/folder.png)
}
.dragging-node-tooltip {
border: 1px dotted #ccc;
background-repeat: no-repeat;
...
JavaScript
(function() {
// Ember Tree
Ember.Tree = Ember.Namespace.create();
// Ember Tree Node
Ember.Tree.Node = Ember.ObjectProxy.extend({
label: null,
isActive: false,
isSelected: false,
isOpened: false,
parent: null,
children: [],
isVisible: function() {
return this._hierarchyIsVisible(this);
}.property('isRoot', 'parent', 'parent.isVisible', 'parent.isOpened'),
isVisibleUnderRoot: function() {
return this._hierarchyIsVisible(this, true);
}.property('parent.isRoot', 'parent', 'parent.isVisible', 'parent.isOpened'),
_hierarchyIsVisible: function(node, underRoot) {
if (!underRoot && node.get('isRoot') || underRoot && node.get('parent.isRoot')) {
return true;
}
return node.get('parent.isOpened') && this._hierarchyIsVisible(node.get('parent'), underRoot);
},
level: function() {
return this._computeLevel(this.get('parent'), 0);
}.property().volatile(),
isRoot: function() {
return this.get('parent') === null;
}.property('parent'),
isBranch: function() {
return this.get('children').length > 0;
}.property('children', 'children.@each'),
isLeaf: function() {
return !this.get('children').length;
}.property('children', 'children.@each'),
_computeLevel: function(node, level) {
if (null !== node) {
return this._computeLevel(node.get('parent'), level+1);
}
return level;
}
});
// Mixins
/**
* Ember.StyleBindingsMixin
* CREDITS for this one to Addepar EmberTable
*/
Ember.StyleBindingsMixin = Ember.Mixin.create({
concatenatedProperties: ['styleBindings'],
attributeBindings: ['style'],
unitType: 'px',
createStyleString: function(styleName, property) {
...