Skip to content

Commit 0945ae8

Browse files
Ben RubinBen Rubin
authored andcommitted
add auto open for filtering
1 parent e0a4911 commit 0945ae8

File tree

4 files changed

+135
-70
lines changed

4 files changed

+135
-70
lines changed

docsApp/pages/home/home.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
<div layout="row">
22
<div layout="column" flex>
33
<input type="search" style="line-height: 48px; padding-left: 16px; border: none; outline: none;" placeholder="Search..." ng-model="searchTerm" />
4-
<md-tree ng-model="vm.selectedItems" restrict-selection="depth" open-on-filter="searchTerm" flex>
5-
<md-branch branch-repeat="location in vm.locationData | filter: searchTerm | orderBy: location.name" class="md-2-line" select>
4+
<md-tree ng-model="vm.selectedItems" restrict-selection="depth" flex>
5+
<md-branch branch-repeat="location in vm.locationData | filter: $mdBranchFilter(searchTerm) | orderBy: location.name" class="md-2-line" select>
66
<div class="md-branch-text">
77
<h3>{{location.name}}</h3>
88
<p>Location</p>
99
</div>
1010

11-
<md-branch branch-repeat="menu in location.menus | filter: searchTerm | orderBy: menu.name" class="md-2-line" select>
11+
<md-branch branch-repeat="menu in location.menus | filter: $mdBranchFilter(searchTerm) | orderBy: menu.name" class="md-2-line" select>
1212
<div class="md-branch-text">
1313
<h3>{{menu.name}}</h3>
1414
<p>Menu</p>

src/js/branch.js

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ var BRANCH_ARROW_TEMPLATE = angular.element('<div class="md-branch-icon-containe
1414
'</div>');
1515

