Skip to content

Commit

Permalink
Add the ability to define a branch class via a function.
Browse files Browse the repository at this point in the history
  • Loading branch information
ashclarke committed Oct 15, 2018
1 parent cd6f6a1 commit aea763b
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 24 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,18 @@ Attributes of angular treecontrol
- `isLeaf` : function (node) -> boolean used to determine if a node is a leaf or branch. The default function checks for existence of children of the node to determine leaf or branch.
- `injectClasses` : allows to inject additional CSS classes into the tree DOM
- `ul` : inject classes into the ul elements
- `li` : inject classes into the li elements
- `li` : inject classes into the li elements. Also allows for an external function that takes a single `node` parameter.

```js
// Example:
function getBranchClass(node) {
// `matchingNodeIds` is local to a parent component controller.
if (matchingNodeIds.includes(node.id)) {
return "tree-branch-match";
}
}
```

- `liSelected` : inject classes into the li elements only when the node is selected
- `iExpanded` : inject classes into the 'i' element for the expanded nodes
- `iCollapsed` : inject classes into the 'i' element for the collapsed nodes
Expand Down
49 changes: 27 additions & 22 deletions angular-tree-control.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex
scope = scope.$parent;
}
return _path;
}
};
}

function ensureDefault(obj, prop, value) {
Expand Down Expand Up @@ -85,7 +85,6 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex
.constant('treeConfig', {
templateUrl: null
})

.directive( 'treecontrol', ['$compile', function( $compile ) {
/**
* @param cssClass - the css class
Expand All @@ -101,6 +100,7 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex
else
return "";
}

return {
restrict: 'EA',
require: "treecontrol",
Expand Down Expand Up @@ -149,16 +149,29 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex
}

$scope.headClass = function(node) {
var liClass = $scope.options.injectClasses.li;

if (typeof liClass === "function") {
liClass = liClass(node);
}

var additionalClasses = " " + classIfDefined(liClass, false);

var liSelectionClass = classIfDefined($scope.options.injectClasses.liSelected, false);
var injectSelectionClass = "";
if (liSelectionClass && isSelectedNode(node))
injectSelectionClass = " " + liSelectionClass;
if ($scope.options.isLeaf(node, $scope))
return "tree-leaf" + injectSelectionClass;
if ($scope.expandedNodesMap[this.$id])
return "tree-expanded" + injectSelectionClass;
else
return "tree-collapsed" + injectSelectionClass;

if (liSelectionClass && isSelectedNode(node)) {
additionalClasses += " " + liSelectionClass;
}

if ($scope.options.isLeaf(node, $scope)) {
return "tree-leaf" + additionalClasses;
}

if ($scope.expandedNodesMap[this.$id]) {
return "tree-expanded" + additionalClasses;
}

return "tree-collapsed" + additionalClasses;
};

$scope.iBranchClass = function() {
Expand Down Expand Up @@ -241,7 +254,7 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex
}
if ($scope.onSelection) {
var parentNode = (transcludedScope.$parent.node === transcludedScope.synteticRoot)?null:transcludedScope.$parent.node;
var path = createPath(transcludedScope)
var path = createPath(transcludedScope);
$scope.onSelection({node: selectedNode, selected: selected, $parentNode: parentNode, $path: path,
$index: transcludedScope.$index, $first: transcludedScope.$first, $middle: transcludedScope.$middle,
$last: transcludedScope.$last, $odd: transcludedScope.$odd, $even: transcludedScope.$even});
Expand Down Expand Up @@ -300,7 +313,6 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex
orderBy: $scope.orderBy ? " | orderBy:orderByFunc():isReverse()" : '',
ulClass: classIfDefined($scope.options.injectClasses.ul, true),
nodeChildren: $scope.options.nodeChildren,
liClass: classIfDefined($scope.options.injectClasses.li, true),
iLeafClass: classIfDefined($scope.options.injectClasses.iLeaf, false),
labelClass: classIfDefined($scope.options.injectClasses.label, false)
};
Expand All @@ -315,7 +327,7 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex
if(!template) {
template =
'<ul {{options.ulClass}} >' +
'<li ng-repeat="node in node.{{options.nodeChildren}} | filter:filterExpression:filterComparator {{options.orderBy}}" ng-class="headClass(node)" {{options.liClass}}' +
'<li ng-repeat="node in node.{{options.nodeChildren}} | filter:filterExpression:filterComparator {{options.orderBy}}" ng-class="headClass(node)"' +
'set-node-to-data>' +
'<i class="tree-branch-head" ng-class="iBranchClass()" ng-click="selectNodeHead(node)"></i>' +
'<i class="tree-leaf-head {{options.iLeafClass}}"></i>' +
Expand All @@ -327,7 +339,6 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex

this.template = $compile($interpolate(template)({options: templateOptions}));
}],

compile: function(element, attrs, childTranscludeFn) {
return function ( scope, element, attrs, treemodelCntr ) {

Expand Down Expand Up @@ -378,10 +389,6 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex
scope.expandedNodesMap = newExpandedNodesMap;
});

// scope.$watch('expandedNodesMap', function(newValue) {
//
// });

//Rendering template for a root node
treemodelCntr.template( scope, function(clone) {
element.html('').append( clone );
Expand All @@ -403,18 +410,16 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex
}
};
}])

.directive('treeRightClick', function($parse) {
return function(scope, element, attrs) {
var fn = $parse(attrs.treeRightClick);
element.bind('contextmenu', function(event) {
scope.$apply(function() {
fn(scope, {$event:event}); // go do our stuff
fn(scope, {$event:event});
});
});
};
})

.directive("treeitem", function() {
return {
restrict: 'E',
Expand Down
34 changes: 33 additions & 1 deletion test/angular-tree-control-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
describe('treeControl', function() {
var $compile, $rootScope, element, num, $templateCache;

var LI_CLASS = "tree-branch-test";

beforeEach(function () {
module('treeControl');
inject(function ($injector) {
Expand All @@ -19,6 +21,12 @@ describe('treeControl', function() {
return currentLevel;
}

function liClassFn(node) {
if (node.label === "node 7") {
return LI_CLASS;
}
}

describe('rendering', function () {
beforeEach(function () {
$rootScope.treedata = createSubTree(2, 2);
Expand Down Expand Up @@ -613,7 +621,7 @@ describe('treeControl', function() {
expect(element.find('li:eq(1)').text()).toBe('b');
expect(element.find('li:eq(2)').text()).toBe('a');
});

it('should be able to accept alternative children variable name', function () {
$rootScope.treedata = createSubTree(2, 2);
$rootScope.treedata.push({kinder: [{}]});
Expand Down Expand Up @@ -710,6 +718,30 @@ describe('treeControl', function() {
expect(element.find('li:eq(1) .tree-branch-head').hasClass('collapsecls')).toBeTruthy();
});

it('should be able to accept a string or function for the li element class names', function () {
// Constant li class

$rootScope.treedata = createSubTree(2, 2);
$rootScope.treeOptions = {injectClasses: { li: LI_CLASS }};
element = $compile('<treecontrol tree-model="treedata" options="treeOptions">{{node.label}}</treecontrol>')($rootScope);
$rootScope.$digest();

expect(element.find('li:eq(0)').hasClass(LI_CLASS)).toBe(true);

expect(element.find('li:eq(1)').hasClass(LI_CLASS)).toBe(true);

// Conditional li class, via a function.

$rootScope.treedata = createSubTree(2, 2);
$rootScope.treeOptions = {injectClasses: { li: liClassFn }};
element = $compile('<treecontrol tree-model="treedata" options="treeOptions">{{node.label}}</treecontrol>')($rootScope);
$rootScope.$digest();

expect(element.find('li:eq(0)').hasClass(LI_CLASS)).toBe(true);

expect(element.find('li:eq(1)').hasClass(LI_CLASS)).toBe(false);
});

it('should filter sibling nodes based on filter expression which is a string', function() {
$rootScope.treedata = [
{ label: "a", children: [] },
Expand Down

0 comments on commit aea763b

Please sign in to comment.