Skip to content

Commit 31e32c4

Browse files
committed
added support for filtering sub-nodes in the tree
1 parent 8b1d290 commit 31e32c4

File tree

3 files changed

+82
-2
lines changed

3 files changed

+82
-2
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ Attributes of angular treecontrol
127127
- `labelSelected` : inject classes into the div element around the label only when the node is selected
128128
- `order-by` : value for ng-repeat to use for ordering sibling nodes
129129
- `reverse-order` : whether or not to reverse the ordering of sibling nodes based on the value of `order-by`
130+
- `filter-expression` : value for ng-repeat to use for filtering the sibling nodes
131+
- `filter-comparator` : value for ng-repeat to use for comparing nodes with the filter expression
130132

131133
### The tree labels
132134

angular-tree-control.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
onNodeToggle: "&",
3636
options: "=?",
3737
orderBy: "@",
38-
reverseOrder: "@"
38+
reverseOrder: "@",
39+
filterExpression: "=?",
40+
filterComparator: "=?"
3941
},
4042
controller: ['$scope', function( $scope ) {
4143

@@ -149,7 +151,7 @@
149151
//tree template
150152
var template =
151153
'<ul '+classIfDefined($scope.options.injectClasses.ul, true)+'>' +
152-
'<li ng-repeat="node in node.' + $scope.options.nodeChildren + ' | orderBy:orderBy:reverseOrder" ng-class="headClass(node)" '+classIfDefined($scope.options.injectClasses.li, true)+'>' +
154+
'<li ng-repeat="node in node.' + $scope.options.nodeChildren + ' | filter:filterExpression:filterComparator | orderBy:orderBy:reverseOrder" ng-class="headClass(node)" '+classIfDefined($scope.options.injectClasses.li, true)+'>' +
153155
'<i class="tree-branch-head" ng-class="iBranchClass()" ng-click="selectNodeHead(node)"></i>' +
154156
'<i class="tree-leaf-head '+classIfDefined($scope.options.injectClasses.iLeaf, false)+'"></i>' +
155157
'<div class="tree-label '+classIfDefined($scope.options.injectClasses.label, false)+'" ng-class="selectedClass()" ng-click="selectNodeLabel(node)" tree-transclude></div>' +

test/angular-tree-control-test.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,82 @@ describe('treeControl', function() {
354354
expect(element.find('li:eq(0) .tree-branch-head').hasClass('expandcls')).toBeTruthy();
355355
expect(element.find('li:eq(1) .tree-branch-head').hasClass('collapsecls')).toBeTruthy();
356356
});
357+
358+
it('should filter sibling nodes based on filter expression which is a string', function() {
359+
$rootScope.treedata = [
360+
{ label: "a", children: [] },
361+
{ label: "c", children: [] },
362+
{ label: "b", children: [] }
363+
];
364+
$rootScope.predicate = 'b';
365+
element = $compile('<treecontrol tree-model="treedata" filter-expression="predicate">{{node.label}}</treecontrol>')($rootScope);
366+
$rootScope.$digest();
367+
expect(element.find('li:eq(0)').text()).toBe('b');
368+
expect(element.find('li').length).toBe(1);
369+
});
370+
371+
it('should filter sibling nodes based on filter expression which is an object', function() {
372+
$rootScope.treedata = [
373+
{ label: "a", age: 12, children: [] },
374+
{ label: "c", age: 12, children: [] },
375+
{ label: "b", age: 14, children: [] }
376+
];
377+
$rootScope.predicate = {age:12};
378+
element = $compile('<treecontrol tree-model="treedata" filter-expression="predicate">{{node.label}}</treecontrol>')($rootScope);
379+
$rootScope.$digest();
380+
expect(element.find('li:eq(0)').text()).toBe('a');
381+
expect(element.find('li:eq(1)').text()).toBe('c');
382+
expect(element.find('li').length).toBe(2);
383+
});
384+
385+
it('should filter sibling nodes based on filter expression which is a function', function() {
386+
$rootScope.treedata = [
387+
{ label: "a", age: 12, children: [] },
388+
{ label: "c", age: 12, children: [] },
389+
{ label: "b", age: 14, children: [] }
390+
];
391+
$rootScope.predicate = function(node) {
392+
return node.age == 12;
393+
};
394+
element = $compile('<treecontrol tree-model="treedata" filter-expression="predicate">{{node.label}}</treecontrol>')($rootScope);
395+
$rootScope.$digest();
396+
expect(element.find('li:eq(0)').text()).toBe('a');
397+
expect(element.find('li:eq(1)').text()).toBe('c');
398+
expect(element.find('li').length).toBe(2);
399+
});
400+
401+
it('should filter sibling nodes based on filter expression in non prefix match', function() {
402+
$rootScope.treedata = [
403+
{ label: "abcd", age: 12, children: [] },
404+
{ label: "abef", age: 12, children: [] },
405+
{ label: "bcde", age: 14, children: [] }
406+
];
407+
$rootScope.predicate = "ab";
408+
$rootScope.comparator = false;
409+
element = $compile('<treecontrol tree-model="treedata" filter-expression="predicate" filter-comparator="comparator">{{node.label}}</treecontrol>')($rootScope);
410+
$rootScope.$digest();
411+
expect(element.find('li:eq(0)').text()).toBe('abcd');
412+
expect(element.find('li:eq(1)').text()).toBe('abef');
413+
expect(element.find('li').length).toBe(2);
414+
});
415+
416+
it('should filter sibling nodes based on filter expression in non prefix match', function() {
417+
$rootScope.treedata = [
418+
{ label: "abcd", age: 12, children: [] },
419+
{ label: "abef", age: 12, children: [] },
420+
{ label: "bcde", age: 14, children: [] }
421+
];
422+
$rootScope.predicate = "ab";
423+
$rootScope.comparator = true;
424+
element = $compile('<treecontrol tree-model="treedata" filter-expression="predicate" filter-comparator="comparator">{{node.label}}</treecontrol>')($rootScope);
425+
$rootScope.$digest();
426+
expect(element.find('li').length).toBe(0);
427+
428+
$rootScope.predicate = "abcd";
429+
$rootScope.$digest();
430+
expect(element.find('li:eq(0)').text()).toBe('abcd');
431+
expect(element.find('li').length).toBe(1);
432+
});
357433
});
358434

359435
describe('customizations', function () {

0 commit comments

Comments
 (0)