|
30 | 30 | scope: { |
31 | 31 | treeModel: "=", |
32 | 32 | selectedNode: "=?", |
| 33 | + selectedNodes: "=?", |
33 | 34 | expandedNodes: "=?", |
34 | 35 | onSelection: "&", |
35 | 36 | onNodeToggle: "&", |
|
56 | 57 | } |
57 | 58 |
|
58 | 59 | $scope.options = $scope.options || {}; |
| 60 | + ensureDefault($scope.options, "multiSelection", false); |
59 | 61 | ensureDefault($scope.options, "nodeChildren", "children"); |
60 | 62 | ensureDefault($scope.options, "dirSelectable", "true"); |
61 | 63 | ensureDefault($scope.options, "injectClasses", {}); |
|
70 | 72 | ensureDefault($scope.options, "equality", defaultEquality); |
71 | 73 | ensureDefault($scope.options, "isLeaf", defaultIsLeaf); |
72 | 74 |
|
| 75 | + $scope.selectedNodes = $scope.selectedNodes || []; |
73 | 76 | $scope.expandedNodes = $scope.expandedNodes || []; |
74 | 77 | $scope.expandedNodesMap = {}; |
75 | 78 | for (var i=0; i < $scope.expandedNodes.length; i++) { |
|
78 | 81 | $scope.parentScopeOfTree = $scope.$parent; |
79 | 82 |
|
80 | 83 |
|
| 84 | + function isSelectedNode(node) { |
| 85 | + if (!$scope.options.multiSelection && ($scope.options.equality(node, $scope.selectedNode))) |
| 86 | + return true; |
| 87 | + else if ($scope.options.multiSelection && $scope.selectedNodes) { |
| 88 | + for (var i = 0; (i < $scope.selectedNodes.length); i++) { |
| 89 | + if ($scope.options.equality(node, $scope.selectedNodes[i])) { |
| 90 | + return true; |
| 91 | + } |
| 92 | + } |
| 93 | + return false; |
| 94 | + } |
| 95 | + } |
| 96 | + |
81 | 97 | $scope.headClass = function(node) { |
82 | 98 | var liSelectionClass = classIfDefined($scope.options.injectClasses.liSelected, false); |
83 | 99 | var injectSelectionClass = ""; |
84 | | - if (liSelectionClass && ($scope.options.equality(this.node, $scope.selectedNode))) |
| 100 | + if (liSelectionClass && isSelectedNode(node)) |
85 | 101 | injectSelectionClass = " " + liSelectionClass; |
86 | 102 | if ($scope.options.isLeaf(node)) |
87 | 103 | return "tree-leaf" + injectSelectionClass; |
|
128 | 144 | this.selectNodeHead(); |
129 | 145 | } |
130 | 146 | else { |
131 | | - if ($scope.selectedNode != selectedNode) { |
132 | | - $scope.selectedNode = selectedNode; |
133 | | - } |
134 | | - else { |
135 | | - $scope.selectedNode = undefined; |
| 147 | + var selected = false; |
| 148 | + if ($scope.options.multiSelection) { |
| 149 | + var pos = $scope.selectedNodes.indexOf(selectedNode); |
| 150 | + if (pos === -1) { |
| 151 | + $scope.selectedNodes.push(selectedNode); |
| 152 | + selected = true; |
| 153 | + } else { |
| 154 | + $scope.selectedNodes.splice(pos, 1); |
| 155 | + } |
| 156 | + } else { |
| 157 | + if ($scope.selectedNode != selectedNode) { |
| 158 | + $scope.selectedNode = selectedNode; |
| 159 | + selected = true; |
| 160 | + } |
| 161 | + else { |
| 162 | + $scope.selectedNode = undefined; |
| 163 | + } |
136 | 164 | } |
137 | 165 | if ($scope.onSelection) |
138 | | - $scope.onSelection({node: $scope.selectedNode}); |
| 166 | + $scope.onSelection({node: selected? selectedNode : undefined}); |
139 | 167 | } |
140 | 168 | }; |
141 | 169 |
|
142 | 170 | $scope.selectedClass = function() { |
| 171 | + var isThisNodeSelected = isSelectedNode(this.node); |
143 | 172 | var labelSelectionClass = classIfDefined($scope.options.injectClasses.labelSelected, false); |
144 | 173 | var injectSelectionClass = ""; |
145 | | - if (labelSelectionClass && (this.node == $scope.selectedNode)) |
| 174 | + if (labelSelectionClass && isThisNodeSelected) |
146 | 175 | injectSelectionClass = " " + labelSelectionClass; |
147 | 176 |
|
148 | | - return (this.node == $scope.selectedNode)?"tree-selected" + injectSelectionClass:""; |
| 177 | + return isThisNodeSelected?"tree-selected" + injectSelectionClass:""; |
149 | 178 | }; |
150 | 179 |
|
151 | 180 | //tree template |
|
248 | 277 | } |
249 | 278 | }); |
250 | 279 | } |
251 | | - if (scope.options.equality(scope.node, scope.selectedNode)) { |
| 280 | + if (!scope.options.multiSelection && scope.options.equality(scope.node, scope.selectedNode)) { |
252 | 281 | scope.selectedNode = scope.node; |
| 282 | + } else if (scope.options.multiSelection) { |
| 283 | + var newSelectedNodes = []; |
| 284 | + for (var i = 0; (i < scope.selectedNodes.length); i++) { |
| 285 | + if (scope.options.equality(scope.node, scope.selectedNodes[i])) { |
| 286 | + newSelectedNodes.push(scope.node); |
| 287 | + } |
| 288 | + } |
| 289 | + scope.selectedNodes = newSelectedNodes; |
253 | 290 | } |
254 | 291 |
|
255 | 292 | // create a scope for the transclusion, whos parent is the parent of the tree control |
|
0 commit comments