diff --git a/README.md b/README.md index 5d7c9bf..97c4ec1 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ At a miniumum, you must supply `tree-data` : But there are other attributes to customize the tree: - + initial-selection = "Vegetable" + expand-on-click = "true"> > The example uses Font-Awesome 3, but Font-Awsome 4 also works. Use the following syntax: icon-leaf = "fa fa-file" - + ( in general, use spaces to apply multiple classes to icon elements ) @@ -61,7 +62,7 @@ The data to create the tree is defined in your controller, and could be as simpl There is a long-form for elements, in which each node is an object with a "label", and optionally other stuff like "data", and "children". There is a short-form for listing nodes children (as used for "children" above), where the "children" is just a list of strings. -If you use the short-form for listing elements, then your "on-select" function will have to act based only upon the "branch.label". If you use the +If you use the short-form for listing elements, then your "on-select" function will have to act based only upon the "branch.label". If you use the long-form, where is branch is an object, then you can also attach "data" to a branch. If you would like to add classes to a certain node, give it an array of classes like so: @@ -91,7 +92,7 @@ Or, you can put a custom "on-select" function on an individual branch: onSelect: function(branch){...}, children: ['Jade','Less','Coffeescript'] }] - + Each branch can have a "data" element which you can use to hold whatever data you want. It is not touched by the tree, and it is available to your "on-select" function as "branch.data". In the example, in the "test" folder, this technique is used in "my_tree_handler" to add extra info to "Dog","Cat", and "Hippo". Warning: If you attach extra attributes directly to a branch (instead of to "branch.data"), they could conflict with the internal workings of the tree, which adds branch attributes at runtime, like "expanded" and "selected". diff --git a/dist/abn_tree_directive.js b/dist/abn_tree_directive.js index f309995..071e6c3 100644 --- a/dist/abn_tree_directive.js +++ b/dist/abn_tree_directive.js @@ -8,7 +8,7 @@ '$timeout', function($timeout) { return { restrict: 'E', - template: "", + template: "", replace: true, scope: { treeData: '=', @@ -32,6 +32,9 @@ if (attrs.iconLeaf == null) { attrs.iconLeaf = 'icon-file glyphicon glyphicon-file fa fa-file'; } + if (attrs.expandOnClick == null) { + attrs.expandOnClick = 'false'; + } if (attrs.expandLevel == null) { attrs.expandLevel = '3'; } @@ -103,10 +106,30 @@ } }; scope.user_clicks_branch = function(branch) { + if (attrs.expandOnClick) { + if (branch.close_from_icon) { + branch.close_from_icon = false; + return select_branch(branch); + } + if (!branch.expanded) { + branch.expanded = true; + } else if (branch.selected && !branch.open_from_icon) { + branch.expanded = false; + branch.open_from_icon = false; + } + } if (branch !== selected_branch) { return select_branch(branch); } }; + scope.user_clicks_icon = function(branch) { + if (branch.expanded) { + branch.close_from_icon = true; + } else { + branch.open_from_icon = true; + } + return branch.expanded = !branch.expanded; + }; get_parent = function(child) { var parent; parent = void 0; @@ -135,25 +158,6 @@ scope.tree_rows = []; on_treeData_change = function() { var add_branch_to_list, root_branch, _i, _len, _ref, _results; - for_each_branch(function(b, level) { - if (!b.uid) { - return b.uid = "" + Math.random(); - } - }); - console.log('UIDs are set.'); - for_each_branch(function(b) { - var child, _i, _len, _ref, _results; - if (angular.isArray(b.children)) { - _ref = b.children; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - _results.push(child.parent_uid = b.uid); - } - return _results; - } - }); - scope.tree_rows = []; for_each_branch(function(branch) { var child, f; if (branch.children) { @@ -183,6 +187,27 @@ return branch.children = []; } }); + for_each_branch(function(b, level) { + if (!b.uid) { + b.close_from_icon = false; + b.open_from_icon = false; + return b.uid = "" + Math.random(); + } + }); + console.log('UIDs are set.'); + for_each_branch(function(b) { + var child, _i, _len, _ref, _results; + if (angular.isArray(b.children)) { + _ref = b.children; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + _results.push(child.parent_uid = b.uid); + } + return _results; + } + }); + scope.tree_rows = []; add_branch_to_list = function(level, branch, visible) { var child, child_visible, tree_icon, _i, _len, _ref, _results; if (branch.expanded == null) { diff --git a/src/abn_tree_directive.coffee b/src/abn_tree_directive.coffee index ae4f83b..87b8899 100644 --- a/src/abn_tree_directive.coffee +++ b/src/abn_tree_directive.coffee @@ -1,8 +1,8 @@ module = angular.module 'angularBootstrapNavTree',[] -module.directive 'abnTree',['$timeout',($timeout)-> +module.directive 'abnTree',['$timeout',($timeout)-> restrict:'E' - + #templateUrl: '../dist/abn_tree_template.html' # <--- another way to do this template: """{html}""" # will be replaced by Grunt, during build, with the actual Template HTML @@ -23,9 +23,10 @@ module.directive 'abnTree',['$timeout',($timeout)-> # default values ( Font-Awesome 3 or 4 or Glyphicons ) - attrs.iconExpand ?= 'icon-plus glyphicon glyphicon-plus fa fa-plus' + attrs.iconExpand ?= 'icon-plus glyphicon glyphicon-plus fa fa-plus' attrs.iconCollapse ?= 'icon-minus glyphicon glyphicon-minus fa fa-minus' attrs.iconLeaf ?= 'icon-file glyphicon glyphicon-file fa fa-file' + attrs.expandOnClick ?= 'false' attrs.expandLevel ?= '3' @@ -46,8 +47,8 @@ module.directive 'abnTree',['$timeout',($timeout)-> # # internal utilities... - # - for_each_branch = (f)-> + # + for_each_branch = (f)-> do_f = (branch,level)-> f(branch,level) if branch.children? @@ -59,10 +60,10 @@ module.directive 'abnTree',['$timeout',($timeout)-> - + # # only one branch can be selected at a time - # + # selected_branch = null select_branch = (branch)-> @@ -102,9 +103,24 @@ module.directive 'abnTree',['$timeout',($timeout)-> scope.user_clicks_branch = (branch)-> + if attrs.expandOnClick + if branch.close_from_icon + branch.close_from_icon = false + return select_branch(branch) + if not branch.expanded + branch.expanded = true; + else if branch.selected and not branch.open_from_icon + branch.expanded = false + branch.open_from_icon = false; if branch isnt selected_branch select_branch(branch) + scope.user_clicks_icon = (branch)-> + if branch.expanded + branch.close_from_icon = true + else + branch.open_from_icon = true + branch.expanded = !branch.expanded get_parent = (child)-> parent = undefined @@ -134,20 +150,20 @@ module.directive 'abnTree',['$timeout',($timeout)-> # # We do this whenever data in the tree changes. # The tree itself is bound to this list. - # - # Children of un-expanded parents are included, - # but are set to "visible:false" + # + # Children of un-expanded parents are included, + # but are set to "visible:false" # ( and then they filtered out during rendering ) # scope.tree_rows = [] on_treeData_change = -> #console.log 'tree-data-change!' - + # # if "children" is just a list of strings... # ...change them into objects: - # + # for_each_branch (branch)-> if branch.children if branch.children.length > 0 @@ -167,6 +183,8 @@ module.directive 'abnTree',['$timeout',($timeout)-> # give each Branch a UID ( to keep AngularJS happy ) for_each_branch (b,level)-> if not b.uid + b.close_from_icon = false + b.open_from_icon = false b.uid = ""+Math.random() console.log 'UIDs are set.' @@ -180,7 +198,7 @@ module.directive 'abnTree',['$timeout',($timeout)-> scope.tree_rows = [] - + # # add_branch_to_list: recursively add one branch # and all of it's children to the list @@ -205,7 +223,7 @@ module.directive 'abnTree',['$timeout',($timeout)-> if branch.expanded tree_icon = attrs.iconCollapse else - tree_icon = attrs.iconExpand + tree_icon = attrs.iconExpand # @@ -228,7 +246,7 @@ module.directive 'abnTree',['$timeout',($timeout)-> # all branches are added to the list, # but some are not visible # ( if parent is collapsed ) - # + # child_visible = visible and branch.expanded add_branch_to_list level+1, child, child_visible @@ -236,7 +254,7 @@ module.directive 'abnTree',['$timeout',($timeout)-> # start with root branches, # and recursively add all children to the list # - for root_branch in scope.treeData + for root_branch in scope.treeData add_branch_to_list 1, root_branch, true @@ -272,7 +290,7 @@ module.directive 'abnTree',['$timeout',($timeout)-> # TREE-CONTROL : the API to the Tree # # if we have been given an Object for this, - # then we attach all of tree-control functions + # then we attach all of tree-control functions # to that given object: # if scope.treeControl? @@ -429,7 +447,7 @@ module.directive 'abnTree',['$timeout',($timeout)-> return next - tree.select_next_branch = (b)-> + tree.select_next_branch = (b)-> b ?= selected_branch if b? next = tree.get_next_branch(b) @@ -467,13 +485,3 @@ module.directive 'abnTree',['$timeout',($timeout)-> tree.select_branch(prev) return prev ] - - - - - - - - - - diff --git a/src/abn_tree_directive.js b/src/abn_tree_directive.js index 9e8334c..3c6ca80 100644 --- a/src/abn_tree_directive.js +++ b/src/abn_tree_directive.js @@ -31,6 +31,9 @@ module.directive('abnTree', [ if (attrs.iconLeaf == null) { attrs.iconLeaf = 'icon-file glyphicon glyphicon-file fa fa-file'; } + if (attrs.expandOnClick == null) { + attrs.expandOnClick = 'false'; + } if (attrs.expandLevel == null) { attrs.expandLevel = '3'; } @@ -102,10 +105,30 @@ module.directive('abnTree', [ } }; scope.user_clicks_branch = function(branch) { - if (branch !== selected_branch) { - return select_branch(branch); - } + if (attrs.expandOnClick) { + if (branch.close_from_icon) { + branch.close_from_icon = false; + return select_branch(branch); + } + if (!branch.expanded) { + branch.expanded = true; + } else if (branch.selected && !branch.open_from_icon) { + branch.expanded = false; + branch.open_from_icon = false; + } + } + if (branch !== selected_branch) { + return select_branch(branch); + } }; + scope.user_clicks_icon = function(branch) { + if (branch.expanded) { + branch.close_from_icon = true; + } else { + branch.open_from_icon = true; + } + return branch.expanded = !branch.expanded; + }; get_parent = function(child) { var parent; parent = void 0; @@ -135,10 +158,12 @@ module.directive('abnTree', [ on_treeData_change = function() { var add_branch_to_list, root_branch, _i, _len, _ref, _results; for_each_branch(function(b, level) { - if (!b.uid) { - return b.uid = "" + Math.random(); - } - }); + if (!b.uid) { + b.close_from_icon = false; + b.open_from_icon = false; + return b.uid = "" + Math.random(); + } + }); console.log('UIDs are set.'); for_each_branch(function(b) { var child, _i, _len, _ref, _results; diff --git a/src/abn_tree_template.jade b/src/abn_tree_template.jade index bec2c02..4f3347f 100644 --- a/src/abn_tree_template.jade +++ b/src/abn_tree_template.jade @@ -11,7 +11,7 @@ ul.nav.nav-list.nav-pills.nav-stacked.abn-tree i.indented.tree-icon( ng-class="row.tree_icon" - ng-click="row.branch.expanded = !row.branch.expanded" + ng-click="user_clicks_icon(row.branch)" ) span.indented.tree-label {{ row.label }}