1616
/*@ngInject*/
17-
function branchDirective($parse, $document, $mdUtil) {
17+
function branchDirective($parse, $document, $mdUtil, $filter, $$mdTree) {
1818
return {
1919
restrict: 'E',
2020
require: ['?^mdBranchTemplates'],
@@ -42,16 +42,33 @@ function branchDirective($parse, $document, $mdUtil) {
4242
var pooledBlocks = [];
4343
var itemsLength = 0;
4444
var isUpdating = false;
45+
var isFilterOpen = false;
4546
if (isOpen) { startWatching(); }
4647

48+
scope.$mdBranchFilter = function (value) {
49+
if (value && value.length > 2) {
50+
isFilterOpen = true;
51+
blocks.forEach(function (block) {
52+
$$mdTree.filterOpen(block);
53+
});
54+
} else if ((!value || value.length < 3) && isFilterOpen) {
55+
isFilterOpen = false;
56+
blocks.forEach(function (block) {
57+
$$mdTree.filterClose(block);
58+
});
59+
}
60+
return $filter('filter')(value);
61+
}
62+
4763

4864
function startWatching() {
49-
killWatching();
65+
if (dataWatcher) { return; }
5066
dataWatcher = scope.$watchCollection(repeatListExpression, updateBranch);
5167
}
5268
function killWatching() {
5369
if (typeof dataWatcher === 'function') {
5470
dataWatcher();
71+
dataWatcher = undefined;
5572
}
5673
}
5774
scope.startWatching = startWatching;
@@ -192,12 +209,26 @@ function branchDirective($parse, $document, $mdUtil) {
192209
function updateState($scope, index) {
193210
var item = items ? items[index] : undefined;
194211
var element = $scope.$element && $scope.$element[0] ? $scope.$element : undefined;
212+
$mdUtil.nextTick(function () {
213+
element.toggleClass('md-open', item.$$isOpen);
214+
if (item.$$isOpen) {
215+
$mdUtil.reconnectScope($scope);
216+
$scope.startWatching();
217+
}
218+
});
219+
}
195220

196-
element.toggleClass('md-open', item.$$isOpen);
197-
if (item.$$isOpen) {
198-
$mdUtil.reconnectScope($scope);
199-
$scope.startWatching();
221+
function getTreeCtrl(scope) {
222+
if (scope.treeCtrl) { return scope.treeCtrl; }
223+
var parent = scope.$element[0].parentNode;
224+
while (parent && parent !== document.body) {
225+
if (parent.nodeName === 'MD-TREE') {
226+
scope.treeCtrl = angular.element(parent).controller('mdTree');
227+
return scope.treeCtrl;
228+
}
229+
parent = parent.parentNode;
200230
}
231+
console.error('`<md-branch>` element is not nested in a `<md-tree>` element. Selection will not work');
201232
}
202233

203234
function initState(item) {

src/js/service.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
angular
2+
.module('angular-material-tree')
3+
.factory('$$mdTree', treeService);
4+
5+
6+
function treeService($mdUtil, $animateCss) {
7+
return {
8+
open: open,
9+
close: close,
10+
11+
filterOpen: filterOpen,
12+
filterClose: filterClose
13+
};
14+
15+
function open(branchElement, noAnimation) {
16+
if (!branchElement) { return; }
17+
18+
var element = angular.element(branchElement);
19+
var scope = element.scope();
20+
$mdUtil.reconnectScope(scope);
21+
scope.isOpen = true;
22+
scope.startWatching();
23+
if (noAnimation === true) { element.addClass('md-no-animation'); }
24+
25+
$mdUtil.nextTick(function () {
26+
var container = angular.element(element[0].querySelector('.md-branch-container'));
27+
element.addClass('md-open');
28+
container.addClass('md-overflow md-show');
29+
30+
$animateCss(container, {
31+
from: {'max-height': '0px', opacity: 0},
32+
to: {'max-height': getHeight(element), opacity: 1}
33+
})
34+
.start()
35+
.then(function () {
36+
container.css('max-height', 'none');
37+
container.removeClass('md-overflow md-show');
38+
element.removeClass('md-no-animation');
39+
});
40+
});
41+
}
42+
43+
function close(branchElement, noAnimation) {
44+
if (!branchElement) { return; }
45+
46+
var element = angular.element(branchElement);
47+
var scope = element.scope();
48+
scope.isOpen = false;
49+
scope.killWatching();
50+
if (noAnimation === true) { element.addClass('md-no-animation'); }
51+
52+
$mdUtil.nextTick(function () {
53+
var container = angular.element(element[0].querySelector('.md-branch-container'));
54+
element.removeClass('md-open');
55+
container.addClass('md-overflow md-hide');
56+
$animateCss(container, {
57+
from: {'max-height': getHeight(element), opacity: 1},
58+
to: {'max-height': '0px', opacity: 0}
59+
})
60+
.start()
61+
.then(function () {
62+
container.removeClass('md-overflow md-hide');
63+
element.removeClass('md-no-animation');
64+
$mdUtil.disconnectScope(scope);
65+
});
66+
});
67+
}
68+
69+
function getHeight(element) {
70+
return element[0].scrollHeight + 'px';
71+
}
72+
73+
74+
function filterOpen(block) {
75+
$mdUtil.reconnectScope(block.scope);
76+
block.scope.isOpen = true;
77+
block.scope.startWatching();
78+
block.element.addClass('md-open');
79+
var container = angular.element(block.element[0].querySelector('.md-branch-container'));
80+
container.css('max-height', 'none');
81+
}
82+
83+
function filterClose(block) {
84+
$mdUtil.disconnectScope(block.scope);
85+
block.scope.isOpen = false;
86+
block.scope.killWatching();
87+
block.element.removeClass('md-open');
88+
var container = angular.element(block.element[0].querySelector('.md-branch-container'));
89+
container.css('max-height', '');
90+
}
91+
}

src/js/tree.js

Lines changed: 4 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ angular
44

55

66
var branchNextId = 0;
7-
function treeDirective($mdTheming, $mdUtil, $parse) {
7+
function treeDirective($mdTheming, $mdUtil) {
88
return {
99
restrict: 'E',
1010
require: ['mdTree', '?ngModel'],
@@ -30,14 +30,10 @@ function treeDirective($mdTheming, $mdUtil, $parse) {
3030
}
3131

3232
/*@ngInject*/
33-
function controller($scope, $attrs, $element, $mdUtil, $animateCss) {
33+
function controller($scope, $attrs, $element, $mdUtil, $$mdTree) {
3434
/*jshint validthis:true*/
3535
var vm = this;
3636
var selectionRestictions;
37-
var openOnFilter = $attrs.openOnFilter ? $parse($attrs.openOnFilter) : undefined;
38-
$scope.$watch(function () { return openOnFilter($scope); }, function (value) {
39-
// TODO handle is filter
40-
});
4137

4238
vm.selected = {};
4339
vm.opened = {};
@@ -115,67 +111,14 @@ function treeDirective($mdTheming, $mdUtil, $parse) {
115111
if (isOpen) {
116112
vm.opened[hashKey] = hashValue;
117113
hashValue.$$isOpen = true;
118-
open(branchElement);
114+
$$mdTree.open(branchElement);
119115
} else {
120116
delete vm.opened[hashKey];
121117
hashValue.$$isOpen = false;
122-
close(branchElement);
118+
$$mdTree.close(branchElement);
123119
}
124120
}
125121

126-
function open(branchElement) {
127-
if (!branchElement) { return; }
128-
129-
var element = angular.element(branchElement);
130-
var scope = element.scope();
131-
$mdUtil.reconnectScope(scope);
132-
scope.isOpen = true;
133-
scope.startWatching();
134-
135-
$mdUtil.nextTick(function () {
136-
var container = angular.element(element[0].querySelector('.md-branch-container'));
137-
element.addClass('md-open');
138-
container.addClass('md-overflow md-show');
139-
140-
$animateCss(container, {
141-
from: {'max-height': '0px', opacity: 0},
142-
to: {'max-height': getHeight(element), opacity: 1}
143-
})
144-
.start()
145-
.then(function () {
146-
container.css('max-height', 'none');
147-
container.removeClass('md-overflow md-show');
148-
});
149-
});
150-
}
151-
152-
function close(branchElement) {
153-
if (!branchElement) { return; }
154-
155-
var element = angular.element(branchElement);
156-
var scope = element.scope();
157-
scope.isOpen = false;
158-
scope.killWatching();
159-
160-
$mdUtil.nextTick(function () {
161-
var container = angular.element(element[0].querySelector('.md-branch-container'));
162-
element.removeClass('md-open');
163-
container.addClass('md-overflow md-hide');
164-
$animateCss(container, {
165-
from: {'max-height': getHeight(element), opacity: 1},
166-
to: {'max-height': '0px', opacity: 0}
167-
})
168-
.start()
169-
.then(function () {
170-
container.removeClass('md-overflow md-hide');
171-
$mdUtil.disconnectScope(scope);
172-
});
173-
});
174-
}
175-
176-
function getHeight(element) {
177-
return element[0].scrollHeight + 'px';
178-
}
179122

180123
// handle selection restrictions set by `[restrict-selection]` attr
181124
// TODO how do i invoke this if there is no controller to call

0 commit comments

Comments
 (0)