From b72b7000cb34728d42a1b01d6146b9d41eb39df3 Mon Sep 17 00:00:00 2001 From: Kojotto Date: Tue, 14 Jul 2015 15:48:03 +0200 Subject: [PATCH 1/4] Update angular-tree-control.js Added the function to the controller so that the directive can be more extensible. Now you can create your own directive that has a different template but can still use the original functions. example: .directive("treecontrolfoldering", function () { return { restrict: "A", require: "treecontrol", link: function (scope, element, attributes, ctrl) { ctrl.ensureDefault(ctrl.$scope.options, "nodeFolderType", "FolderType"); ctrl.$scope.folderTypeClass = function (node) { var t = scope.foldering.getDestinationObject(node); if (t.isFolderType) { return t.cssClass; } }; ctrl.defaultIsLeaf = function (node) { return (!node[ctrl.$scope.options.nodeChildren] || node[ctrl.$scope.options.nodeChildren].length === 0) && (!node[ctrl.$scope.options.nodeFolderType] || node[ctrl.$scope.options.nodeFolderType].length === 0); } ctrl.$scope.options.isLeaf = ctrl.defaultIsLeaf; ctrl.orderBy = "| orderBy:'Name'"; ctrl.orderByFolderType = "| orderBy:'toString()'"; var template = ''; ctrl.template = ctrl.$compile(template); } } }); --- angular-tree-control.js | 597 +++++++++++++++++++++------------------- 1 file changed, 310 insertions(+), 287 deletions(-) diff --git a/angular-tree-control.js b/angular-tree-control.js index b138572..496c6bd 100644 --- a/angular-tree-control.js +++ b/angular-tree-control.js @@ -1,331 +1,354 @@ -(function ( angular ) { +(function (angular) { 'use strict'; - - angular.module( 'treeControl', [] ) - .directive( 'treecontrol', ['$compile', function( $compile ) { - /** + + angular.module('treeControl') + .directive('treecontrol', [ + '$compile', function ($compile) { + /** * @param cssClass - the css class * @param addClassProperty - should we wrap the class name with class="" */ - function classIfDefined(cssClass, addClassProperty) { - if (cssClass) { - if (addClassProperty) - return 'class="' + cssClass + '"'; - else - return cssClass; - } - else - return ""; - } - - function ensureDefault(obj, prop, value) { - if (!obj.hasOwnProperty(prop)) - obj[prop] = value; - } - - return { - restrict: 'EA', - require: "treecontrol", - transclude: true, - scope: { - treeModel: "=", - selectedNode: "=?", - selectedNodes: "=?", - expandedNodes: "=?", - onSelection: "&", - onNodeToggle: "&", - options: "=?", - orderBy: "@", - reverseOrder: "@", - filterExpression: "=?", - filterComparator: "=?" - }, - controller: ['$scope', function( $scope ) { - - function defaultIsLeaf(node) { - return !node[$scope.options.nodeChildren] || node[$scope.options.nodeChildren].length === 0; - } - function shallowCopy(src, dst) { - if (angular.isArray(src)) { - dst = dst || []; + return { + restrict: 'EA', + require: "treecontrol", + transclude: true, + scope: { + treeModel: "=", + selectedNode: "=?", + selectedNodes: "=?", + expandedNodes: "=?", + onSelection: "&", + onNodeToggle: "&", + options: "=?", + orderBy: "@", + reverseOrder: "@", + filterExpression: "=?", + filterComparator: "=?" + }, + controller: [ + '$scope', function ($scope) { + + var ctrl = this; + + ctrl.$scope = $scope; + ctrl.$compile = $compile; + - for ( var i = 0; i < src.length; i++) { - dst[i] = src[i]; + ctrl.classIfDefined = function (cssClass, addClassProperty) { + if (cssClass) { + if (addClassProperty) + return 'class="' + cssClass + '"'; + else + return cssClass; + } else + return ""; } - } else if (angular.isObject(src)) { - dst = dst || {}; - for (var key in src) { - if (hasOwnProperty.call(src, key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) { - dst[key] = src[key]; - } + ctrl.ensureDefault = function (obj, prop, value) { + if (!obj.hasOwnProperty(prop)) + obj[prop] = value; } - } - return dst || src; - } - function defaultEquality(a, b) { - if (a === undefined || b === undefined) - return false; - a = shallowCopy(a); - a[$scope.options.nodeChildren] = []; - b = shallowCopy(b); - b[$scope.options.nodeChildren] = []; - return angular.equals(a, b); - } - function defaultIsSelectable() { - return true; - } + ctrl.defaultIsLeaf = function (node) { + return !node[$scope.options.nodeChildren] || node[$scope.options.nodeChildren].length === 0; + } - $scope.options = $scope.options || {}; - ensureDefault($scope.options, "multiSelection", false); - ensureDefault($scope.options, "nodeChildren", "children"); - ensureDefault($scope.options, "dirSelectable", "true"); - ensureDefault($scope.options, "injectClasses", {}); - ensureDefault($scope.options.injectClasses, "ul", ""); - ensureDefault($scope.options.injectClasses, "li", ""); - ensureDefault($scope.options.injectClasses, "liSelected", ""); - ensureDefault($scope.options.injectClasses, "iExpanded", ""); - ensureDefault($scope.options.injectClasses, "iCollapsed", ""); - ensureDefault($scope.options.injectClasses, "iLeaf", ""); - ensureDefault($scope.options.injectClasses, "label", ""); - ensureDefault($scope.options.injectClasses, "labelSelected", ""); - ensureDefault($scope.options, "equality", defaultEquality); - ensureDefault($scope.options, "isLeaf", defaultIsLeaf); - ensureDefault($scope.options, "allowDeselect", true); - ensureDefault($scope.options, "isSelectable", defaultIsSelectable); - - $scope.selectedNodes = $scope.selectedNodes || []; - $scope.expandedNodes = $scope.expandedNodes || []; - $scope.expandedNodesMap = {}; - for (var i=0; i < $scope.expandedNodes.length; i++) { - $scope.expandedNodesMap[""+i] = $scope.expandedNodes[i]; - } - $scope.parentScopeOfTree = $scope.$parent; + ctrl.shallowCopy = function (src, dst) { + if (angular.isArray(src)) { + dst = dst || []; + for (var i = 0; i < src.length; i++) { + dst[i] = src[i]; + } + } else if (angular.isObject(src)) { + dst = dst || {}; - function isSelectedNode(node) { - if (!$scope.options.multiSelection && ($scope.options.equality(node, $scope.selectedNode))) - return true; - else if ($scope.options.multiSelection && $scope.selectedNodes) { - for (var i = 0; (i < $scope.selectedNodes.length); i++) { - if ($scope.options.equality(node, $scope.selectedNodes[i])) { - return true; + for (var key in src) { + if (hasOwnProperty.call(src, key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) { + dst[key] = src[key]; + } + } } + + return dst || src; + } + ctrl.defaultEquality = function (a, b) { + if (a === undefined || b === undefined) + return false; + a = ctrl.shallowCopy(a); + a[$scope.options.nodeChildren] = []; + b = ctrl.shallowCopy(b); + b[$scope.options.nodeChildren] = []; + return angular.equals(a, b); } - return false; - } - } - $scope.headClass = function(node) { - var liSelectionClass = classIfDefined($scope.options.injectClasses.liSelected, false); - var injectSelectionClass = ""; - if (liSelectionClass && isSelectedNode(node)) - injectSelectionClass = " " + liSelectionClass; - if ($scope.options.isLeaf(node)) - return "tree-leaf" + injectSelectionClass; - if ($scope.expandedNodesMap[this.$id]) - return "tree-expanded" + injectSelectionClass; - else - return "tree-collapsed" + injectSelectionClass; - }; - - $scope.iBranchClass = function() { - if ($scope.expandedNodesMap[this.$id]) - return classIfDefined($scope.options.injectClasses.iExpanded); - else - return classIfDefined($scope.options.injectClasses.iCollapsed); - }; - - $scope.nodeExpanded = function() { - return !!$scope.expandedNodesMap[this.$id]; - }; - - $scope.selectNodeHead = function() { - var transcludedScope = this; - var expanding = $scope.expandedNodesMap[transcludedScope.$id] === undefined; - $scope.expandedNodesMap[transcludedScope.$id] = (expanding ? transcludedScope.node : undefined); - if (expanding) { - $scope.expandedNodes.push(transcludedScope.node); - } - else { - var index; - for (var i=0; (i < $scope.expandedNodes.length) && !index; i++) { - if ($scope.options.equality($scope.expandedNodes[i], transcludedScope.node)) { - index = i; - } + ctrl.defaultIsSelectable = function () { + return true; } - if (index != undefined) - $scope.expandedNodes.splice(index, 1); - } - if ($scope.onNodeToggle) { - var parentNode = (transcludedScope.$parent.node === transcludedScope.synteticRoot)?null:transcludedScope.$parent.node; - $scope.onNodeToggle({node: transcludedScope.node, $parentNode: parentNode, - $index: transcludedScope.$index, $first: transcludedScope.$first, $middle: transcludedScope.$middle, - $last: transcludedScope.$last, $odd: transcludedScope.$odd, $even: transcludedScope.$even, expanded: expanding}); - } - }; + $scope.options = $scope.options || {}; + ctrl.ensureDefault($scope.options, "multiSelection", false); + ctrl.ensureDefault($scope.options, "nodeChildren", "children"); + ctrl.ensureDefault($scope.options, "dirSelectable", "true"); + ctrl.ensureDefault($scope.options, "injectClasses", {}); + ctrl.ensureDefault($scope.options.injectClasses, "ul", ""); + ctrl.ensureDefault($scope.options.injectClasses, "li", ""); + ctrl.ensureDefault($scope.options.injectClasses, "liSelected", ""); + ctrl.ensureDefault($scope.options.injectClasses, "iExpanded", ""); + ctrl.ensureDefault($scope.options.injectClasses, "iCollapsed", ""); + ctrl.ensureDefault($scope.options.injectClasses, "iLeaf", ""); + ctrl.ensureDefault($scope.options.injectClasses, "label", ""); + ctrl.ensureDefault($scope.options.injectClasses, "labelSelected", ""); + ctrl.ensureDefault($scope.options, "equality", ctrl.defaultEquality); + ctrl.ensureDefault($scope.options, "isLeaf", ctrl.defaultIsLeaf); + ctrl.ensureDefault($scope.options, "allowDeselect", true); + ctrl.ensureDefault($scope.options, "isSelectable", ctrl.defaultIsSelectable); - $scope.selectNodeLabel = function( selectedNode){ - var transcludedScope = this; - if(!$scope.options.isLeaf(selectedNode) && (!$scope.options.dirSelectable || !$scope.options.isSelectable(selectedNode))) { - // Branch node is not selectable, expand - this.selectNodeHead(); - } - else if($scope.options.isLeaf(selectedNode) && (!$scope.options.isSelectable(selectedNode))) { - // Leaf node is not selectable - return; - } - else { - var selected = false; - if ($scope.options.multiSelection) { - var pos = -1; - for (var i=0; i < $scope.selectedNodes.length; i++) { - if($scope.options.equality(selectedNode, $scope.selectedNodes[i])) { - pos = i; - break; + $scope.selectedNodes = $scope.selectedNodes || []; + $scope.expandedNodes = $scope.expandedNodes || []; + $scope.expandedNodesMap = {}; + for (var i = 0; i < $scope.expandedNodes.length; i++) { + $scope.expandedNodesMap["" + i] = $scope.expandedNodes[i]; + } + $scope.parentScopeOfTree = $scope.$parent; + + + ctrl.isSelectedNode = function (node) { + if (!$scope.options.multiSelection && ($scope.options.equality(node, $scope.selectedNode))) + return true; + else if ($scope.options.multiSelection && $scope.selectedNodes) { + for (var i = 0; (i < $scope.selectedNodes.length) ; i++) { + if ($scope.options.equality(node, $scope.selectedNodes[i])) { + return true; + } } + return false; } - if (pos === -1) { - $scope.selectedNodes.push(selectedNode); - selected = true; + return false; + } + + $scope.headClass = function (node) { + var liSelectionClass = ctrl.classIfDefined($scope.options.injectClasses.liSelected, false); + var injectSelectionClass = ""; + if (liSelectionClass && ctrl.isSelectedNode(node)) + injectSelectionClass = " " + liSelectionClass; + if ($scope.options.isLeaf(node)) + return "tree-leaf" + injectSelectionClass; + if ($scope.expandedNodesMap[this.$id]) + return "tree-expanded" + injectSelectionClass; + else + return "tree-collapsed" + injectSelectionClass; + }; + + $scope.iBranchClass = function () { + if ($scope.expandedNodesMap[this.$id]) + return ctrl.classIfDefined($scope.options.injectClasses.iExpanded); + else + return ctrl.classIfDefined($scope.options.injectClasses.iCollapsed); + }; + + $scope.nodeExpanded = function () { + return !!$scope.expandedNodesMap[this.$id]; + }; + + $scope.selectNodeHead = function () { + var transcludedScope = this; + var expanding = $scope.expandedNodesMap[transcludedScope.$id] === undefined; + $scope.expandedNodesMap[transcludedScope.$id] = (expanding ? transcludedScope.node : undefined); + if (expanding) { + $scope.expandedNodes.push(transcludedScope.node); } else { - $scope.selectedNodes.splice(pos, 1); + var index; + for (var i = 0; (i < $scope.expandedNodes.length) && !index; i++) { + if ($scope.options.equality($scope.expandedNodes[i], transcludedScope.node)) { + index = i; + } + } + if (index != undefined) + $scope.expandedNodes.splice(index, 1); } - } else { - if (!$scope.options.equality(selectedNode, $scope.selectedNode)) { - $scope.selectedNode = selectedNode; - selected = true; + if ($scope.onNodeToggle) { + var parentNode = (transcludedScope.$parent.node === transcludedScope.synteticRoot) ? null : transcludedScope.$parent.node; + $scope.onNodeToggle({ + node: transcludedScope.node, + $parentNode: parentNode, + $index: transcludedScope.$index, + $first: transcludedScope.$first, + $middle: transcludedScope.$middle, + $last: transcludedScope.$last, + $odd: transcludedScope.$odd, + $even: transcludedScope.$even, + expanded: expanding + }); + } - else { - if ($scope.options.allowDeselect) { - $scope.selectedNode = undefined; + }; + + $scope.selectNodeLabel = function (selectedNode) { + var transcludedScope = this; + if (!$scope.options.isLeaf(selectedNode) && (!$scope.options.dirSelectable || !$scope.options.isSelectable(selectedNode))) { + // Branch node is not selectable, expand + this.selectNodeHead(); + } else if ($scope.options.isLeaf(selectedNode) && (!$scope.options.isSelectable(selectedNode))) { + // Leaf node is not selectable + return; + } else { + var selected = false; + if ($scope.options.multiSelection) { + var pos = -1; + for (var i = 0; i < $scope.selectedNodes.length; i++) { + if ($scope.options.equality(selectedNode, $scope.selectedNodes[i])) { + pos = i; + break; + } + } + if (pos === -1) { + $scope.selectedNodes.push(selectedNode); + selected = true; + } else { + $scope.selectedNodes.splice(pos, 1); + } } else { - $scope.selectedNode = selectedNode; - selected = true; + if (!$scope.options.equality(selectedNode, $scope.selectedNode)) { + $scope.selectedNode = selectedNode; + selected = true; + } else { + if ($scope.options.allowDeselect) { + $scope.selectedNode = undefined; + } else { + $scope.selectedNode = selectedNode; + selected = true; + } + } + } + if ($scope.onSelection) { + var parentNode = (transcludedScope.$parent.node === transcludedScope.synteticRoot) ? null : transcludedScope.$parent.node; + $scope.onSelection({ + node: selectedNode, + selected: selected, + $parentNode: parentNode, + $index: transcludedScope.$index, + $first: transcludedScope.$first, + $middle: transcludedScope.$middle, + $last: transcludedScope.$last, + $odd: transcludedScope.$odd, + $even: transcludedScope.$even + }); } } - } - if ($scope.onSelection) { - var parentNode = (transcludedScope.$parent.node === transcludedScope.synteticRoot)?null:transcludedScope.$parent.node; - $scope.onSelection({node: selectedNode, selected: selected, $parentNode: parentNode, - $index: transcludedScope.$index, $first: transcludedScope.$first, $middle: transcludedScope.$middle, - $last: transcludedScope.$last, $odd: transcludedScope.$odd, $even: transcludedScope.$even}); - } + }; + + $scope.selectedClass = function () { + var isThisNodeSelected = ctrl.isSelectedNode(this.node); + var labelSelectionClass = ctrl.classIfDefined($scope.options.injectClasses.labelSelected, false); + var injectSelectionClass = ""; + if (labelSelectionClass && isThisNodeSelected) + injectSelectionClass = " " + labelSelectionClass; + + return isThisNodeSelected ? "tree-selected" + injectSelectionClass : ""; + }; + + $scope.unselectableClass = function () { + var isThisNodeUnselectable = !$scope.options.isSelectable(this.node); + var labelUnselectableClass = ctrl.classIfDefined($scope.options.injectClasses.labelUnselectable, false); + return isThisNodeUnselectable ? "tree-unselectable " + labelUnselectableClass : ""; + }; + + //tree template + ctrl.orderBy = $scope.orderBy ? ' | orderBy:orderBy:reverseOrder' : ''; + var template = + ''; + + ctrl.template = $compile(template); } - }; - - $scope.selectedClass = function() { - var isThisNodeSelected = isSelectedNode(this.node); - var labelSelectionClass = classIfDefined($scope.options.injectClasses.labelSelected, false); - var injectSelectionClass = ""; - if (labelSelectionClass && isThisNodeSelected) - injectSelectionClass = " " + labelSelectionClass; - - return isThisNodeSelected ? "tree-selected" + injectSelectionClass : ""; - }; - - $scope.unselectableClass = function() { - var isThisNodeUnselectable = !$scope.options.isSelectable(this.node); - var labelUnselectableClass = classIfDefined($scope.options.injectClasses.labelUnselectable, false); - return isThisNodeUnselectable ? "tree-unselectable " + labelUnselectableClass : ""; - }; - - //tree template - var orderBy = $scope.orderBy ? ' | orderBy:orderBy:reverseOrder' : ''; - var template = - ''; - - this.template = $compile(template); - }], - compile: function(element, attrs, childTranscludeFn) { - return function ( scope, element, attrs, treemodelCntr ) { - - scope.$watch("treeModel", function updateNodeOnRootScope(newValue) { - if (angular.isArray(newValue)) { - if (angular.isDefined(scope.node) && angular.equals(scope.node[scope.options.nodeChildren], newValue)) - return; - scope.node = {}; - scope.synteticRoot = scope.node; - scope.node[scope.options.nodeChildren] = newValue; - } - else { - if (angular.equals(scope.node, newValue)) - return; - scope.node = newValue; - } - }); + ], + compile: function (element, attrs, childTranscludeFn) { + return function (scope, element, attrs, treemodelCntr) { - scope.$watchCollection('expandedNodes', function(newValue) { - var notFoundIds = 0; - var newExpandedNodesMap = {}; - var $liElements = element.find('li'); - var existingScopes = []; - // find all nodes visible on the tree and the scope $id of the scopes including them - angular.forEach($liElements, function(liElement) { - var $liElement = angular.element(liElement); - var liScope = $liElement.scope(); - existingScopes.push(liScope); + scope.$watch("treeModel", function updateNodeOnRootScope(newValue) { + if (angular.isArray(newValue)) { + if (angular.isDefined(scope.node) && angular.equals(scope.node[scope.options.nodeChildren], newValue)) + return; + scope.node = {}; + scope.synteticRoot = scope.node; + scope.node[scope.options.nodeChildren] = newValue; + } else { + if (angular.equals(scope.node, newValue)) + return; + scope.node = newValue; + } }); - // iterate over the newValue, the new expanded nodes, and for each find it in the existingNodesAndScopes - // if found, add the mapping $id -> node into newExpandedNodesMap - // if not found, add the mapping num -> node into newExpandedNodesMap - angular.forEach(newValue, function(newExNode) { - var found = false; - for (var i=0; (i < existingScopes.length) && !found; i++) { - var existingScope = existingScopes[i]; - if (scope.options.equality(newExNode, existingScope.node)) { - newExpandedNodesMap[existingScope.$id] = existingScope.node; - found = true; + + scope.$watchCollection('expandedNodes', function (newValue) { + var notFoundIds = 0; + var newExpandedNodesMap = {}; + var $liElements = element.find('li'); + var existingScopes = []; + // find all nodes visible on the tree and the scope $id of the scopes including them + angular.forEach($liElements, function (liElement) { + var $liElement = angular.element(liElement); + var liScope = $liElement.scope(); + existingScopes.push(liScope); + }); + // iterate over the newValue, the new expanded nodes, and for each find it in the existingNodesAndScopes + // if found, add the mapping $id -> node into newExpandedNodesMap + // if not found, add the mapping num -> node into newExpandedNodesMap + angular.forEach(newValue, function (newExNode) { + var found = false; + for (var i = 0; (i < existingScopes.length) && !found; i++) { + var existingScope = existingScopes[i]; + if (scope.options.equality(newExNode, existingScope.node)) { + newExpandedNodesMap[existingScope.$id] = existingScope.node; + found = true; + } } - } - if (!found) - newExpandedNodesMap[notFoundIds++] = newExNode; + if (!found) + newExpandedNodesMap[notFoundIds++] = newExNode; + }); + scope.expandedNodesMap = newExpandedNodesMap; }); - scope.expandedNodesMap = newExpandedNodesMap; - }); -// scope.$watch('expandedNodesMap', function(newValue) { -// -// }); + // scope.$watch('expandedNodesMap', function(newValue) { + // + // }); - //Rendering template for a root node - treemodelCntr.template( scope, function(clone) { - element.html('').append( clone ); - }); - // save the transclude function from compile (which is not bound to a scope as apposed to the one from link) - // we can fix this to work with the link transclude function with angular 1.2.6. as for angular 1.2.0 we need - // to keep using the compile function - scope.$treeTransclude = childTranscludeFn; + //Rendering template for a root node + treemodelCntr.template(scope, function (clone) { + element.html('').append(clone); + }); + // save the transclude function from compile (which is not bound to a scope as apposed to the one from link) + // we can fix this to work with the link transclude function with angular 1.2.6. as for angular 1.2.0 we need + // to keep using the compile function + scope.$treeTransclude = childTranscludeFn; + } } - } - }; - }]) - .directive("treeitem", function() { + }; + } + ]) + .directive("treeitem", function () { return { restrict: 'E', require: "^treecontrol", - link: function( scope, element, attrs, treemodelCntr) { + link: function (scope, element, attrs, treemodelCntr) { // Rendering template for the current node - treemodelCntr.template(scope, function(clone) { + treemodelCntr.template(scope, function (clone) { element.html('').append(clone); }); } } }) - .directive("treeTransclude", function() { + .directive("treeTransclude", function () { return { - link: function(scope, element, attrs, controller) { + link: function (scope, element, attrs, controller) { if (!scope.options.isLeaf(scope.node)) { angular.forEach(scope.expandedNodesMap, function (node, id) { if (scope.options.equality(node, scope.node)) { @@ -338,7 +361,7 @@ scope.selectedNode = scope.node; } else if (scope.options.multiSelection) { var newSelectedNodes = []; - for (var i = 0; (i < scope.selectedNodes.length); i++) { + for (var i = 0; (i < scope.selectedNodes.length) ; i++) { if (scope.options.equality(scope.node, scope.selectedNodes[i])) { newSelectedNodes.push(scope.node); } @@ -349,22 +372,22 @@ // create a scope for the transclusion, whos parent is the parent of the tree control scope.transcludeScope = scope.parentScopeOfTree.$new(); scope.transcludeScope.node = scope.node; - scope.transcludeScope.$parentNode = (scope.$parent.node === scope.synteticRoot)?null:scope.$parent.node; + scope.transcludeScope.$parentNode = (scope.$parent.node === scope.synteticRoot) ? null : scope.$parent.node; scope.transcludeScope.$index = scope.$index; scope.transcludeScope.$first = scope.$first; scope.transcludeScope.$middle = scope.$middle; scope.transcludeScope.$last = scope.$last; scope.transcludeScope.$odd = scope.$odd; scope.transcludeScope.$even = scope.$even; - scope.$on('$destroy', function() { + scope.$on('$destroy', function () { scope.transcludeScope.$destroy(); }); - scope.$treeTransclude(scope.transcludeScope, function(clone) { + scope.$treeTransclude(scope.transcludeScope, function (clone) { element.empty(); element.append(clone); }); } } }); -})( angular ); +})(angular); From 43e98a7f440339a42c8ee5f1a08efdf437ac3aa2 Mon Sep 17 00:00:00 2001 From: Kojotto Date: Thu, 16 Jul 2015 14:57:46 +0200 Subject: [PATCH 2/4] Update angular-tree-control.js --- angular-tree-control.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/angular-tree-control.js b/angular-tree-control.js index 496c6bd..037d64c 100644 --- a/angular-tree-control.js +++ b/angular-tree-control.js @@ -4,11 +4,6 @@ angular.module('treeControl') .directive('treecontrol', [ '$compile', function ($compile) { - /** - * @param cssClass - the css class - * @param addClassProperty - should we wrap the class name with class="" - */ - return { restrict: 'EA', require: "treecontrol", From 2bad43a2728675310606017cc7f9d0d67aeed69a Mon Sep 17 00:00:00 2001 From: Kojotto Date: Fri, 17 Jul 2015 16:15:39 +0200 Subject: [PATCH 3/4] Update angular-tree-control.js Removed some unnecessary bindings. you can now extend the directive, example: .directive("treecontrolfoldering", function() { return { restrict: "A", require: "treecontrolFoldering", link: function(scope, element, attributes, ctrl) { var isolateScope = element.isolateScope(); ctrl.ensureDefault(element.isolateScope().options, "nodeFolderType", "FolderType"); isolateScope.folderTypeClass = function (node) { var destinationType = scope.foldering.getDestinationObject(node); return destinationType.cssClass; }; ctrl.defaultIsLeaf = function(node) { return (!node[isolateScope.options.nodeChildren] || node[isolateScope.options.nodeChildren].length === 0) && (!node[isolateScope.options.nodeFolderType] || node[isolateScope.options.nodeFolderType].length === 0); } isolateScope.options.isLeaf = ctrl.defaultIsLeaf; ctrl.orderBy = "| orderBy:'Name'"; ctrl.orderByFolderType = "| orderBy:'toString()'"; var template = '
    ' + '
  • ' + '' + '
    ' + '
  • ' + '
  • ' + '' + '' + '
    ' + '' + '
  • ' + '
'; ctrl.template = ctrl.recompileTemplate(template); } } }); some additional code is needed but ... --- angular-tree-control.js | 72 ++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/angular-tree-control.js b/angular-tree-control.js index 037d64c..437d7c0 100644 --- a/angular-tree-control.js +++ b/angular-tree-control.js @@ -1,9 +1,9 @@ -(function (angular) { +(function(angular) { 'use strict'; angular.module('treeControl') .directive('treecontrol', [ - '$compile', function ($compile) { + '$compile', function($compile) { return { restrict: 'EA', require: "treecontrol", @@ -23,14 +23,13 @@ }, controller: [ '$scope', function ($scope) { - var ctrl = this; - ctrl.$scope = $scope; - ctrl.$compile = $compile; - + ctrl.recompileTemplate = function(template) { + return $compile(template); + } - ctrl.classIfDefined = function (cssClass, addClassProperty) { + ctrl.classIfDefined = function(cssClass, addClassProperty) { if (cssClass) { if (addClassProperty) return 'class="' + cssClass + '"'; @@ -40,17 +39,16 @@ return ""; } - ctrl.ensureDefault = function (obj, prop, value) { + ctrl.ensureDefault = function(obj, prop, value) { if (!obj.hasOwnProperty(prop)) obj[prop] = value; } - - ctrl.defaultIsLeaf = function (node) { + ctrl.defaultIsLeaf = function(node) { return !node[$scope.options.nodeChildren] || node[$scope.options.nodeChildren].length === 0; } - ctrl.shallowCopy = function (src, dst) { + ctrl.shallowCopy = function(src, dst) { if (angular.isArray(src)) { dst = dst || []; @@ -69,7 +67,7 @@ return dst || src; } - ctrl.defaultEquality = function (a, b) { + ctrl.defaultEquality = function(a, b) { if (a === undefined || b === undefined) return false; a = ctrl.shallowCopy(a); @@ -79,7 +77,7 @@ return angular.equals(a, b); } - ctrl.defaultIsSelectable = function () { + ctrl.defaultIsSelectable = function() { return true; } @@ -110,11 +108,11 @@ $scope.parentScopeOfTree = $scope.$parent; - ctrl.isSelectedNode = function (node) { + ctrl.isSelectedNode = function(node) { if (!$scope.options.multiSelection && ($scope.options.equality(node, $scope.selectedNode))) return true; else if ($scope.options.multiSelection && $scope.selectedNodes) { - for (var i = 0; (i < $scope.selectedNodes.length) ; i++) { + for (var i = 0; (i < $scope.selectedNodes.length); i++) { if ($scope.options.equality(node, $scope.selectedNodes[i])) { return true; } @@ -124,7 +122,7 @@ return false; } - $scope.headClass = function (node) { + $scope.headClass = function(node) { var liSelectionClass = ctrl.classIfDefined($scope.options.injectClasses.liSelected, false); var injectSelectionClass = ""; if (liSelectionClass && ctrl.isSelectedNode(node)) @@ -137,18 +135,18 @@ return "tree-collapsed" + injectSelectionClass; }; - $scope.iBranchClass = function () { + $scope.iBranchClass = function() { if ($scope.expandedNodesMap[this.$id]) return ctrl.classIfDefined($scope.options.injectClasses.iExpanded); else return ctrl.classIfDefined($scope.options.injectClasses.iCollapsed); }; - $scope.nodeExpanded = function () { + $scope.nodeExpanded = function() { return !!$scope.expandedNodesMap[this.$id]; }; - $scope.selectNodeHead = function () { + $scope.selectNodeHead = function() { var transcludedScope = this; var expanding = $scope.expandedNodesMap[transcludedScope.$id] === undefined; $scope.expandedNodesMap[transcludedScope.$id] = (expanding ? transcludedScope.node : undefined); @@ -181,7 +179,7 @@ } }; - $scope.selectNodeLabel = function (selectedNode) { + $scope.selectNodeLabel = function(selectedNode) { var transcludedScope = this; if (!$scope.options.isLeaf(selectedNode) && (!$scope.options.dirSelectable || !$scope.options.isSelectable(selectedNode))) { // Branch node is not selectable, expand @@ -235,7 +233,7 @@ } }; - $scope.selectedClass = function () { + $scope.selectedClass = function() { var isThisNodeSelected = ctrl.isSelectedNode(this.node); var labelSelectionClass = ctrl.classIfDefined($scope.options.injectClasses.labelSelected, false); var injectSelectionClass = ""; @@ -245,7 +243,7 @@ return isThisNodeSelected ? "tree-selected" + injectSelectionClass : ""; }; - $scope.unselectableClass = function () { + $scope.unselectableClass = function() { var isThisNodeUnselectable = !$scope.options.isSelectable(this.node); var labelUnselectableClass = ctrl.classIfDefined($scope.options.injectClasses.labelUnselectable, false); return isThisNodeUnselectable ? "tree-unselectable " + labelUnselectableClass : ""; @@ -266,8 +264,8 @@ ctrl.template = $compile(template); } ], - compile: function (element, attrs, childTranscludeFn) { - return function (scope, element, attrs, treemodelCntr) { + compile: function(element, attrs, childTranscludeFn) { + return function(scope, element, attrs, treemodelCntr) { scope.$watch("treeModel", function updateNodeOnRootScope(newValue) { if (angular.isArray(newValue)) { @@ -283,13 +281,13 @@ } }); - scope.$watchCollection('expandedNodes', function (newValue) { + scope.$watchCollection('expandedNodes', function(newValue) { var notFoundIds = 0; var newExpandedNodesMap = {}; var $liElements = element.find('li'); var existingScopes = []; // find all nodes visible on the tree and the scope $id of the scopes including them - angular.forEach($liElements, function (liElement) { + angular.forEach($liElements, function(liElement) { var $liElement = angular.element(liElement); var liScope = $liElement.scope(); existingScopes.push(liScope); @@ -297,7 +295,7 @@ // iterate over the newValue, the new expanded nodes, and for each find it in the existingNodesAndScopes // if found, add the mapping $id -> node into newExpandedNodesMap // if not found, add the mapping num -> node into newExpandedNodesMap - angular.forEach(newValue, function (newExNode) { + angular.forEach(newValue, function(newExNode) { var found = false; for (var i = 0; (i < existingScopes.length) && !found; i++) { var existingScope = existingScopes[i]; @@ -317,7 +315,7 @@ // }); //Rendering template for a root node - treemodelCntr.template(scope, function (clone) { + treemodelCntr.template(scope, function(clone) { element.html('').append(clone); }); // save the transclude function from compile (which is not bound to a scope as apposed to the one from link) @@ -329,23 +327,23 @@ }; } ]) - .directive("treeitem", function () { + .directive("treeitem", function() { return { restrict: 'E', require: "^treecontrol", - link: function (scope, element, attrs, treemodelCntr) { + link: function(scope, element, attrs, treemodelCntr) { // Rendering template for the current node - treemodelCntr.template(scope, function (clone) { + treemodelCntr.template(scope, function(clone) { element.html('').append(clone); }); } } }) - .directive("treeTransclude", function () { + .directive("treeTransclude", function() { return { - link: function (scope, element, attrs, controller) { + link: function(scope, element, attrs, controller) { if (!scope.options.isLeaf(scope.node)) { - angular.forEach(scope.expandedNodesMap, function (node, id) { + angular.forEach(scope.expandedNodesMap, function(node, id) { if (scope.options.equality(node, scope.node)) { scope.expandedNodesMap[scope.$id] = scope.node; scope.expandedNodesMap[id] = undefined; @@ -356,7 +354,7 @@ scope.selectedNode = scope.node; } else if (scope.options.multiSelection) { var newSelectedNodes = []; - for (var i = 0; (i < scope.selectedNodes.length) ; i++) { + for (var i = 0; (i < scope.selectedNodes.length); i++) { if (scope.options.equality(scope.node, scope.selectedNodes[i])) { newSelectedNodes.push(scope.node); } @@ -374,11 +372,11 @@ scope.transcludeScope.$last = scope.$last; scope.transcludeScope.$odd = scope.$odd; scope.transcludeScope.$even = scope.$even; - scope.$on('$destroy', function () { + scope.$on('$destroy', function() { scope.transcludeScope.$destroy(); }); - scope.$treeTransclude(scope.transcludeScope, function (clone) { + scope.$treeTransclude(scope.transcludeScope, function(clone) { element.empty(); element.append(clone); }); From 62d07b515b6eac3b0a955c4fd3d68c4f7f1b90f8 Mon Sep 17 00:00:00 2001 From: Kojotto Date: Fri, 17 Jul 2015 16:24:55 +0200 Subject: [PATCH 4/4] Update angular-tree-control.js Changed the orderBy back to private as it's not needed on the controller. --- angular-tree-control.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/angular-tree-control.js b/angular-tree-control.js index 437d7c0..92d07c3 100644 --- a/angular-tree-control.js +++ b/angular-tree-control.js @@ -250,10 +250,10 @@ }; //tree template - ctrl.orderBy = $scope.orderBy ? ' | orderBy:orderBy:reverseOrder' : ''; + var orderBy = $scope.orderBy ? ' | orderBy:orderBy:reverseOrder' : ''; var template = '
    ' + - '
  • ' + + '
  • ' + '' + '' + '
    ' +